import runDbClient_default from "../../../../data/db/runDbClient.js";
import { getLogger as getLogger$1 } from "../../../../logger.js";
import { requireProjectPermission } from "../../../../middleware/projectAccess.js";
import { OpenAPIHono, z } from "@hono/zod-openapi";
import { DatasetRunApiSelectSchema, ListResponseSchema, SingleResponseSchema, TenantProjectParamsSchema, commonGetErrorResponses, createApiError, getConversation, getDatasetRunById, getDatasetRunConfigById, getDatasetRunConversationRelations, getMessagesByConversation, listDatasetItems, listDatasetRuns, listScheduledTriggerInvocationsByTriggerId } from "@inkeep/agents-core";
import { createProtectedRoute } from "@inkeep/agents-core/middleware";

//#region src/domains/manage/routes/evals/datasetRuns.ts
const app = new OpenAPIHono();
const logger = getLogger$1("datasetRuns");
app.openapi(createProtectedRoute({
	method: "get",
	path: "/by-dataset/{datasetId}",
	summary: "List Dataset Runs by Dataset ID",
	operationId: "list-dataset-runs",
	tags: ["Evaluations"],
	permission: requireProjectPermission("view"),
	request: { params: TenantProjectParamsSchema.extend({ datasetId: z.string() }) },
	responses: {
		200: {
			description: "List of dataset runs",
			content: { "application/json": { schema: ListResponseSchema(DatasetRunApiSelectSchema) } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, datasetId } = c.req.valid("param");
	try {
		const filteredRuns = (await listDatasetRuns(runDbClient_default)({ scopes: {
			tenantId,
			projectId
		} })).filter((run) => run.datasetId === datasetId);
		const runsWithMeta = await Promise.all(filteredRuns.map(async (run) => {
			const runConfig = run.datasetRunConfigId ? await getDatasetRunConfigById(db)({ scopes: {
				tenantId,
				projectId,
				datasetRunConfigId: run.datasetRunConfigId
			} }) : null;
			return {
				...run,
				runConfigName: runConfig?.name ?? null
			};
		}));
		return c.json({
			data: runsWithMeta,
			pagination: {
				page: 1,
				limit: runsWithMeta.length,
				total: runsWithMeta.length,
				pages: 1
			}
		});
	} catch (error) {
		logger.error({
			error,
			tenantId,
			projectId,
			datasetId
		}, "Failed to list dataset runs");
		return c.json(createApiError({
			code: "internal_server_error",
			message: "Failed to list dataset runs"
		}), 500);
	}
});
app.openapi(createProtectedRoute({
	method: "get",
	path: "/{runId}",
	summary: "Get Dataset Run by ID",
	operationId: "get-dataset-run",
	tags: ["Evaluations"],
	permission: requireProjectPermission("view"),
	request: { params: TenantProjectParamsSchema.extend({ runId: z.string() }) },
	responses: {
		200: {
			description: "Dataset run with conversations",
			content: { "application/json": { schema: SingleResponseSchema(DatasetRunApiSelectSchema.extend({ items: z.array(z.object({
				id: z.string(),
				tenantId: z.string(),
				projectId: z.string(),
				datasetId: z.string(),
				input: z.any().nullable().optional(),
				expectedOutput: z.any().nullable().optional(),
				createdAt: z.string(),
				updatedAt: z.string(),
				conversations: z.array(z.object({
					id: z.string(),
					conversationId: z.string(),
					datasetRunId: z.string(),
					agentId: z.string().nullable().optional(),
					output: z.string().nullable().optional(),
					createdAt: z.string(),
					updatedAt: z.string()
				}))
			})) })) } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, runId } = c.req.valid("param");
	try {
		const run = await getDatasetRunById(runDbClient_default)({ scopes: {
			tenantId,
			projectId,
			datasetRunId: runId
		} });
		if (!run) return c.json(createApiError({
			code: "not_found",
			message: "Dataset run not found"
		}), 404);
		const [runConfig, conversationRelations] = await Promise.all([run.datasetRunConfigId ? getDatasetRunConfigById(db)({ scopes: {
			tenantId,
			projectId,
			datasetRunConfigId: run.datasetRunConfigId
		} }) : Promise.resolve(null), getDatasetRunConversationRelations(runDbClient_default)({ scopes: {
			tenantId,
			projectId,
			datasetRunId: runId
		} })]);
		const runConfigName = runConfig?.name ?? null;
		const datasetItems = await listDatasetItems(db)({ scopes: {
			tenantId,
			projectId,
			datasetId: run.datasetId
		} });
		const itemsWithConversations = await Promise.all(datasetItems.map(async (item) => {
			const itemConversations = conversationRelations.filter((conv) => conv.datasetItemId === item.id);
			const conversationsWithOutput = await Promise.all(itemConversations.map(async (conv) => {
				try {
					const agentId = (await getConversation(runDbClient_default)({
						scopes: {
							tenantId,
							projectId
						},
						conversationId: conv.conversationId
					}))?.agentId || null;
					const assistantMessage = (await getMessagesByConversation(runDbClient_default)({
						scopes: {
							tenantId,
							projectId
						},
						conversationId: conv.conversationId,
						pagination: {
							page: 1,
							limit: 100
						}
					})).filter((msg) => msg.role === "assistant" || msg.role === "agent").sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())[0];
					let output = null;
					if (assistantMessage?.content) {
						if (typeof assistantMessage.content === "string") output = assistantMessage.content;
						else if (typeof assistantMessage.content === "object" && assistantMessage.content !== null && "text" in assistantMessage.content) output = typeof assistantMessage.content.text === "string" ? assistantMessage.content.text : null;
					}
					return {
						...conv,
						output,
						agentId
					};
				} catch (error) {
					logger.warn({
						error,
						conversationId: conv.conversationId
					}, "Failed to fetch conversation output");
					return {
						...conv,
						output: null,
						agentId: null
					};
				}
			}));
			return {
				...item,
				conversations: conversationsWithOutput
			};
		}));
		return c.json({ data: {
			...run,
			runConfigName,
			items: itemsWithConversations
		} });
	} catch (error) {
		logger.error({
			error,
			tenantId,
			projectId,
			runId
		}, "Failed to get dataset run");
		return c.json(createApiError({
			code: "internal_server_error",
			message: "Failed to get dataset run"
		}), 500);
	}
});
const DatasetRunItemResponseSchema = z.object({
	id: z.string(),
	tenantId: z.string(),
	projectId: z.string(),
	agentId: z.string(),
	datasetRunId: z.string(),
	datasetItemId: z.string(),
	status: z.string(),
	startedAt: z.string().nullable().optional(),
	completedAt: z.string().nullable().optional(),
	attemptNumber: z.number(),
	createdAt: z.string(),
	conversationId: z.string().nullable().optional()
});
app.openapi(createProtectedRoute({
	method: "get",
	path: "/{runId}/items",
	summary: "Get Dataset Run Items",
	operationId: "get-dataset-run-items",
	tags: ["Evaluations"],
	permission: requireProjectPermission("view"),
	request: {
		params: TenantProjectParamsSchema.extend({ runId: z.string() }),
		query: z.object({ status: z.string().optional() })
	},
	responses: {
		200: {
			description: "List of dataset run invocations",
			content: { "application/json": { schema: ListResponseSchema(DatasetRunItemResponseSchema) } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const { tenantId, projectId, runId } = c.req.valid("param");
	const { status } = c.req.valid("query");
	try {
		const [invocations, relations] = await Promise.all([listScheduledTriggerInvocationsByTriggerId(runDbClient_default)({
			scopes: {
				tenantId,
				projectId
			},
			scheduledTriggerId: runId,
			filters: status ? { status } : void 0
		}), getDatasetRunConversationRelations(runDbClient_default)({ scopes: {
			tenantId,
			projectId,
			datasetRunId: runId
		} })]);
		const items = invocations.map((inv) => {
			const datasetItemId = inv.resolvedPayload?.datasetItemId;
			const rel = relations.find((r) => r.datasetItemId === datasetItemId && r.conversationId !== void 0);
			return {
				id: inv.id,
				tenantId: inv.tenantId,
				projectId: inv.projectId,
				agentId: inv.agentId,
				datasetRunId: inv.scheduledTriggerId,
				datasetItemId: datasetItemId ?? "",
				status: inv.status,
				startedAt: inv.startedAt ?? null,
				completedAt: inv.completedAt ?? null,
				attemptNumber: inv.attemptNumber,
				createdAt: inv.createdAt,
				conversationId: rel?.conversationId ?? null
			};
		});
		return c.json({
			data: items,
			pagination: {
				page: 1,
				limit: items.length,
				total: items.length,
				pages: 1
			}
		});
	} catch (error) {
		logger.error({
			error,
			tenantId,
			projectId,
			runId
		}, "Failed to get dataset run items");
		return c.json(createApiError({
			code: "internal_server_error",
			message: "Failed to get dataset run items"
		}), 500);
	}
});
var datasetRuns_default = app;

//#endregion
export { datasetRuns_default as default };