UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

226 lines (225 loc) 9.72 kB
import { t as formatErrorMessage } from "./errors-Db3Ymjlb.js"; import { t as createSubsystemLogger } from "./subsystem-Dy2tqXOS.js"; import { o as resolveAgentModelTimeoutMsValue } from "./model-input-BuGMCNOz.js"; import "./provider-env-vars-B8XgJCSL.js"; import { a as isFailoverError } from "./error-Bb_OF8ag.js"; import { i as describeFailoverError } from "./failover-error-BkNxlp8A.js"; import { a as resolveCapabilityModelCandidates, d as throwCapabilityGenerationFailure, i as recordCapabilityCandidateFailure, l as resolveMediaProviderRequestTimeoutMs, n as buildNoCapabilityModelConfiguredMessage, t as buildMediaGenerationNormalizationMetadata, u as resolveReferenceImageCapabilityError } from "./runtime-shared-DRaKQShq.js"; import { i as listImageGenerationProviders, s as parseGenerationModelRef, t as getImageGenerationProvider } from "./registry-BFqDasrd.js"; import { n as hasMediaNormalizationEntry, t as resolveMediaGeometryOverrides } from "./geometry-normalization-ecjI7wns.js"; //#region src/image-generation/capabilities.ts function resolveImageGenerationMaxInputImages(params) { const model = params.model?.trim(); let prefixLimit; let prefixLength = -1; if (model) { for (const [prefix, limit] of Object.entries(params.provider.capabilities.edit.maxInputImagesByModelPrefix ?? {})) if (prefix.length > prefixLength && model.startsWith(prefix)) { prefixLimit = limit; prefixLength = prefix.length; } } return (model ? params.provider.capabilities.edit.maxInputImagesByModel?.[model] : void 0) ?? prefixLimit ?? params.provider.capabilities.edit.maxInputImages; } //#endregion //#region src/image-generation/normalization.ts /** Normalizes image generation request overrides against provider/model capabilities. */ /** Returns supported image overrides plus ignored/normalized override metadata for replies. */ function resolveImageGenerationOverrides(params) { const modeCaps = params.inputImages?.length ? params.provider.capabilities.edit : params.provider.capabilities.generate; const geometry = params.provider.capabilities.geometry; const sanitized = resolveMediaGeometryOverrides({ size: params.size, aspectRatio: params.aspectRatio, resolution: params.resolution, capabilities: { ...modeCaps, 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 }, fallbackSizes: geometry?.sizes }); const ignoredOverrides = sanitized.ignoredOverrides; let { quality, outputFormat, background } = params; if (quality && !(params.provider.capabilities.output?.qualities ?? []).includes(quality)) { ignoredOverrides.push({ key: "quality", value: quality }); quality = void 0; } if (outputFormat && !(params.provider.capabilities.output?.formats ?? []).includes(outputFormat)) { ignoredOverrides.push({ key: "outputFormat", value: outputFormat }); outputFormat = void 0; } if (background && !(params.provider.capabilities.output?.backgrounds ?? []).includes(background)) { ignoredOverrides.push({ key: "background", value: background }); background = void 0; } const { normalization } = sanitized; return { size: sanitized.size, aspectRatio: sanitized.aspectRatio, resolution: sanitized.resolution, quality, outputFormat, background, ignoredOverrides, normalization: hasMediaNormalizationEntry(normalization.size) || hasMediaNormalizationEntry(normalization.aspectRatio) || hasMediaNormalizationEntry(normalization.resolution) ? normalization : void 0 }; } //#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) { const listProviders = deps.listProviders ?? listImageGenerationProviders; return buildNoCapabilityModelConfiguredMessage({ capabilityLabel: "image-generation", modelConfigKey: "mediaModels.image", providers: listProviders(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?.mediaModels?.image); const candidates = resolveCapabilityModelCandidates({ cfg: params.cfg, modelConfig: params.cfg.agents?.defaults?.mediaModels?.image, modelOverride: params.modelOverride, parseModelRef: parseGenerationModelRef, 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; } const inputImageCount = params.inputImages?.length ?? 0; const maxInputImages = resolveImageGenerationMaxInputImages({ provider, model: candidate.model }); const referenceImageError = resolveReferenceImageCapabilityError({ candidateRef: `${candidate.provider}/${candidate.model}`, inputImageCount, edit: { enabled: provider.capabilities.edit.enabled, ...maxInputImages !== void 0 ? { maxInputImages } : {} } }); if (referenceImageError) { recordCapabilityCandidateFailure({ attempts, provider: candidate.provider, model: candidate.model, error: referenceImageError }); lastError = new Error(referenceImageError); logger.warn(`image-generation candidate skipped: ${referenceImageError}`); continue; } try { const timeoutMs = resolveMediaProviderRequestTimeoutMs({ timeoutMs: requestedTimeoutMs, providerDefaultTimeoutMs: provider.defaultTimeoutMs }); const modelResolutions = provider.capabilities.geometry?.resolutionsByModel?.[candidate.model]; const inferredResolution = (params.inputImages?.length ? provider.capabilities.edit : provider.capabilities.generate).supportsResolution === false || modelResolutions?.length === 0 ? void 0 : params.inferredResolution; const sanitized = resolveImageGenerationOverrides({ provider, model: candidate.model, size: params.size, aspectRatio: params.aspectRatio, resolution: params.resolution ?? inferredResolution, 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."); const emptyImageIndex = result.images.findIndex((image) => image.buffer.byteLength === 0); if (emptyImageIndex >= 0) throw new Error(`Image generation provider returned an empty image buffer at index ${emptyImageIndex}.`); return { images: result.images, provider: candidate.provider, model: result.model ?? candidate.model, attempts, ...sanitized.resolution ? { appliedResolution: sanitized.resolution } : {}, 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, resolveImageGenerationMaxInputImages as r, generateImage as t };