import { getLogger as getLogger$1 } from "../../../../logger.js";
import manageDbClient_default from "../../../../data/db/manageDbClient.js";
import manageDbPool_default from "../../../../data/db/manageDbPool.js";
import runDbClient_default from "../../../../data/db/runDbClient.js";
import "../../../../data/db/index.js";
import { EvaluationService } from "../../services/EvaluationService.js";
import { createDatasetRunConversationRelation, createEvaluationResult, generateId, getConversation, getEvaluatorById, getProjectScopedRef, resolveRef, updateEvaluationResult, withRef } from "@inkeep/agents-core";

//#region src/domains/evals/workflow/functions/runDatasetItem.ts
/**
* Workflow for running dataset items through the chat API.
*
* This makes dataset run processing fire-and-forget - each item is queued
* independently and processed in parallel by the workflow system.
*/
const logger = getLogger$1("workflow-run-dataset-item");
/**
* Step: Call the chat API to process the dataset item
*/
async function callChatApiStep(payload) {
	"use step";
	const { tenantId, projectId, agentId, datasetItemId, datasetItemInput, datasetItemSimulationAgent, datasetRunId } = payload;
	const evaluationService = new EvaluationService();
	const datasetItem = {
		id: datasetItemId,
		input: datasetItemInput,
		simulationAgent: datasetItemSimulationAgent
	};
	const result = await evaluationService.runDatasetItem({
		tenantId,
		projectId,
		agentId,
		datasetItem,
		datasetRunId
	});
	logger.info({
		tenantId,
		projectId,
		datasetItemId,
		datasetRunId,
		conversationId: result.conversationId,
		hasError: !!result.error
	}, "Chat API call completed");
	return result;
}
/**
* Step: Create conversation relation in database
*/
async function createRelationStep(payload, conversationId) {
	"use step";
	const { tenantId, projectId, datasetItemId, datasetRunId } = payload;
	const relationId = generateId();
	try {
		await createDatasetRunConversationRelation(runDbClient_default)({
			tenantId,
			projectId,
			id: relationId,
			datasetRunId,
			conversationId,
			datasetItemId
		});
		logger.info({
			tenantId,
			projectId,
			datasetItemId,
			datasetRunId,
			conversationId,
			relationId
		}, "Created conversation relation");
		return {
			relationId,
			success: true
		};
	} catch (error) {
		if (error?.cause?.code === "23503" || error?.code === "23503") {
			logger.warn({
				tenantId,
				projectId,
				datasetItemId,
				datasetRunId,
				conversationId
			}, "Conversation does not exist, skipping relation creation");
			return {
				relationId: null,
				success: false,
				reason: "conversation_not_found"
			};
		}
		throw error;
	}
}
/**
* Step: Execute a single evaluator on a conversation
*/
async function executeEvaluatorStep(tenantId, projectId, conversationId, evaluatorId, evaluationRunId, expectedOutput) {
	"use step";
	const ref = getProjectScopedRef(tenantId, projectId, "main");
	const resolvedRef = await resolveRef(manageDbClient_default)(ref);
	if (!resolvedRef) throw new Error("Failed to resolve ref");
	const evaluator = await withRef(manageDbPool_default, resolvedRef, (db) => getEvaluatorById(db)({ scopes: {
		tenantId,
		projectId,
		evaluatorId
	} }));
	if (!evaluator) {
		logger.warn({ evaluatorId }, "Evaluator not found");
		return null;
	}
	const conversation = await getConversation(runDbClient_default)({
		scopes: {
			tenantId,
			projectId
		},
		conversationId
	});
	if (!conversation) throw new Error(`Conversation not found: ${conversationId}`);
	const evalResult = await createEvaluationResult(runDbClient_default)({
		id: generateId(),
		tenantId,
		projectId,
		conversationId,
		evaluatorId: evaluator.id,
		evaluationRunId
	});
	try {
		const output = await new EvaluationService().executeEvaluation({
			conversation,
			evaluator,
			tenantId,
			projectId,
			expectedOutput
		});
		await updateEvaluationResult(runDbClient_default)({
			scopes: {
				tenantId,
				projectId,
				evaluationResultId: evalResult.id
			},
			data: { output }
		});
		logger.info({
			conversationId,
			evaluatorId: evaluator.id,
			resultId: evalResult.id
		}, "Evaluation completed");
		return evalResult.id;
	} catch (error) {
		const errorMessage = error instanceof Error ? error.message : "Unknown error";
		logger.error({
			error,
			conversationId,
			evaluatorId: evaluator.id
		}, "Evaluation failed");
		await updateEvaluationResult(runDbClient_default)({
			scopes: {
				tenantId,
				projectId,
				evaluationResultId: evalResult.id
			},
			data: { output: { text: `Evaluation failed: ${errorMessage}` } }
		});
		return evalResult.id;
	}
}
/**
* Step: Log workflow progress
*/
async function logStep(message, data) {
	"use step";
	logger.info(data, message);
}
/**
* Main workflow function - processes a single dataset item through the chat API.
* Optionally runs evaluators on the resulting conversation.
*/
async function _runDatasetItemWorkflow(payload) {
	"use workflow";
	const { datasetItemId, datasetRunId, agentId, evaluatorIds, evaluationRunId } = payload;
	await logStep("Starting dataset item processing", {
		datasetItemId,
		datasetRunId,
		agentId,
		hasEvaluators: !!(evaluatorIds && evaluatorIds.length > 0)
	});
	const result = await callChatApiStep(payload);
	if (result.conversationId) {
		await createRelationStep(payload, result.conversationId);
		if (evaluatorIds && evaluatorIds.length > 0 && evaluationRunId) for (const evaluatorId of evaluatorIds) await executeEvaluatorStep(payload.tenantId, payload.projectId, result.conversationId, evaluatorId, evaluationRunId, payload.datasetItemExpectedOutput);
	} else await logStep("No conversation created", {
		datasetItemId,
		datasetRunId,
		error: result.error
	});
	return {
		success: !result.error,
		datasetItemId,
		datasetRunId,
		conversationId: result.conversationId || null,
		error: result.error || null
	};
}
const runDatasetItemWorkflow = Object.assign(_runDatasetItemWorkflow, { workflowId: "workflow//src/domains/evals/workflow/functions/runDatasetItem.ts//_runDatasetItemWorkflow" });

//#endregion
export { runDatasetItemWorkflow };