import { createLogger } from "../../../utils/logger/index.js";
import { init_logger } from "../../../utils/logger.js";
import { PROVIDER_ENV_MAP, init_env_keys } from "../../../providers/env-keys.js";
import { describeFailoverError, isFailoverError } from "../../failover-error.js";
import { buildMediaGenerationNormalizationMetadata, buildNoCapabilityModelConfiguredMessage, recordCapabilityCandidateFailure, resolveCapabilityModelCandidates, throwCapabilityGenerationFailure } from "../../media-generation/runtime-shared.js";
import "../../media-generation/index.js";
import { parseImageGenerationModelRef } from "./model-ref.js";
import { resolveImageGenerationOverrides } from "./normalization.js";
import { getImageGenerationProvider, listImageGenerationProviders, listImageGenerationProvidersSummary as listImageGenerationProvidersSummary$1 } from "./provider-registry.js";
import "./bundled.js";
//#region src/agent/image/generation/runtime.ts
init_env_keys();
init_logger();
const log = createLogger("ImageGen");
/**
* Generate one or more images, walking the candidate model list with
* structured failover. See {@link GenerateImageParams} / {@link GenerateImageRuntimeResult}.
*/
async function generateImage(params, deps = {}) {
	const listProviders = (cfg) => (deps.listProviders ?? listImageGenerationProviders)(cfg);
	const getProvider = (id, cfg) => (deps.getProvider ?? getImageGenerationProvider)(id, cfg);
	const candidates = resolveCapabilityModelCandidates({
		cfg: params.cfg,
		modelConfig: params.cfg?.agents?.defaults?.imageGenerationModel,
		modelOverride: params.modelOverride,
		parseModelRef: parseImageGenerationModelRef,
		agentDir: params.agentDir,
		listProviders: (cfg) => listProviders(cfg).map(toCapabilityCandidate),
		autoProviderFallback: params.autoProviderFallback
	});
	if (candidates.length === 0) throw new Error(buildNoImageGenerationModelConfiguredMessage(params.cfg, deps));
	const attempts = [];
	let lastError;
	for (const candidate of candidates) {
		const startedAt = Date.now();
		const provider = getProvider(candidate.provider, params.cfg);
		if (!provider) {
			const errorMessage = `Image generation provider not registered: ${candidate.provider}`;
			attempts.push({
				provider: candidate.provider,
				model: candidate.model,
				error: errorMessage,
				reason: "config"
			});
			lastError = new Error(errorMessage);
			log.warn({
				provider: candidate.provider,
				model: candidate.model,
				phase: "candidate_skipped"
			}, `image-generation candidate skipped: ${errorMessage}`);
			continue;
		}
		try {
			const sanitized = resolveImageGenerationOverrides({
				provider,
				size: params.size,
				aspectRatio: params.aspectRatio,
				resolution: params.resolution,
				quality: params.quality,
				outputFormat: params.outputFormat,
				background: params.background,
				inputImages: params.inputImages
			});
			const request = buildProviderRequest({
				provider,
				candidate,
				params,
				sanitized
			});
			log.debug({
				provider: candidate.provider,
				model: candidate.model,
				phase: "provider_invoked",
				normalizationCount: sanitized.normalization ? Object.keys(sanitized.normalization).length : 0,
				ignoredCount: sanitized.ignoredOverrides.length
			}, `image-generation provider invoked: ${candidate.provider}/${candidate.model}`);
			const result = await provider.generateImage(request);
			if (!result.images?.length) throw new Error("Image generation provider returned no images.");
			const normalizationMetadata = buildMediaGenerationNormalizationMetadata({ normalization: sanitized.normalization });
			return {
				images: result.images,
				provider: candidate.provider,
				model: result.model ?? candidate.model,
				attempts,
				...sanitized.normalization ? { normalization: sanitized.normalization } : {},
				ignoredOverrides: sanitized.ignoredOverrides,
				metadata: {
					...result.metadata ?? {},
					...normalizationMetadata
				}
			};
		} catch (err) {
			lastError = err;
			const durationMs = Date.now() - startedAt;
			recordCapabilityCandidateFailure({
				attempts,
				provider: candidate.provider,
				model: candidate.model,
				error: err,
				durationMs
			});
			const last = attempts[attempts.length - 1];
			const description = isFailoverError(err) ? describeFailoverError(err) : void 0;
			log.warn({
				err,
				provider: candidate.provider,
				model: candidate.model,
				status: last?.status,
				reason: last?.reason,
				durationMs,
				phase: "candidate_failed",
				attemptCount: attempts.length
			}, `image-generation candidate failed: ${candidate.provider}/${candidate.model}: ${description ?? last?.error ?? (err instanceof Error ? err.message : String(err))}`);
		}
	}
	return throwCapabilityGenerationFailure({
		capabilityLabel: "image generation",
		attempts,
		lastError
	});
}
function listImageGenerationProvidersSummary(cfg) {
	return listImageGenerationProvidersSummary$1(cfg);
}
function buildProviderRequest(input) {
	const { provider, candidate, params, sanitized } = input;
	const inputImages = params.inputImages ? cloneInputImages(params.inputImages) : void 0;
	return {
		provider: provider.id,
		model: candidate.model,
		prompt: params.prompt,
		...params.cfg ? { cfg: params.cfg } : {},
		...params.agentDir ? { agentDir: params.agentDir } : {},
		...params.authStore ? { authStore: params.authStore } : {},
		...typeof params.timeoutMs === "number" ? { timeoutMs: params.timeoutMs } : {},
		...params.signal ? { signal: params.signal } : {},
		...typeof params.count === "number" ? { count: params.count } : {},
		...sanitized.size !== void 0 ? { size: sanitized.size } : {},
		...sanitized.aspectRatio !== void 0 ? { aspectRatio: sanitized.aspectRatio } : {},
		...sanitized.resolution !== void 0 ? { resolution: sanitized.resolution } : {},
		...sanitized.quality !== void 0 ? { quality: sanitized.quality } : {},
		...sanitized.outputFormat !== void 0 ? { outputFormat: sanitized.outputFormat } : {},
		...sanitized.background !== void 0 ? { background: sanitized.background } : {},
		...inputImages ? { inputImages } : {},
		...params.providerOptions ? { providerOptions: params.providerOptions } : {}
	};
}
function cloneInputImages(images) {
	return images.map((img) => ({
		buffer: img.buffer,
		mimeType: img.mimeType,
		...img.fileName ? { fileName: img.fileName } : {},
		...img.metadata ? { metadata: img.metadata } : {}
	}));
}
function toCapabilityCandidate(provider) {
	return {
		id: provider.id,
		...provider.aliases ? { aliases: provider.aliases } : {},
		defaultModel: provider.defaultModel ?? null,
		models: provider.models ?? [],
		isConfigured: provider.isConfigured
	};
}
function buildNoImageGenerationModelConfiguredMessage(cfg, deps) {
	return buildNoCapabilityModelConfiguredMessage({
		capabilityLabel: "image-generation",
		modelConfigKey: "imageGenerationModel",
		providers: (deps.listProviders ?? listImageGenerationProviders)(cfg).map(toCapabilityCandidate),
		getProviderEnvVars: deps.getProviderEnvVars ?? ((id) => PROVIDER_ENV_MAP[id])
	});
}
//#endregion
export { generateImage, getImageGenerationProvider, listImageGenerationProviders, listImageGenerationProvidersSummary };

//# sourceMappingURL=runtime.js.map