import { r as formatErrorMessage } from "./errors-CGMew-1w.js";
import { t as createSubsystemLogger } from "./subsystem-qDUB67UD.js";
import { i as isFailoverError, r as describeFailoverError } from "./failover-error-CGdVbNet.js";
import { c as resolveClosestResolution, i as hasMediaNormalizationEntry, l as resolveClosestSize, n as buildNoCapabilityModelConfiguredMessage, o as resolveCapabilityModelCandidates, s as resolveClosestAspectRatio, t as buildMediaGenerationNormalizationMetadata, u as throwCapabilityGenerationFailure } from "./runtime-shared-DmxuY3Fp.js";
import { n as listVideoGenerationProviders, r as parseVideoGenerationModelRef, t as getVideoGenerationProvider } from "./provider-registry-D8zcIzss.js";
//#region src/video-generation/capabilities.ts
function resolveVideoGenerationMode(params) {
	const inputImageCount = params.inputImageCount ?? 0;
	const inputVideoCount = params.inputVideoCount ?? 0;
	if (inputImageCount > 0 && inputVideoCount > 0) return null;
	if (inputVideoCount > 0) return "videoToVideo";
	if (inputImageCount > 0) return "imageToVideo";
	return "generate";
}
function listSupportedVideoGenerationModes(provider) {
	const modes = ["generate"];
	if (provider.capabilities.imageToVideo?.enabled) modes.push("imageToVideo");
	if (provider.capabilities.videoToVideo?.enabled) modes.push("videoToVideo");
	return modes;
}
function resolveVideoGenerationModeCapabilities(params) {
	const mode = resolveVideoGenerationMode(params);
	const capabilities = params.provider?.capabilities;
	if (!capabilities) return {
		mode,
		capabilities: void 0
	};
	if (mode === "generate") return {
		mode,
		capabilities: capabilities.generate
	};
	if (mode === "imageToVideo") return {
		mode,
		capabilities: capabilities.imageToVideo
	};
	if (mode === "videoToVideo") return {
		mode,
		capabilities: capabilities.videoToVideo
	};
	return {
		mode,
		capabilities: void 0
	};
}
//#endregion
//#region src/video-generation/duration-support.ts
function normalizeSupportedDurationValues(values) {
	if (!Array.isArray(values) || values.length === 0) return;
	const normalized = [...new Set(values)].filter((value) => Number.isFinite(value) && value > 0).map((value) => Math.round(value)).filter((value) => value > 0).toSorted((left, right) => left - right);
	return normalized.length > 0 ? normalized : void 0;
}
function resolveVideoGenerationSupportedDurations(params) {
	const { capabilities: caps } = resolveVideoGenerationModeCapabilities({
		provider: params.provider,
		inputImageCount: params.inputImageCount,
		inputVideoCount: params.inputVideoCount
	});
	const model = params.model?.trim();
	return normalizeSupportedDurationValues((model && caps?.supportedDurationSecondsByModel ? caps.supportedDurationSecondsByModel[model] : void 0) ?? caps?.supportedDurationSeconds);
}
function normalizeVideoGenerationDuration(params) {
	if (typeof params.durationSeconds !== "number" || !Number.isFinite(params.durationSeconds)) return;
	const rounded = Math.max(1, Math.round(params.durationSeconds));
	const supported = resolveVideoGenerationSupportedDurations(params);
	if (!supported || supported.length === 0) return rounded;
	return supported.reduce((best, current) => {
		const currentDistance = Math.abs(current - rounded);
		const bestDistance = Math.abs(best - rounded);
		if (currentDistance < bestDistance) return current;
		if (currentDistance === bestDistance && current > best) return current;
		return best;
	});
}
//#endregion
//#region src/video-generation/normalization.ts
function resolveVideoGenerationOverrides(params) {
	const { capabilities: caps } = resolveVideoGenerationModeCapabilities({
		provider: params.provider,
		inputImageCount: params.inputImageCount,
		inputVideoCount: params.inputVideoCount
	});
	const ignoredOverrides = [];
	const normalization = {};
	let size = params.size;
	let aspectRatio = params.aspectRatio;
	let resolution = params.resolution;
	let audio = params.audio;
	let watermark = params.watermark;
	if (caps) {
		if (size && (caps.sizes?.length ?? 0) > 0 && caps.supportsSize) {
			const normalizedSize = resolveClosestSize({
				requestedSize: size,
				requestedAspectRatio: aspectRatio,
				supportedSizes: caps.sizes
			});
			if (normalizedSize && normalizedSize !== size) normalization.size = {
				requested: size,
				applied: normalizedSize
			};
			size = normalizedSize;
		}
		if (!caps.supportsSize && size) {
			let translated = false;
			if (caps.supportsAspectRatio) {
				const normalizedAspectRatio = resolveClosestAspectRatio({
					requestedAspectRatio: aspectRatio,
					requestedSize: size,
					supportedAspectRatios: caps.aspectRatios
				});
				if (normalizedAspectRatio) {
					aspectRatio = normalizedAspectRatio;
					normalization.aspectRatio = {
						applied: normalizedAspectRatio,
						derivedFrom: "size"
					};
					translated = true;
				}
			}
			if (!translated) ignoredOverrides.push({
				key: "size",
				value: size
			});
			size = void 0;
		}
		if (aspectRatio && (caps.aspectRatios?.length ?? 0) > 0 && caps.supportsAspectRatio) {
			const normalizedAspectRatio = resolveClosestAspectRatio({
				requestedAspectRatio: aspectRatio,
				requestedSize: size,
				supportedAspectRatios: caps.aspectRatios
			});
			if (normalizedAspectRatio && normalizedAspectRatio !== aspectRatio) normalization.aspectRatio = {
				requested: aspectRatio,
				applied: normalizedAspectRatio
			};
			aspectRatio = normalizedAspectRatio;
		} else if (!caps.supportsAspectRatio && aspectRatio) {
			const derivedSize = caps.supportsSize && !size ? resolveClosestSize({
				requestedSize: params.size,
				requestedAspectRatio: aspectRatio,
				supportedSizes: caps.sizes
			}) : void 0;
			if (derivedSize) {
				size = derivedSize;
				normalization.size = {
					applied: derivedSize,
					derivedFrom: "aspectRatio"
				};
			} else ignoredOverrides.push({
				key: "aspectRatio",
				value: aspectRatio
			});
			aspectRatio = void 0;
		}
		if (resolution && (caps.resolutions?.length ?? 0) > 0 && caps.supportsResolution) {
			const normalizedResolution = resolveClosestResolution({
				requestedResolution: resolution,
				supportedResolutions: caps.resolutions
			});
			if (normalizedResolution && normalizedResolution !== resolution) normalization.resolution = {
				requested: resolution,
				applied: normalizedResolution
			};
			resolution = normalizedResolution;
		} else if (resolution && !caps.supportsResolution) {
			ignoredOverrides.push({
				key: "resolution",
				value: resolution
			});
			resolution = void 0;
		}
		if (typeof audio === "boolean" && !caps.supportsAudio) {
			ignoredOverrides.push({
				key: "audio",
				value: audio
			});
			audio = void 0;
		}
		if (typeof watermark === "boolean" && !caps.supportsWatermark) {
			ignoredOverrides.push({
				key: "watermark",
				value: watermark
			});
			watermark = void 0;
		}
	}
	if (caps && size && !caps.supportsSize) {
		ignoredOverrides.push({
			key: "size",
			value: size
		});
		size = void 0;
	}
	if (caps && aspectRatio && !caps.supportsAspectRatio) {
		ignoredOverrides.push({
			key: "aspectRatio",
			value: aspectRatio
		});
		aspectRatio = void 0;
	}
	if (caps && resolution && !caps.supportsResolution) {
		ignoredOverrides.push({
			key: "resolution",
			value: resolution
		});
		resolution = void 0;
	}
	if (!normalization.size && size && params.size && params.size !== size) normalization.size = {
		requested: params.size,
		applied: size
	};
	if (!normalization.aspectRatio && aspectRatio && (!params.aspectRatio && params.size || params.aspectRatio !== aspectRatio)) normalization.aspectRatio = {
		applied: aspectRatio,
		...params.aspectRatio ? { requested: params.aspectRatio } : {},
		...!params.aspectRatio && params.size ? { derivedFrom: "size" } : {}
	};
	if (!normalization.resolution && resolution && params.resolution && params.resolution !== resolution) normalization.resolution = {
		requested: params.resolution,
		applied: resolution
	};
	const requestedDurationSeconds = typeof params.durationSeconds === "number" && Number.isFinite(params.durationSeconds) ? Math.max(1, Math.round(params.durationSeconds)) : void 0;
	const durationSeconds = normalizeVideoGenerationDuration({
		provider: params.provider,
		model: params.model,
		durationSeconds: requestedDurationSeconds,
		inputImageCount: params.inputImageCount ?? 0,
		inputVideoCount: params.inputVideoCount ?? 0
	});
	const supportedDurationSeconds = resolveVideoGenerationSupportedDurations({
		provider: params.provider,
		model: params.model,
		inputImageCount: params.inputImageCount ?? 0,
		inputVideoCount: params.inputVideoCount ?? 0
	});
	if (typeof requestedDurationSeconds === "number" && typeof durationSeconds === "number" && requestedDurationSeconds !== durationSeconds) normalization.durationSeconds = {
		requested: requestedDurationSeconds,
		applied: durationSeconds,
		...supportedDurationSeconds?.length ? { supportedValues: supportedDurationSeconds } : {}
	};
	return {
		size,
		aspectRatio,
		resolution,
		durationSeconds,
		supportedDurationSeconds,
		audio,
		watermark,
		ignoredOverrides,
		normalization: hasMediaNormalizationEntry(normalization.size) || hasMediaNormalizationEntry(normalization.aspectRatio) || hasMediaNormalizationEntry(normalization.resolution) || hasMediaNormalizationEntry(normalization.durationSeconds) ? normalization : void 0
	};
}
//#endregion
//#region src/video-generation/runtime.ts
const log = createSubsystemLogger("video-generation");
function buildNoVideoGenerationModelConfiguredMessage(cfg) {
	return buildNoCapabilityModelConfiguredMessage({
		capabilityLabel: "video-generation",
		modelConfigKey: "videoGenerationModel",
		providers: listVideoGenerationProviders(cfg)
	});
}
function listRuntimeVideoGenerationProviders(params) {
	return listVideoGenerationProviders(params?.config);
}
async function generateVideo(params) {
	const candidates = resolveCapabilityModelCandidates({
		cfg: params.cfg,
		modelConfig: params.cfg.agents?.defaults?.videoGenerationModel,
		modelOverride: params.modelOverride,
		parseModelRef: parseVideoGenerationModelRef,
		agentDir: params.agentDir,
		listProviders: listVideoGenerationProviders
	});
	if (candidates.length === 0) throw new Error(buildNoVideoGenerationModelConfiguredMessage(params.cfg));
	const attempts = [];
	let lastError;
	for (const candidate of candidates) {
		const provider = getVideoGenerationProvider(candidate.provider, params.cfg);
		if (!provider) {
			const error = `No video-generation provider registered for ${candidate.provider}`;
			attempts.push({
				provider: candidate.provider,
				model: candidate.model,
				error
			});
			lastError = new Error(error);
			continue;
		}
		try {
			const sanitized = resolveVideoGenerationOverrides({
				provider,
				model: candidate.model,
				size: params.size,
				aspectRatio: params.aspectRatio,
				resolution: params.resolution,
				durationSeconds: params.durationSeconds,
				audio: params.audio,
				watermark: params.watermark,
				inputImageCount: params.inputImages?.length ?? 0,
				inputVideoCount: params.inputVideos?.length ?? 0
			});
			const result = await provider.generateVideo({
				provider: candidate.provider,
				model: candidate.model,
				prompt: params.prompt,
				cfg: params.cfg,
				agentDir: params.agentDir,
				authStore: params.authStore,
				size: sanitized.size,
				aspectRatio: sanitized.aspectRatio,
				resolution: sanitized.resolution,
				durationSeconds: sanitized.durationSeconds,
				audio: sanitized.audio,
				watermark: sanitized.watermark,
				inputImages: params.inputImages,
				inputVideos: params.inputVideos
			});
			if (!Array.isArray(result.videos) || result.videos.length === 0) throw new Error("Video generation provider returned no videos.");
			return {
				videos: result.videos,
				provider: candidate.provider,
				model: result.model ?? candidate.model,
				attempts,
				normalization: sanitized.normalization,
				ignoredOverrides: sanitized.ignoredOverrides,
				metadata: {
					...result.metadata,
					...buildMediaGenerationNormalizationMetadata({
						normalization: sanitized.normalization,
						requestedSizeForDerivedAspectRatio: params.size,
						includeSupportedDurationSeconds: true
					})
				}
			};
		} catch (err) {
			lastError = err;
			const described = isFailoverError(err) ? describeFailoverError(err) : void 0;
			attempts.push({
				provider: candidate.provider,
				model: candidate.model,
				error: described?.message ?? formatErrorMessage(err),
				reason: described?.reason,
				status: described?.status,
				code: described?.code
			});
			log.debug(`video-generation candidate failed: ${candidate.provider}/${candidate.model}`);
		}
	}
	throwCapabilityGenerationFailure({
		capabilityLabel: "video generation",
		attempts,
		lastError
	});
}
//#endregion
export { resolveVideoGenerationModeCapabilities as a, resolveVideoGenerationMode as i, listRuntimeVideoGenerationProviders as n, listSupportedVideoGenerationModes as r, generateVideo as t };
