UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

305 lines (304 loc) 11.5 kB
import { i as formatErrorMessage } from "./errors-BXgSefBE.js"; import { t as createSubsystemLogger } from "./subsystem-BzXSmsuh.js"; import { a as resolveAgentModelTimeoutMsValue } from "./model-input-B2zxl6MM.js"; import "./provider-env-vars-Clp1DREb.js"; import { a as describeFailoverError, o as isFailoverError } from "./failover-error-DAwMDmz6.js"; import { n as listImageGenerationProviders, r as parseImageGenerationModelRef, t as getImageGenerationProvider } from "./provider-registry-GqLIOxZZ.js"; import { c as resolveClosestResolution, d as resolveMediaProviderRequestTimeoutMs, f as throwCapabilityGenerationFailure, l as resolveClosestSize, n as buildNoCapabilityModelConfiguredMessage, o as resolveCapabilityModelCandidates, p as hasMediaNormalizationEntry, s as resolveClosestAspectRatio, t as buildMediaGenerationNormalizationMetadata } from "./runtime-shared-CClY-xy4.js"; //#region src/image-generation/normalization.ts /** Normalizes image generation request overrides against provider/model capabilities. */ function finalizeImageNormalization(normalization) { return hasMediaNormalizationEntry(normalization.size) || hasMediaNormalizationEntry(normalization.aspectRatio) || hasMediaNormalizationEntry(normalization.resolution) ? normalization : void 0; } /** Returns supported image overrides plus ignored/normalized override metadata for replies. */ function resolveImageGenerationOverrides(params) { const modeCaps = (params.inputImages?.length ?? 0) > 0 ? params.provider.capabilities.edit : params.provider.capabilities.generate; const geometry = params.provider.capabilities.geometry; const modelGeometry = { sizes: params.model ? geometry?.sizesByModel?.[params.model] ?? geometry?.sizes : geometry?.sizes, aspectRatios: params.model ? geometry?.aspectRatiosByModel?.[params.model] ?? geometry?.aspectRatios : geometry?.aspectRatios, resolutions: params.model ? geometry?.resolutionsByModel?.[params.model] ?? geometry?.resolutions : geometry?.resolutions }; const ignoredOverrides = []; const normalization = {}; let size = params.size; let aspectRatio = params.aspectRatio; let resolution = params.resolution; let quality = params.quality; let outputFormat = params.outputFormat; let background = params.background; if (size && (modelGeometry.sizes?.length ?? 0) > 0 && modeCaps.supportsSize) { const normalizedSize = resolveClosestSize({ requestedSize: size, supportedSizes: modelGeometry.sizes }); if (normalizedSize && normalizedSize !== size) normalization.size = { requested: size, applied: normalizedSize }; size = normalizedSize; } if (!modeCaps.supportsSize && size) { let translated = false; if (modeCaps.supportsAspectRatio) { const normalizedAspectRatio = resolveClosestAspectRatio({ requestedAspectRatio: aspectRatio, requestedSize: size, supportedAspectRatios: modelGeometry.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 && (modelGeometry.aspectRatios?.length ?? 0) > 0 && modeCaps.supportsAspectRatio) { const normalizedAspectRatio = resolveClosestAspectRatio({ requestedAspectRatio: aspectRatio, requestedSize: size, supportedAspectRatios: modelGeometry.aspectRatios }); if (normalizedAspectRatio && normalizedAspectRatio !== aspectRatio) normalization.aspectRatio = { requested: aspectRatio, applied: normalizedAspectRatio }; aspectRatio = normalizedAspectRatio; } else if (!modeCaps.supportsAspectRatio && aspectRatio) { const derivedSize = modeCaps.supportsSize && !size ? resolveClosestSize({ requestedSize: params.size, requestedAspectRatio: aspectRatio, supportedSizes: modelGeometry.sizes }) : void 0; let translated = false; if (derivedSize) { size = derivedSize; normalization.size = { applied: derivedSize, derivedFrom: "aspectRatio" }; translated = true; } if (!translated) ignoredOverrides.push({ key: "aspectRatio", value: aspectRatio }); aspectRatio = void 0; } if (resolution && (modelGeometry.resolutions?.length ?? 0) > 0 && modeCaps.supportsResolution) { const normalizedResolution = resolveClosestResolution({ requestedResolution: resolution, supportedResolutions: modelGeometry.resolutions }); if (normalizedResolution && normalizedResolution !== resolution) normalization.resolution = { requested: resolution, applied: normalizedResolution }; resolution = normalizedResolution; } else if (!modeCaps.supportsResolution && resolution) { ignoredOverrides.push({ key: "resolution", value: resolution }); resolution = void 0; } if (size && !modeCaps.supportsSize) { ignoredOverrides.push({ key: "size", value: size }); size = void 0; } if (aspectRatio && !modeCaps.supportsAspectRatio) { ignoredOverrides.push({ key: "aspectRatio", value: aspectRatio }); aspectRatio = void 0; } if (resolution && !modeCaps.supportsResolution) { ignoredOverrides.push({ key: "resolution", value: resolution }); resolution = void 0; } const supportedQualities = params.provider.capabilities.output?.qualities; if (quality && !(supportedQualities ?? []).includes(quality)) { ignoredOverrides.push({ key: "quality", value: quality }); quality = void 0; } const supportedFormats = params.provider.capabilities.output?.formats; if (outputFormat && !(supportedFormats ?? []).includes(outputFormat)) { ignoredOverrides.push({ key: "outputFormat", value: outputFormat }); outputFormat = void 0; } const supportedBackgrounds = params.provider.capabilities.output?.backgrounds; if (background && !(supportedBackgrounds ?? []).includes(background)) { ignoredOverrides.push({ key: "background", value: background }); background = void 0; } 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.size && size && params.size && params.size !== size) normalization.size = { requested: params.size, applied: size }; if (!normalization.aspectRatio && !params.aspectRatio && params.size && aspectRatio) normalization.aspectRatio = { applied: aspectRatio, derivedFrom: "size" }; if (!normalization.resolution && resolution && params.resolution && params.resolution !== resolution) normalization.resolution = { requested: params.resolution, applied: resolution }; return { size, aspectRatio, resolution, quality, outputFormat, background, ignoredOverrides, normalization: finalizeImageNormalization(normalization) }; } //#endregion //#region src/image-generation/runtime.ts /** Runtime entrypoint for image generation with provider fallback and override normalization. */ const log = createSubsystemLogger("image-generation"); function buildNoImageGenerationModelConfiguredMessage(cfg, deps) { return buildNoCapabilityModelConfiguredMessage({ capabilityLabel: "image-generation", modelConfigKey: "imageGenerationModel", providers: (deps.listProviders ?? listImageGenerationProviders)(cfg), getProviderEnvVars: deps.getProviderEnvVars }); } /** Lists image-generation providers visible for the current config. */ function listRuntimeImageGenerationProviders(params, deps = {}) { return (deps.listProviders ?? listImageGenerationProviders)(params?.config); } async function generateImage(params, deps = {}) { const getProvider = deps.getProvider ?? getImageGenerationProvider; const listProviders = deps.listProviders ?? listImageGenerationProviders; const logger = deps.log ?? log; const requestedTimeoutMs = params.timeoutMs ?? resolveAgentModelTimeoutMsValue(params.cfg.agents?.defaults?.imageGenerationModel); const candidates = resolveCapabilityModelCandidates({ cfg: params.cfg, modelConfig: params.cfg.agents?.defaults?.imageGenerationModel, modelOverride: params.modelOverride, parseModelRef: parseImageGenerationModelRef, agentDir: params.agentDir, listProviders, autoProviderFallback: params.autoProviderFallback }); if (candidates.length === 0) throw new Error(buildNoImageGenerationModelConfiguredMessage(params.cfg, deps)); const attempts = []; let lastError; for (const candidate of candidates) { const provider = getProvider(candidate.provider, params.cfg); if (!provider) { const error = `No image-generation provider registered for ${candidate.provider}`; attempts.push({ provider: candidate.provider, model: candidate.model, error }); lastError = new Error(error); logger.warn(`image-generation candidate failed: ${candidate.provider}/${candidate.model}: ${error}`); continue; } try { const timeoutMs = resolveMediaProviderRequestTimeoutMs({ timeoutMs: requestedTimeoutMs, providerDefaultTimeoutMs: provider.defaultTimeoutMs }); const sanitized = resolveImageGenerationOverrides({ provider, model: candidate.model, size: params.size, aspectRatio: params.aspectRatio, resolution: params.resolution, quality: params.quality, outputFormat: params.outputFormat, background: params.background, inputImages: params.inputImages }); const result = await provider.generateImage({ provider: candidate.provider, model: candidate.model, prompt: params.prompt, cfg: params.cfg, agentDir: params.agentDir, authStore: params.authStore, count: params.count, size: sanitized.size, aspectRatio: sanitized.aspectRatio, resolution: sanitized.resolution, quality: sanitized.quality, outputFormat: sanitized.outputFormat, background: sanitized.background, inputImages: params.inputImages, ...timeoutMs !== void 0 ? { timeoutMs } : {}, providerOptions: params.providerOptions, ssrfPolicy: params.ssrfPolicy }); if (!Array.isArray(result.images) || result.images.length === 0) throw new Error("Image generation provider returned no images."); return { images: result.images, provider: candidate.provider, model: result.model ?? candidate.model, attempts, normalization: sanitized.normalization, metadata: { ...result.metadata, ...buildMediaGenerationNormalizationMetadata({ normalization: sanitized.normalization, requestedSizeForDerivedAspectRatio: params.size }) }, ignoredOverrides: sanitized.ignoredOverrides }; } 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 }); logger.warn(`image-generation candidate failed: ${candidate.provider}/${candidate.model}: ${described?.message ?? formatErrorMessage(err)}`); } } return throwCapabilityGenerationFailure({ capabilityLabel: "image generation", attempts, lastError }); } //#endregion export { listRuntimeImageGenerationProviders as n, generateImage as t };