import { _ as getEnvBool, g as getConfigDirectoryPath, i as logger_default } from "./logger-CATn0kWr.js";
import { m as ResultFailureReason } from "./types-CHrVA-1r.js";
import * as path$1 from "path";
import { relations, sql } from "drizzle-orm";
import Database from "better-sqlite3";
import { drizzle } from "drizzle-orm/better-sqlite3";
import { DefaultLogger } from "drizzle-orm/logger";
import { index, integer, primaryKey, real, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";

//#region src/database/index.ts
var DrizzleLogWriter = class {
	write(message) {
		if (getEnvBool("PROMPTFOO_ENABLE_DATABASE_LOGS", false)) logger_default.debug(`Drizzle: ${message}`);
	}
};
let dbInstance = null;
let sqliteInstance = null;
function getDbPath() {
	return path$1.resolve(getConfigDirectoryPath(true), "promptfoo.db");
}
function getDbSignalPath() {
	return path$1.resolve(getConfigDirectoryPath(true), "evalLastWritten");
}
function getDb() {
	if (!dbInstance) {
		const isMemoryDb = getEnvBool("IS_TESTING");
		sqliteInstance = new Database(isMemoryDb ? ":memory:" : getDbPath());
		sqliteInstance.pragma("foreign_keys = ON");
		if (!isMemoryDb && !getEnvBool("PROMPTFOO_DISABLE_WAL_MODE", false)) try {
			sqliteInstance.pragma("journal_mode = WAL");
			const result = sqliteInstance.prepare("PRAGMA journal_mode").get();
			if (result.journal_mode.toLowerCase() === "wal") logger_default.debug("Successfully enabled SQLite WAL mode");
			else logger_default.warn(`Failed to enable WAL mode (got '${result.journal_mode}'). Database performance may be reduced. This can happen on network filesystems. Set PROMPTFOO_DISABLE_WAL_MODE=true to suppress this warning.`);
			sqliteInstance.pragma("wal_autocheckpoint = 1000");
			sqliteInstance.pragma("synchronous = NORMAL");
		} catch (err) {
			logger_default.warn(`Error configuring SQLite WAL mode: ${err}. Database will use default journal mode. Performance may be reduced. This can happen on network filesystems or certain containerized environments. Set PROMPTFOO_DISABLE_WAL_MODE=true to suppress this warning.`);
		}
		const drizzleLogger = new DefaultLogger({ writer: new DrizzleLogWriter() });
		dbInstance = drizzle(sqliteInstance, { logger: drizzleLogger });
	}
	return dbInstance;
}

//#endregion
//#region src/database/tables.ts
const promptsTable = sqliteTable("prompts", {
	id: text("id").primaryKey(),
	createdAt: integer("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
	prompt: text("prompt").notNull()
}, (table) => ({ createdAtIdx: index("prompts_created_at_idx").on(table.createdAt) }));
const tagsTable = sqliteTable("tags", {
	id: text("id").primaryKey(),
	name: text("name").notNull(),
	value: text("value").notNull()
}, (table) => ({
	nameIdx: index("tags_name_idx").on(table.name),
	uniqueNameValue: uniqueIndex("tags_name_value_unique").on(table.name, table.value)
}));
const evalsTable = sqliteTable("evals", {
	id: text("id").primaryKey(),
	createdAt: integer("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
	author: text("author"),
	description: text("description"),
	results: text("results", { mode: "json" }).$type().notNull(),
	config: text("config", { mode: "json" }).$type().notNull(),
	prompts: text("prompts", { mode: "json" }).$type(),
	vars: text("vars", { mode: "json" }).$type(),
	runtimeOptions: text("runtime_options", { mode: "json" }).$type(),
	isRedteam: integer("is_redteam", { mode: "boolean" }).notNull().default(false)
}, (table) => ({
	createdAtIdx: index("evals_created_at_idx").on(table.createdAt),
	authorIdx: index("evals_author_idx").on(table.author),
	isRedteamIdx: index("evals_is_redteam_idx").on(table.isRedteam)
}));
const evalResultsTable = sqliteTable("eval_results", {
	id: text("id").primaryKey(),
	createdAt: integer("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
	updatedAt: integer("updated_at").notNull().default(sql`CURRENT_TIMESTAMP`),
	evalId: text("eval_id").notNull().references(() => evalsTable.id),
	promptIdx: integer("prompt_idx").notNull(),
	testIdx: integer("test_idx").notNull(),
	testCase: text("test_case", { mode: "json" }).$type().notNull(),
	prompt: text("prompt", { mode: "json" }).$type().notNull(),
	promptId: text("prompt_id").references(() => promptsTable.id),
	provider: text("provider", { mode: "json" }).$type().notNull(),
	latencyMs: integer("latency_ms"),
	cost: real("cost"),
	response: text("response", { mode: "json" }).$type(),
	error: text("error"),
	failureReason: integer("failure_reason").default(ResultFailureReason.NONE).notNull(),
	success: integer("success", { mode: "boolean" }).notNull(),
	score: real("score").notNull(),
	gradingResult: text("grading_result", { mode: "json" }).$type(),
	namedScores: text("named_scores", { mode: "json" }).$type(),
	metadata: text("metadata", { mode: "json" }).$type()
}, (table) => ({
	evalIdIdx: index("eval_result_eval_id_idx").on(table.evalId),
	testIdxIdx: index("eval_result_test_idx").on(table.testIdx),
	evalTestIdx: index("eval_result_eval_test_idx").on(table.evalId, table.testIdx),
	evalSuccessIdx: index("eval_result_eval_success_idx").on(table.evalId, table.success),
	evalFailureIdx: index("eval_result_eval_failure_idx").on(table.evalId, table.failureReason),
	evalTestSuccessIdx: index("eval_result_eval_test_success_idx").on(table.evalId, table.testIdx, table.success),
	responseIdx: index("eval_result_response_idx").on(table.response),
	gradingResultReasonIdx: index("eval_result_grading_result_reason_idx").on(sql`json_extract(${table.gradingResult}, '$.reason')`),
	gradingResultCommentIdx: index("eval_result_grading_result_comment_idx").on(sql`json_extract(${table.gradingResult}, '$.comment')`),
	testCaseVarsIdx: index("eval_result_test_case_vars_idx").on(sql`json_extract(${table.testCase}, '$.vars')`),
	testCaseMetadataIdx: index("eval_result_test_case_metadata_idx").on(sql`json_extract(${table.metadata}, '$')`),
	namedScoresIdx: index("eval_result_named_scores_idx").on(sql`json_extract(${table.namedScores}, '$')`),
	metadataIdx: index("eval_result_metadata_idx").on(sql`json_extract(${table.metadata}, '$')`),
	metadataPluginIdIdx: index("eval_result_metadata_plugin_id_idx").on(sql`json_extract(${table.metadata}, '$.pluginId')`),
	metadataStrategyIdIdx: index("eval_result_metadata_strategy_id_idx").on(sql`json_extract(${table.metadata}, '$.strategyId')`)
}));
const evalsToPromptsTable = sqliteTable("evals_to_prompts", {
	evalId: text("eval_id").notNull().references(() => evalsTable.id, { onDelete: "cascade" }),
	promptId: text("prompt_id").notNull().references(() => promptsTable.id)
}, (t) => ({
	pk: primaryKey({ columns: [t.evalId, t.promptId] }),
	evalIdIdx: index("evals_to_prompts_eval_id_idx").on(t.evalId),
	promptIdIdx: index("evals_to_prompts_prompt_id_idx").on(t.promptId)
}));
const promptsRelations = relations(promptsTable, ({ many }) => ({ evalsToPrompts: many(evalsToPromptsTable) }));
const evalsToTagsTable = sqliteTable("evals_to_tags", {
	evalId: text("eval_id").notNull().references(() => evalsTable.id),
	tagId: text("tag_id").notNull().references(() => tagsTable.id)
}, (t) => ({
	pk: primaryKey({ columns: [t.evalId, t.tagId] }),
	evalIdIdx: index("evals_to_tags_eval_id_idx").on(t.evalId),
	tagIdIdx: index("evals_to_tags_tag_id_idx").on(t.tagId)
}));
const tagsRelations = relations(tagsTable, ({ many }) => ({ evalsToTags: many(evalsToTagsTable) }));
const evalsToTagsRelations = relations(evalsToTagsTable, ({ one }) => ({
	eval: one(evalsTable, {
		fields: [evalsToTagsTable.evalId],
		references: [evalsTable.id]
	}),
	tag: one(tagsTable, {
		fields: [evalsToTagsTable.tagId],
		references: [tagsTable.id]
	})
}));
const blobAssetsTable = sqliteTable("blob_assets", {
	hash: text("hash").primaryKey(),
	sizeBytes: integer("size_bytes").notNull(),
	mimeType: text("mime_type").notNull(),
	provider: text("provider").notNull(),
	createdAt: integer("created_at").notNull().default(sql`CURRENT_TIMESTAMP`)
}, (table) => ({
	providerIdx: index("blob_assets_provider_idx").on(table.provider),
	createdAtIdx: index("blob_assets_created_at_idx").on(table.createdAt)
}));
const blobReferencesTable = sqliteTable("blob_references", {
	id: text("id").primaryKey(),
	blobHash: text("blob_hash").notNull().references(() => blobAssetsTable.hash, { onDelete: "cascade" }),
	evalId: text("eval_id").notNull().references(() => evalsTable.id, { onDelete: "cascade" }),
	testIdx: integer("test_idx"),
	promptIdx: integer("prompt_idx"),
	location: text("location"),
	kind: text("kind"),
	createdAt: integer("created_at").notNull().default(sql`CURRENT_TIMESTAMP`)
}, (table) => ({
	blobIdx: index("blob_references_blob_idx").on(table.blobHash),
	evalIdx: index("blob_references_eval_idx").on(table.evalId)
}));
const datasetsTable = sqliteTable("datasets", {
	id: text("id").primaryKey(),
	tests: text("tests", { mode: "json" }).$type(),
	createdAt: integer("created_at").notNull().default(sql`CURRENT_TIMESTAMP`)
}, (table) => ({ createdAtIdx: index("datasets_created_at_idx").on(table.createdAt) }));
const evalsToDatasetsTable = sqliteTable("evals_to_datasets", {
	evalId: text("eval_id").notNull().references(() => evalsTable.id),
	datasetId: text("dataset_id").notNull().references(() => datasetsTable.id)
}, (t) => ({
	pk: primaryKey({ columns: [t.evalId, t.datasetId] }),
	evalIdIdx: index("evals_to_datasets_eval_id_idx").on(t.evalId),
	datasetIdIdx: index("evals_to_datasets_dataset_id_idx").on(t.datasetId)
}));
const datasetsRelations = relations(datasetsTable, ({ many }) => ({ evalsToDatasets: many(evalsToDatasetsTable) }));
const evalsRelations = relations(evalsTable, ({ many }) => ({
	evalsToPrompts: many(evalsToPromptsTable),
	evalsToDatasets: many(evalsToDatasetsTable),
	evalsToTags: many(evalsToTagsTable)
}));
const evalsToPromptsRelations = relations(evalsToPromptsTable, ({ one }) => ({
	eval: one(evalsTable, {
		fields: [evalsToPromptsTable.evalId],
		references: [evalsTable.id]
	}),
	prompt: one(promptsTable, {
		fields: [evalsToPromptsTable.promptId],
		references: [promptsTable.id]
	})
}));
const evalsToDatasetsRelations = relations(evalsToDatasetsTable, ({ one }) => ({
	eval: one(evalsTable, {
		fields: [evalsToDatasetsTable.evalId],
		references: [evalsTable.id]
	}),
	dataset: one(datasetsTable, {
		fields: [evalsToDatasetsTable.datasetId],
		references: [datasetsTable.id]
	})
}));
const configsTable = sqliteTable("configs", {
	id: text("id").primaryKey(),
	createdAt: integer("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
	updatedAt: integer("updated_at").notNull().default(sql`CURRENT_TIMESTAMP`),
	name: text("name").notNull(),
	type: text("type").notNull(),
	config: text("config", { mode: "json" }).notNull()
}, (table) => ({
	createdAtIdx: index("configs_created_at_idx").on(table.createdAt),
	typeIdx: index("configs_type_idx").on(table.type)
}));
const modelAuditsTable = sqliteTable("model_audits", {
	id: text("id").primaryKey(),
	createdAt: integer("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
	updatedAt: integer("updated_at").notNull().default(sql`CURRENT_TIMESTAMP`),
	name: text("name"),
	author: text("author"),
	modelPath: text("model_path").notNull(),
	modelType: text("model_type"),
	results: text("results", { mode: "json" }).$type().notNull(),
	checks: text("checks", { mode: "json" }).$type(),
	issues: text("issues", { mode: "json" }).$type(),
	hasErrors: integer("has_errors", { mode: "boolean" }).notNull(),
	totalChecks: integer("total_checks"),
	passedChecks: integer("passed_checks"),
	failedChecks: integer("failed_checks"),
	metadata: text("metadata", { mode: "json" }).$type(),
	modelId: text("model_id"),
	revisionSha: text("revision_sha"),
	contentHash: text("content_hash"),
	modelSource: text("model_source"),
	sourceLastModified: integer("source_last_modified"),
	scannerVersion: text("scanner_version")
}, (table) => ({
	createdAtIdx: index("model_audits_created_at_idx").on(table.createdAt),
	modelPathIdx: index("model_audits_model_path_idx").on(table.modelPath),
	hasErrorsIdx: index("model_audits_has_errors_idx").on(table.hasErrors),
	modelTypeIdx: index("model_audits_model_type_idx").on(table.modelType),
	modelIdIdx: index("model_audits_model_id_idx").on(table.modelId),
	revisionShaIdx: index("model_audits_revision_sha_idx").on(table.revisionSha),
	contentHashIdx: index("model_audits_content_hash_idx").on(table.contentHash),
	modelRevisionIdx: index("model_audits_model_revision_idx").on(table.modelId, table.revisionSha),
	modelContentIdx: index("model_audits_model_content_idx").on(table.modelId, table.contentHash)
}));
const tracesTable = sqliteTable("traces", {
	id: text("id").primaryKey(),
	traceId: text("trace_id").notNull().unique(),
	evaluationId: text("evaluation_id").notNull().references(() => evalsTable.id),
	testCaseId: text("test_case_id").notNull(),
	createdAt: integer("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
	metadata: text("metadata", { mode: "json" }).$type()
}, (table) => ({
	evaluationIdx: index("traces_evaluation_idx").on(table.evaluationId),
	traceIdIdx: index("traces_trace_id_idx").on(table.traceId)
}));
const spansTable = sqliteTable("spans", {
	id: text("id").primaryKey(),
	traceId: text("trace_id").notNull().references(() => tracesTable.traceId),
	spanId: text("span_id").notNull(),
	parentSpanId: text("parent_span_id"),
	name: text("name").notNull(),
	startTime: integer("start_time").notNull(),
	endTime: integer("end_time"),
	attributes: text("attributes", { mode: "json" }).$type(),
	statusCode: integer("status_code"),
	statusMessage: text("status_message")
}, (table) => ({
	traceIdIdx: index("spans_trace_id_idx").on(table.traceId),
	spanIdIdx: index("spans_span_id_idx").on(table.spanId)
}));
const tracesRelations = relations(tracesTable, ({ one, many }) => ({
	eval: one(evalsTable, {
		fields: [tracesTable.evaluationId],
		references: [evalsTable.id]
	}),
	spans: many(spansTable)
}));
const spansRelations = relations(spansTable, ({ one }) => ({ trace: one(tracesTable, {
	fields: [spansTable.traceId],
	references: [tracesTable.traceId]
}) }));

//#endregion
export { evalsTable as a, evalsToTagsTable as c, tagsTable as d, tracesTable as f, evalResultsTable as i, promptsTable as l, getDbSignalPath as m, blobReferencesTable as n, evalsToDatasetsTable as o, getDb as p, datasetsTable as r, evalsToPromptsTable as s, blobAssetsTable as t, spansTable as u };
//# sourceMappingURL=tables-BsaipJNh.js.map