/** * Image Generation capability — generate images via BlockRun API. * Uses x402 payment on Solana or Base. */ import type { CapabilityHandler } from '../agent/types.js'; import type { ContentLibrary } from '../content/library.js'; import { type GatewayModel } from '../gateway-models.js'; /** * Models that accept a reference image via /v1/images/image2image. Mirrors the * gateway's EDIT_SUPPORTED_MODELS (src/app/api/v1/images/image2image/route.ts): * both OpenAI gpt-image-* and Google Nano Banana support image-to-image edits. */ export declare const EDIT_SUPPORTED_MODELS: Set; /** * Mask-based inpainting is OpenAI-only. Gemini (Nano Banana) does prompt-based * edits with no mask concept. Mirrors the gateway's MASK_SUPPORTED_MODELS. */ export declare const MASK_SUPPORTED_MODELS: Set; /** * Output-image count ceiling. The gateway has no hard max but price scales with * n, so cap client-side to keep a typo from draining the wallet. */ export declare const MAX_OUTPUT_IMAGES = 4; /** * Valid sizes per known image model, mirroring the gateway's IMAGE_MODELS.sizes * (src/lib/models.ts). Used to fail cheaply before paying when a caller or the * media router picks a size the model rejects. Models absent from this table * (custom / future gateway models) skip validation and let the gateway decide. */ export declare const IMAGE_MODEL_SIZES: Record; export declare const REFERENCE_IMAGE_MAX_BYTES = 4000000; /** * Resolve the per-image USD cost used for the budget check, spend confirm, and * asset record. Two sources, neither sufficient alone: * - the live catalog price is authoritative for models the static table omits * (closing the $0-budget bypass), but it is SIZE-BLIND — a single flat * per_image figure that ignores the larger, pricier tiers; * - the static table is SIZE-AWARE (e.g. gpt-image-1 is $0.02 at 1024x1024 but * $0.04 at 1536x1024) but only covers a handful of models. * Take the HIGHER of the two so none of the three consumers ever undercounts the * real charge for a large, non-1024 size. The static figures are base prices with * NO gateway margin, whereas estimateCostUsd already applies GATEWAY_MARGIN — so * we margin-adjust the static operand before the Math.max, keeping both on the * realized-charge basis (otherwise the size-aware path would undercount by ~5%). * Exported for regression tests. */ export declare function resolveImageUnitCost(catalogModel: GatewayModel | null, model: string, size: string): number; /** * Normalize a reference image into a base64 data URI for the gateway. The * /v1/images/image2image endpoint validates `image` against /^data:image\//, * so http(s) URLs and local paths both have to be inlined client-side before * posting. Already-formed data URIs pass through. */ export declare function resolveReferenceImage(input: string, workingDir: string): Promise; export interface ImageGenDeps { /** Optional Content library for auto-recording generations into a piece. */ library?: ContentLibrary; /** Invoked after successful content-linked generation; lets callers persist. */ onContentChange?: () => void | Promise; } /** Insert a `-{idx}` suffix before the file extension: a.png → a-2.png. */ export declare function withIndexSuffix(p: string, idx: number): string; /** * Build the ImageGen capability. Passing `deps.library` enables the * contentId flow: pre-flight budget check + post-generation asset * recording. With no deps, behavior matches the pre-factory version. */ export declare function createImageGenCapability(deps?: ImageGenDeps): CapabilityHandler; /** Back-compat static capability for callers that don't want the Content bridge. */ export declare const imageGenCapability: CapabilityHandler; export interface ImagePollBody { data?: { b64_json?: string; url?: string; revised_prompt?: string; }[]; error?: unknown; status?: string; } export type ImagePollOutcome = { kind: 'completed'; body: ImagePollBody; } | { kind: 'failed'; error?: unknown; } | { kind: 'timed_out'; } | { kind: 'poll_http_error'; status: number; bodyPreview: string; }; export interface PollImageJobOptions { /** Total wall-clock ceiling. Defaults to 5 min (matches videogen scale). */ maxWaitMs?: number; /** Sleep between polls. Defaults to 3 s. */ intervalMs?: number; } export declare function pollImageJob(pollEndpoint: string, headers: Record, signal: AbortSignal, options?: PollImageJobOptions): Promise;