{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/client.ts","../src/extras.ts","../src/helpers.ts"],"sourcesContent":["/**\n * Pollinations SDK\n *\n * The easiest way to add AI to your app.\n * Images, text, audio, video - all in one package.\n *\n * @example\n * ```ts\n * import { generateImage, generateText } from '@pollinations/sdk';\n *\n * const image = await generateImage('a cat in space');\n * await image.saveToFile('cat.png');\n *\n * const text = await generateText('why is the sky blue?');\n * ```\n */\n\n// Main client class\nexport { Pollinations } from \"./client.js\";\n// Extra utilities\nexport {\n    type AudioResponseExt,\n    type ChatResponseExt,\n    // Conversation class\n    Conversation,\n    // Extended response types with helpers\n    type ImageResponseExt,\n    type VideoResponseExt,\n    wrapAudioResponse,\n    wrapChatResponse,\n    // Response wrappers (for advanced use)\n    wrapImageResponse,\n    wrapVideoResponse,\n} from \"./extras.js\";\n// Helper functions\nexport {\n    authorizeDevice,\n    authorizeUrl,\n    chat,\n    chatStream,\n    configure,\n    conversation,\n    createKey,\n    editImage,\n    generateAudio,\n    generateImage,\n    generateText,\n    generateTextStream,\n    generateVideo,\n    getBalance,\n    getDailyUsage,\n    getImageModels,\n    getKeyUsage,\n    getModels,\n    getProfile,\n    getTextModels,\n    getUsage,\n    imageGenerate,\n    imageUrl,\n    listKeys,\n    resetClient,\n    revokeKey,\n    transcribe,\n    upload,\n    userInfo,\n    validateKey,\n    videoUrl,\n} from \"./helpers.js\";\n\n// Export all types\nexport type {\n    AccountBalance,\n    AccountKey,\n    AccountPermission,\n    AccountProfile,\n    AudioBinaryResponse,\n    AudioContentPart,\n    AudioFormat,\n    AudioGenerateOptions,\n    // Audio\n    AudioModel,\n    AudioResponse,\n    AudioVoice,\n    AuthorizeDeviceOptions,\n    AuthorizeOptions,\n    BuiltInToolType,\n    ChatChoice,\n    ChatOptions,\n    ChatResponse,\n    ChatStreamChunk,\n    CompletionUsage,\n    CreatedKey,\n    CreateKeyOptions,\n    DailyUsageRecord,\n    DailyUsageResponse,\n    DeviceAuthorization,\n    DeviceCodeResponse,\n    DeviceTokenResponse,\n    FileContentPart,\n    FunctionDefinition,\n    ImageContentPart,\n    ImageEditOptions,\n    ImageGenerateOptions,\n    ImageGenerateV1Options,\n    // Image\n    ImageModel,\n    ImageQuality,\n    ImageResponse,\n    JsonSchema,\n    KeyAccountPermission,\n    KeyInfo,\n    KeyUsageOptions,\n    Message,\n    MessageContent,\n    MessageContentPart,\n    MessageRole,\n    ModelInfo,\n    // Models\n    ModelTier,\n    // Config\n    PollinationsConfig,\n    // Errors\n    PollinationsErrorDetails,\n    RequestOptions,\n    ResponseFormat,\n    TextContentPart,\n    TextGenerateOptions,\n    // Text\n    TextModel,\n    ThinkingOptions,\n    Tool,\n    ToolCall,\n    TranscribeOptions,\n    TranscriptionModel,\n    TranscriptionResponse,\n    TranscriptionResponseFormat,\n    TranscriptionVerboseResponse,\n    UploadOptions,\n    UploadResponse,\n    UsageOptions,\n    UsageRecord,\n    UsageResponse,\n    UserInfo,\n    VideoContentPart,\n    VideoGenerateOptions,\n    // Video\n    VideoModel,\n    VideoResponse,\n} from \"./types.js\";\n\n// Export the error class\nexport { PollinationsError } from \"./types.js\";\n","export interface PollinationsConfig {\n    /** API key for authentication (get one at https://enter.pollinations.ai) */\n    apiKey?: string;\n    /** Base URL for the API (defaults to https://gen.pollinations.ai) */\n    baseUrl?: string;\n    /** Maximum number of retry attempts (default: 3) */\n    maxRetries?: number;\n    /** Default timeout in ms for all requests (default: 300000 = 5min) */\n    timeout?: number;\n    /** Timeout in ms for text requests (default: 300000 = 5min) */\n    textTimeout?: number;\n    /** Timeout in ms for image requests (default: 600000 = 10min) */\n    imageTimeout?: number;\n    /** Timeout in ms for video requests (default: 600000 = 10min) */\n    videoTimeout?: number;\n}\n\n/** Common options for all request methods */\nexport interface RequestOptions {\n    /** AbortSignal for request cancellation */\n    signal?: AbortSignal;\n}\n\n// ============================================================================\n// Image Generation\n// ============================================================================\n\n/** Image model (use getImageModels() to fetch available models) */\nexport type ImageModel = string;\n\n/** Available video models */\nexport type VideoModel = string;\n\n/** Image quality options */\nexport type ImageQuality = \"low\" | \"medium\" | \"high\" | \"hd\";\n\n/** Reasoning depth for supported image models */\nexport type ImageReasoningMode = \"fast\" | \"balanced\" | \"pro\";\n\n/** Options for image generation */\nexport interface ImageGenerateOptions extends RequestOptions {\n    /** Image model to use (default: 'zimage') */\n    model?: ImageModel;\n    /** Image width in pixels (default: 1024) */\n    width?: number;\n    /** Image height in pixels (default: 1024) */\n    height?: number;\n    /** Seed for reproducible generation (default: random) */\n    seed?: number;\n    /** Let AI enhance/improve your prompt (default: false) */\n    enhance?: boolean;\n    /** Negative prompt - what to avoid in the image */\n    negativePrompt?: string;\n    /** Keep generation private (default: false) */\n    private?: boolean;\n    /** Remove watermark logo (default: false) */\n    nologo?: boolean;\n    /** Don't show in public feed (default: false) */\n    nofeed?: boolean;\n    /** Enable safety content filters (default: false) */\n    safe?: boolean;\n    /** Output quality (default: 'medium') */\n    quality?: ImageQuality;\n    /** Reference image URL(s) for image-to-image generation */\n    referenceImage?: string | string[];\n    /** Enable transparent background - outputs PNG (default: false) */\n    transparent?: boolean;\n    /** How closely to follow prompt, 1-20 (higher = stricter) */\n    guidanceScale?: number;\n    /**\n     * Reasoning mode for supported image models.\n     * Booleans are accepted for backward compatibility: true = \"pro\",\n     * false = \"balanced\".\n     */\n    reasoning?: boolean | ImageReasoningMode;\n}\n\n/** Options for image editing (POST /v1/images/edits) */\nexport interface ImageEditOptions extends RequestOptions {\n    /** Image model to use (default: 'flux') */\n    model?: ImageModel;\n    /** Source image URL(s) for editing */\n    image?: string | string[];\n}\n\n/** Response from image generation */\nexport interface ImageResponse {\n    /** The generated image as a Buffer (Node.js) or ArrayBuffer (browser) */\n    buffer: ArrayBuffer;\n    /** Content type (image/jpeg or image/png) */\n    contentType: string;\n    /** The URL that was used to generate the image */\n    url: string;\n}\n\n// ============================================================================\n// Video Generation\n// ============================================================================\n\n/** Options for video generation */\nexport interface VideoGenerateOptions extends RequestOptions {\n    /** Video model to use (default: 'veo') */\n    model?: VideoModel;\n    /** Duration in seconds (1-30, varies by model) */\n    duration?: number;\n    /** Aspect ratio (e.g., '16:9', '9:16', '1:1') */\n    aspectRatio?: string;\n    /** Seed for reproducible generation */\n    seed?: number;\n    /** Enable audio generation where supported by the selected video model */\n    audio?: boolean;\n    /** Reference image URL(s) for image-to-video. For video, image[0] is the start frame and image[1] is the end frame when supported. */\n    referenceImage?: string | string[];\n    /** Keep generation private (default: false) */\n    private?: boolean;\n    /** Remove watermark logo (default: false) */\n    nologo?: boolean;\n    /** Enable safety content filters (default: false) */\n    safe?: boolean;\n}\n\n/** Response from video generation */\nexport interface VideoResponse {\n    /** The generated video as a Buffer (Node.js) or ArrayBuffer (browser) */\n    buffer: ArrayBuffer;\n    /** Content type (video/mp4) */\n    contentType: string;\n    /** The URL that was used to generate the video */\n    url: string;\n}\n\n// ============================================================================\n// Text Generation\n// ============================================================================\n\n/** Text model (use getTextModels() to fetch available models) */\nexport type TextModel = string;\n\n/** Message roles for chat */\nexport type MessageRole =\n    | \"system\"\n    | \"developer\"\n    | \"user\"\n    | \"assistant\"\n    | \"tool\"\n    | \"function\";\n\n/** Text content part */\nexport interface TextContentPart {\n    type: \"text\";\n    text: string;\n}\n\n/** Image content part for vision */\nexport interface ImageContentPart {\n    type: \"image_url\";\n    image_url: {\n        url: string;\n        detail?: \"auto\" | \"low\" | \"high\";\n        mime_type?: string;\n    };\n}\n\n/** Video content part */\nexport interface VideoContentPart {\n    type: \"video_url\";\n    video_url: {\n        url: string;\n        mime_type?: string;\n    };\n}\n\n/** Audio content part */\nexport interface AudioContentPart {\n    type: \"input_audio\";\n    input_audio: {\n        /** Base64 encoded audio data */\n        data: string;\n        format: \"wav\" | \"mp3\" | \"flac\" | \"opus\" | \"pcm16\";\n    };\n}\n\n/** File content part */\nexport interface FileContentPart {\n    type: \"file\";\n    file: {\n        file_data?: string;\n        file_id?: string;\n        file_name?: string;\n        file_url?: string;\n        mime_type?: string;\n    };\n}\n\n/** All possible content parts */\nexport type MessageContentPart =\n    | TextContentPart\n    | ImageContentPart\n    | VideoContentPart\n    | AudioContentPart\n    | FileContentPart;\n\n/** Message content - either a string or array of content parts */\nexport type MessageContent = string | MessageContentPart[];\n\n/** A chat message */\nexport interface Message {\n    role: MessageRole;\n    content: MessageContent;\n    name?: string;\n    /** For tool messages */\n    tool_call_id?: string;\n}\n\n/** Options for simple text generation */\nexport interface TextGenerateOptions extends RequestOptions {\n    /** Text model to use (default: 'openai') */\n    model?: TextModel;\n    /** System prompt to set context */\n    systemPrompt?: string;\n    /** Seed for reproducible generation */\n    seed?: number;\n    /** Return response as JSON (default: false) */\n    json?: boolean;\n    /** Temperature 0-2, higher = more creative (default: 1) */\n    temperature?: number;\n    /** Maximum tokens to generate */\n    maxTokens?: number;\n    /** Frequency penalty -2 to 2 */\n    frequencyPenalty?: number;\n    /** Presence penalty -2 to 2 */\n    presencePenalty?: number;\n    /** Enable streaming response (default: false) */\n    stream?: boolean;\n    /** Keep generation private (default: false) */\n    private?: boolean;\n}\n\n/** Response format options */\nexport type ResponseFormat =\n    | { type: \"text\" }\n    | { type: \"json_object\" }\n    | { type: \"json_schema\"; json_schema: JsonSchema };\n\n/** JSON schema for structured output */\nexport interface JsonSchema {\n    name: string;\n    description?: string;\n    schema: Record<string, unknown>;\n    strict?: boolean;\n}\n\n/** Tool definition */\nexport interface Tool {\n    type: \"function\";\n    function: {\n        name: string;\n        description?: string;\n        parameters?: Record<string, unknown>;\n        strict?: boolean;\n    };\n}\n\n/** Built-in tool types */\nexport type BuiltInToolType =\n    | \"code_execution\"\n    | \"google_search\"\n    | \"google_maps\"\n    | \"url_context\"\n    | \"computer_use\"\n    | \"file_search\";\n\n/** Thinking/reasoning options */\nexport interface ThinkingOptions {\n    type: \"enabled\" | \"disabled\";\n    budget_tokens?: number;\n}\n\n/** Options for chat completions (POST endpoint) */\nexport interface ChatOptions extends RequestOptions {\n    /** Text model to use (default: 'openai') */\n    model?: TextModel;\n    /** Temperature 0-2 (default: 1) */\n    temperature?: number;\n    /** Top P sampling 0-1 (default: 1) */\n    topP?: number;\n    /** Maximum tokens to generate */\n    maxTokens?: number;\n    /** Frequency penalty -2 to 2 */\n    frequencyPenalty?: number;\n    /** Presence penalty -2 to 2 */\n    presencePenalty?: number;\n    /** Repetition penalty */\n    repetitionPenalty?: number;\n    /** Stop sequences (max 4) */\n    stop?: string | string[];\n    /** Seed for reproducible generation */\n    seed?: number;\n    /** Enable streaming response (default: false) */\n    stream?: boolean;\n    /** Include usage stats in streaming response */\n    streamOptions?: { include_usage?: boolean };\n    /** Response format */\n    responseFormat?: ResponseFormat;\n    /** Tools available to the model */\n    tools?: (Tool | { type: BuiltInToolType })[];\n    /** Tool choice: 'none', 'auto', 'required', or specific function */\n    toolChoice?:\n        | \"none\"\n        | \"auto\"\n        | \"required\"\n        | { type: \"function\"; function: { name: string } };\n    /** Allow parallel tool calls (default: true) */\n    parallelToolCalls?: boolean;\n    /** Enable thinking/reasoning for supported models */\n    thinking?: ThinkingOptions | null;\n    /** Reasoning effort for thinking models */\n    reasoningEffort?: \"low\" | \"medium\" | \"high\";\n    /** Thinking budget in tokens */\n    thinkingBudget?: number;\n    /** Output modalities */\n    modalities?: (\"text\" | \"audio\")[];\n    /** Audio output options */\n    audio?: {\n        voice?: AudioVoice;\n        format?: AudioFormat;\n    };\n    /** User identifier for tracking */\n    user?: string;\n    /** Logit bias for token probabilities */\n    logitBias?: Record<string, number>;\n    /** Return log probabilities */\n    logprobs?: boolean;\n    /** Number of top log probabilities to return (0-20) */\n    topLogprobs?: number;\n    /** Legacy function calling (use tools instead) */\n    functions?: FunctionDefinition[];\n    /** Legacy function call control (use toolChoice instead) */\n    functionCall?: \"none\" | \"auto\" | { name: string };\n}\n\n/** Legacy function definition (use Tool instead) */\nexport interface FunctionDefinition {\n    name: string;\n    description?: string;\n    parameters?: Record<string, unknown>;\n}\n\n/** A tool call in the response */\nexport interface ToolCall {\n    id: string;\n    type: \"function\";\n    function: {\n        name: string;\n        arguments: string;\n    };\n}\n\n/** Token usage information */\nexport interface CompletionUsage {\n    prompt_tokens: number;\n    completion_tokens: number;\n    total_tokens: number;\n    prompt_tokens_details?: {\n        cached_tokens?: number;\n        audio_tokens?: number;\n    };\n    completion_tokens_details?: {\n        reasoning_tokens?: number;\n        audio_tokens?: number;\n    };\n}\n\n/** A choice in the chat response */\nexport interface ChatChoice {\n    index: number;\n    message: {\n        role: \"assistant\";\n        content: string | null;\n        tool_calls?: ToolCall[];\n        audio?: {\n            transcript: string;\n            data: string;\n            id: string;\n            expires_at: number;\n        } | null;\n        reasoning_content?: string | null;\n    };\n    finish_reason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null;\n    logprobs?: {\n        content?: Array<{\n            token: string;\n            logprob: number;\n            bytes?: number[];\n            top_logprobs?: Array<{\n                token: string;\n                logprob: number;\n                bytes?: number[];\n            }>;\n        }>;\n    } | null;\n}\n\n/** Chat completion response */\nexport interface ChatResponse {\n    id: string;\n    object: \"chat.completion\";\n    created: number;\n    model: string;\n    choices: ChatChoice[];\n    usage?: CompletionUsage;\n    system_fingerprint?: string;\n    citations?: string[];\n}\n\n/** A chunk in streaming response */\nexport interface ChatStreamChunk {\n    id: string;\n    object: \"chat.completion.chunk\";\n    created: number;\n    model: string;\n    choices: Array<{\n        index: number;\n        delta: {\n            role?: \"assistant\";\n            content?: string;\n            tool_calls?: Array<{\n                index: number;\n                id?: string;\n                type?: \"function\";\n                function?: {\n                    name?: string;\n                    arguments?: string;\n                };\n            }>;\n        };\n        finish_reason:\n            | \"stop\"\n            | \"length\"\n            | \"tool_calls\"\n            | \"content_filter\"\n            | null;\n    }>;\n    usage?: CompletionUsage;\n}\n\n// ============================================================================\n// Audio Generation\n// ============================================================================\n\n/** Voice option for audio generation */\nexport type AudioVoice = string;\n\n/** Audio format options */\nexport type AudioFormat = \"wav\" | \"mp3\" | \"flac\" | \"opus\" | \"pcm16\";\n\n/** Dedicated audio/music model */\nexport type AudioModel = \"elevenlabs\" | \"elevenmusic\" | \"acestep\" | string;\n\n/** Options for text-to-speech generation (GET /audio/{text} or POST /v1/audio/speech) */\nexport interface AudioGenerateOptions extends RequestOptions {\n    /** Voice to use (default: 'alloy') */\n    voice?: AudioVoice;\n    /** Audio model to use (default: 'elevenlabs') */\n    model?: AudioModel;\n    /** Duration in seconds (for music models like elevenmusic, acestep) */\n    duration?: number;\n    /** Seed for reproducibility */\n    seed?: number;\n}\n\n/** Response from dedicated audio endpoints (binary audio data) */\nexport interface AudioBinaryResponse {\n    /** The generated audio as a Buffer (Node.js) or ArrayBuffer (browser) */\n    buffer: ArrayBuffer;\n    /** Content type (audio/mpeg) */\n    contentType: string;\n}\n\n/** Audio response from chat with audio modality */\nexport interface AudioResponse {\n    /** Transcript of the audio */\n    transcript: string;\n    /** Base64 encoded audio data */\n    data: string;\n    /** Audio ID */\n    id: string;\n    /** Expiration timestamp */\n    expiresAt: number;\n}\n\n// ============================================================================\n// Speech-to-Text (Transcription)\n// ============================================================================\n\n/** STT model options */\nexport type TranscriptionModel =\n    | \"whisper-large-v3\"\n    | \"whisper-1\"\n    | \"scribe\"\n    | \"universal-2\"\n    | \"universal-3-pro\"\n    | string;\n\n/** Response format for transcription */\nexport type TranscriptionResponseFormat =\n    | \"json\"\n    | \"text\"\n    | \"verbose_json\"\n    | \"srt\"\n    | \"vtt\";\n\n/** Options for speech-to-text transcription */\nexport interface TranscribeOptions extends RequestOptions {\n    /** Model to use (default: 'whisper-large-v3') */\n    model?: TranscriptionModel;\n    /** Language code (ISO-639-1, e.g. 'en', 'fr') */\n    language?: string;\n    /** Response format (default: 'json') */\n    responseFormat?: TranscriptionResponseFormat;\n    /** Optional prompt to guide transcription style */\n    prompt?: string;\n    /** Temperature 0-1 for sampling */\n    temperature?: number;\n}\n\n/** Transcription response */\nexport interface TranscriptionResponse {\n    /** Transcribed text */\n    text: string;\n}\n\n/** Verbose transcription response with word/segment details */\nexport interface TranscriptionVerboseResponse extends TranscriptionResponse {\n    task: string;\n    language: string;\n    duration: number;\n    words?: Array<{ word: string; start: number; end: number }>;\n    segments?: Array<{ id: number; start: number; end: number; text: string }>;\n}\n\n// ============================================================================\n// Media Upload\n// ============================================================================\n\n/** Options for media upload */\nexport interface UploadOptions extends RequestOptions {\n    /** Original filename (optional) */\n    name?: string;\n    /** Content type (auto-detected if omitted) */\n    contentType?: string;\n}\n\n/** Response from media upload */\nexport interface UploadResponse {\n    /** Content-addressed hash ID */\n    id: string;\n    /** Public URL for the uploaded media */\n    url: string;\n    /** Content type of the uploaded file */\n    contentType: string;\n    /** File size in bytes */\n    size: number;\n    /** Whether the file was already uploaded (dedup) */\n    duplicate: boolean;\n}\n\n// ============================================================================\n// BYOP (Bring Your Own Pollen)\n// ============================================================================\n\n/** Account permission scopes */\nexport type AccountPermission = \"profile\" | \"usage\" | \"keys\";\n\n/** Options for building a BYOP authorization URL */\nexport interface AuthorizeOptions {\n    /** URL to redirect back to after authorization */\n    redirectUrl: string;\n    /** Your app's publishable key (shows app name to user) */\n    appKey?: string;\n    /** OAuth state value echoed back to the redirect URL */\n    state?: string;\n    /** Authorization host (defaults to https://enter.pollinations.ai) */\n    authBaseUrl?: string;\n    /** Restrict to specific models */\n    models?: string[];\n    /** Numeric pollen cap. Omit for the default cap. */\n    budget?: number;\n    /** Key lifetime in days (default: 30) */\n    expiry?: number;\n    /** Account permissions to request */\n    permissions?: AccountPermission[];\n}\n\n// ============================================================================\n// Account\n// ============================================================================\n\n/** User profile information */\nexport interface AccountProfile {\n    githubUsername: string | null;\n    image: string | null;\n    /** Current tier level (e.g. `\"spore\"`, `\"seed\"`, `\"flower\"`, `\"nectar\"`). */\n    tier: string;\n    /** ISO 8601 timestamp of the next pollen refill. `null` for tiers with no refill. */\n    nextResetAt: string | null;\n    /** Only returned when the API key has the `profile` permission */\n    name?: string | null;\n    /** Only returned when the API key has the `profile` permission */\n    email?: string | null;\n}\n\n/** Account balance */\nexport interface AccountBalance {\n    balance: number;\n}\n\n/** Usage record */\nexport interface UsageRecord {\n    timestamp: string;\n    type: string;\n    model: string;\n    api_key: string;\n    api_key_type: string;\n    meter_source: string;\n    input_text_tokens: number;\n    input_cached_tokens: number;\n    input_audio_tokens: number;\n    input_audio_seconds: number;\n    input_image_tokens: number;\n    output_text_tokens: number;\n    output_reasoning_tokens: number;\n    output_audio_tokens: number;\n    output_audio_seconds: number;\n    output_image_tokens: number;\n    output_video_seconds: number;\n    cost_usd: number;\n    response_time_ms: number;\n}\n\n/** Usage response */\nexport interface UsageResponse {\n    usage: UsageRecord[];\n    count: number;\n}\n\n/** Options for fetching usage */\nexport interface UsageOptions {\n    /** Response format (default: 'json') */\n    format?: \"json\" | \"csv\";\n    /** Number of days to include, max 90 (default: 30) */\n    days?: number;\n    /** Max records to return, 1-50000 (default: 100). CSV exports are capped at 50000. */\n    limit?: number;\n    /** ISO timestamp cursor for pagination */\n    before?: string;\n    /** Exact period granularity */\n    granularity?: \"day\" | \"week\" | \"month\";\n    /** Exact period, e.g. YYYY-MM-DD, YYYY-WNN, or YYYY-MM */\n    period?: string;\n}\n\n/** Options for fetching current-key usage. CSV export is not supported here. */\nexport type KeyUsageOptions = Omit<UsageOptions, \"format\">;\n\n/** Options for fetching daily usage */\nexport interface DailyUsageOptions {\n    /** Response format (default: 'json') */\n    format?: \"json\" | \"csv\";\n    /** Number of days to include, max 90 (default: 90) */\n    days?: number;\n    /** Exact period granularity */\n    granularity?: \"day\" | \"week\" | \"month\";\n    /** Exact period, e.g. YYYY-MM-DD, YYYY-WNN, or YYYY-MM */\n    period?: string;\n    /** Filter to one or more API keys by id */\n    api_key_ids?: string[];\n}\n\n/** Daily usage summary */\nexport interface DailyUsageRecord {\n    date: string;\n    model: string;\n    meter_source: string;\n    requests: number;\n    cost_usd: number;\n}\n\n/** Daily usage response */\nexport interface DailyUsageResponse {\n    usage: DailyUsageRecord[];\n    count: number;\n}\n\n/** API key validation response */\nexport interface KeyInfo {\n    valid: boolean;\n    type: string;\n    name?: string | null;\n    expiresAt?: string | null;\n    expiresIn?: number | null;\n    permissions?: {\n        models?: string[] | null;\n        account?: string[] | null;\n    };\n    pollenBudget?: number | null;\n    rateLimitEnabled?: boolean;\n}\n\n/** Detailed key record returned by GET /account/keys (list) */\nexport interface AccountKey {\n    id: string;\n    name: string;\n    /** First few characters of the key (for identification) */\n    start?: string;\n    prefix: string;\n    type?: string;\n    createdAt: string;\n    expiresAt: string | null;\n    lastRequest: string | null;\n    permissions: {\n        tier?: string[];\n        models?: string[];\n        account?: string[];\n    } | null;\n    metadata: Record<string, unknown> | null;\n    pollenBalance: number | null;\n    enabled: boolean;\n}\n\n/** Key-scope permissions that can be granted on created keys. */\nexport type KeyAccountPermission = \"profile\" | \"usage\" | \"keys\" | string;\n\n/** Options for POST /account/keys */\nexport interface CreateKeyOptions {\n    /** Human-readable name */\n    name: string;\n    /** Key type (default: \"secret\") */\n    type?: \"secret\" | \"publishable\";\n    /** Expiry in seconds from creation */\n    expiresIn?: number;\n    /** Restrict to specific model IDs */\n    allowedModels?: string[];\n    /** Pollen budget cap */\n    pollenBudget?: number;\n    /**\n     * Account permissions to grant (e.g. `[\"profile\", \"usage\"]`).\n     * Without this, scoped keys cannot read account state beyond their\n     * own key metadata, budget, and per-key usage.\n     * `\"keys\"` is auto-stripped server-side on the BYOP flow.\n     */\n    accountPermissions?: KeyAccountPermission[];\n    /**\n     * Allowed OAuth redirect URIs for publishable app keys. Required when\n     * creating a `publishable` key that drives the `/authorize` BYOP flow.\n     * Matching pins scheme, host, port, and path; one trailing slash is\n     * ignored; loopback ports are matched port-agnostically.\n     */\n    redirectUris?: string[];\n    /**\n     * Opt the publishable app key into developer earnings. Defaults to\n     * `false` server-side; only meaningful on `type: \"publishable\"` keys.\n     */\n    earningsEnabled?: boolean;\n}\n\n/**\n * Response from POST /account/keys — includes the raw `key` value which\n * is ONLY shown at creation time. Store it immediately.\n */\nexport interface CreatedKey {\n    id: string;\n    /** The secret key value. Only returned once at creation. */\n    key: string;\n    name: string;\n    type: string;\n    prefix: string;\n    expiresAt: string | null;\n    permissions: {\n        models?: string[];\n        account?: string[];\n    } | null;\n    pollenBudget: number | null;\n}\n\n// ============================================================================\n// Model Information\n// ============================================================================\n\n/** Model tier levels */\nexport type ModelTier = \"anonymous\" | \"seed\" | \"flower\" | \"nectar\";\n\n/** Per-model video frame-control capabilities (video models only) */\nexport type VideoCapability =\n    | \"start_frame\"\n    | \"end_frame\"\n    | \"keyframes\"\n    | \"audio_output\";\n\n/** Model information */\nexport interface ModelInfo {\n    name: string;\n    description?: string;\n    aliases?: string[];\n    tier?: ModelTier;\n    community?: boolean;\n    input_modalities?: string[];\n    output_modalities?: string[];\n    video_capabilities?: VideoCapability[];\n    tools?: boolean;\n    vision?: boolean;\n    audio?: boolean;\n    reasoning?: boolean;\n    uncensored?: boolean;\n    voices?: string[];\n    maxInputChars?: number;\n    context_length?: number;\n    supportsSystemMessages?: boolean;\n    is_specialized?: boolean;\n    pricing?: {\n        currency: \"pollen\";\n        input_token_price?: number;\n        output_token_price?: number;\n        cached_token_price?: number;\n        image_price?: number;\n        audio_input_price?: number;\n        audio_output_price?: number;\n    };\n}\n\n// ============================================================================\n// Device Flow (OAuth)\n// ============================================================================\n\n/** Raw response from POST /api/device/code */\nexport interface DeviceCodeResponse {\n    device_code: string;\n    user_code: string;\n    verification_uri_complete: string;\n    expires_in: number;\n    interval: number;\n}\n\n/** Raw response from POST /api/device/token (polling) */\nexport interface DeviceTokenResponse {\n    access_token?: string;\n    error?: string;\n    error_description?: string;\n}\n\n/** Options for starting device flow */\nexport interface AuthorizeDeviceOptions extends RequestOptions {\n    /** OAuth client ID. Defaults to the public polli CLI client. */\n    clientId?: string;\n    /** Space-separated scope string (default: \"generate keys usage\") */\n    scope?: string;\n}\n\n/**\n * Handle returned by `authorizeDevice()` — surfaces the user-facing\n * verification URL/code, and exposes `poll()` to block until approval.\n */\nexport interface DeviceAuthorization {\n    /** Short code the user types in the verification page */\n    userCode: string;\n    /** URL to open in a browser (includes the user code as a query param) */\n    verificationUri: string;\n    /** When the device code expires and polling must stop */\n    expiresAt: Date;\n    /** Block until the user approves. Resolves with an access token or throws. */\n    poll(): Promise<string>;\n}\n\n/** User identity returned by GET /api/device/userinfo */\nexport interface UserInfo {\n    sub?: string;\n    name?: string;\n    email?: string;\n    githubUsername?: string;\n    tier?: string;\n    [key: string]: unknown;\n}\n\n// ============================================================================\n// Image Generation (OpenAI-compatible POST /v1/images/generations)\n// ============================================================================\n\n/** Options for POST /v1/images/generations */\nexport interface ImageGenerateV1Options extends RequestOptions {\n    /** Image model to use (default: 'zimage') */\n    model?: ImageModel;\n    /** Size string like \"1024x1024\". Alternative to width + height. */\n    size?: string;\n    /** Image width in pixels (converted to `size` when both dimensions provided) */\n    width?: number;\n    /** Image height in pixels */\n    height?: number;\n    /** Number of images to generate (default: 1) */\n    n?: number;\n    /** Response format (default: server decides — usually b64_json) */\n    responseFormat?: \"url\" | \"b64_json\";\n    /** Reasoning mode for supported image models. Booleans are accepted for backward compatibility. */\n    reasoning?: boolean | ImageReasoningMode;\n    /** Seed for reproducible generation */\n    seed?: number;\n    /** Output quality */\n    quality?: ImageQuality;\n    /** Negative prompt - what to avoid */\n    negativePrompt?: string;\n}\n\n// ============================================================================\n// Error Types\n// ============================================================================\n\n/** API error details */\nexport interface PollinationsErrorDetails {\n    code:\n        | \"BAD_REQUEST\"\n        | \"UNAUTHORIZED\"\n        | \"INSUFFICIENT_BALANCE\"\n        | \"PERMISSION_DENIED\"\n        | \"INTERNAL_ERROR\"\n        | string;\n    message: string;\n    timestamp: string;\n    details?: Record<string, unknown>;\n    requestId?: string;\n}\n\n/** Pollinations SDK Error */\nexport class PollinationsError extends Error {\n    code: string;\n    status: number;\n    details?: Record<string, unknown>;\n    requestId?: string;\n    /** Retry-After value in seconds (for 429 rate limit errors) */\n    retryAfter?: number;\n\n    constructor(\n        message: string,\n        code: string,\n        status: number,\n        details?: Record<string, unknown>,\n        requestId?: string,\n        retryAfter?: number,\n    ) {\n        super(message);\n        this.name = \"PollinationsError\";\n        this.code = code;\n        this.status = status;\n        this.details = details;\n        this.requestId = requestId;\n        this.retryAfter = retryAfter;\n    }\n}\n","import type {\n    AccountBalance,\n    AccountKey,\n    AccountProfile,\n    AudioBinaryResponse,\n    AudioGenerateOptions,\n    AuthorizeDeviceOptions,\n    AuthorizeOptions,\n    ChatOptions,\n    ChatResponse,\n    ChatStreamChunk,\n    CreatedKey,\n    CreateKeyOptions,\n    DailyUsageOptions,\n    DailyUsageResponse,\n    DeviceAuthorization,\n    DeviceCodeResponse,\n    DeviceTokenResponse,\n    ImageEditOptions,\n    ImageGenerateOptions,\n    ImageGenerateV1Options,\n    ImageResponse,\n    KeyInfo,\n    KeyUsageOptions,\n    Message,\n    ModelInfo,\n    PollinationsConfig,\n    PollinationsErrorDetails,\n    RequestOptions,\n    TextGenerateOptions,\n    TranscribeOptions,\n    TranscriptionResponse,\n    TranscriptionVerboseResponse,\n    UploadOptions,\n    UploadResponse,\n    UsageOptions,\n    UsageResponse,\n    UserInfo,\n    VideoGenerateOptions,\n    VideoResponse,\n} from \"./types.js\";\nimport { PollinationsError } from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"https://gen.pollinations.ai\";\nexport const AUTH_BASE_URL = \"https://enter.pollinations.ai\";\nconst DEVICE_FLOW_CLIENT_ID = \"pk_NgBAArhUeGvSRFba\";\nconst DEVICE_FLOW_DEFAULT_SCOPE = \"generate keys usage\";\nconst DEFAULT_MAX_RETRIES = 3;\nconst MAX_INT32 = 2147483647;\n// Default timeouts in milliseconds\nconst DEFAULT_TIMEOUT = 300_000; // 5min for text/chat\nconst DEFAULT_IMAGE_TIMEOUT = 600_000; // 10min for images\nconst DEFAULT_VIDEO_TIMEOUT = 600_000; // 10min for videos\n\n// HTTP status codes that should NOT be retried\nconst NON_RETRIABLE_CODES = [400, 401, 402, 403, 404, 422];\n\n// Default Retry-After delay when header is missing (seconds)\nconst DEFAULT_RETRY_AFTER = 60;\n// Cap honored Retry-After so a malicious or misconfigured upstream\n// cannot force the client into an indefinite sleep.\nconst MAX_RETRY_AFTER_SECONDS = 300;\n\n// Helper to get env var (works in Node.js, Deno, Bun, and edge runtimes)\nfunction getEnvVar(name: string): string | undefined {\n    try {\n        const g = globalThis as Record<string, unknown>;\n        if (g.process && typeof g.process === \"object\") {\n            const proc = g.process as {\n                env?: Record<string, string | undefined>;\n            };\n            if (proc.env) return proc.env[name];\n        }\n        if (g.Deno && typeof g.Deno === \"object\") {\n            const deno = g.Deno as {\n                env?: { get?: (k: string) => string | undefined };\n            };\n            if (deno.env?.get) return deno.env.get(name);\n        }\n    } catch {\n        return undefined;\n    }\n    return undefined;\n}\n\n// Generate a random seed (0 to MAX_INT32)\nfunction randomSeed(): number {\n    return Math.floor(Math.random() * MAX_INT32);\n}\n\n// Resolve seed: if -1, generate random; otherwise use as-is\nfunction resolveSeed(seed: number | undefined): number | undefined {\n    if (seed === -1) {\n        return randomSeed();\n    }\n    return seed;\n}\n\n// Sleep helper for retry delays\nfunction sleep(ms: number): Promise<void> {\n    return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// Exponential backoff delay: 1s, 2s, 4s\nfunction getRetryDelay(attempt: number, retryAfterSeconds?: number): number {\n    if (retryAfterSeconds !== undefined && retryAfterSeconds > 0) {\n        return retryAfterSeconds * 1000;\n    }\n    return 2 ** attempt * 1000;\n}\n\n// Parse Retry-After header (can be seconds or HTTP date)\nfunction parseRetryAfter(response: Response): number | undefined {\n    const retryAfter = response.headers.get(\"Retry-After\");\n    if (!retryAfter) return undefined;\n\n    // Try parsing as number of seconds.\n    // Use Number() (not parseInt) so malformed values like \"5abc\" or \"5e2x\"\n    // are rejected instead of being silently truncated into an aggressive\n    // retry delay.\n    const seconds = Number(retryAfter);\n    if (Number.isFinite(seconds) && seconds >= 0) {\n        return Math.min(seconds, MAX_RETRY_AFTER_SECONDS);\n    }\n\n    // Try parsing as HTTP date\n    const date = Date.parse(retryAfter);\n    if (!Number.isNaN(date)) {\n        const delayMs = date - Date.now();\n        return delayMs > 0 ? Math.ceil(delayMs / 1000) : undefined;\n    }\n\n    return undefined;\n}\n\n// Check if an error should be retried\nfunction isRetriableError(error: unknown): boolean {\n    if (error instanceof PollinationsError) {\n        // Don't retry client errors (4xx except rate limits)\n        return !NON_RETRIABLE_CODES.includes(error.status);\n    }\n    // Network errors, timeouts, etc. are retriable\n    return true;\n}\n\n// Fetch with timeout using AbortController\n// Supports both internal timeout and external signal for cancellation\nasync function fetchWithTimeout(\n    url: string,\n    options: RequestInit,\n    timeoutMs: number,\n    externalSignal?: AbortSignal,\n): Promise<Response> {\n    const controller = new AbortController();\n    const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n    // If an external signal is provided, abort our controller when it aborts\n    const abortHandler = externalSignal ? () => controller.abort() : undefined;\n    if (externalSignal && abortHandler) {\n        externalSignal.addEventListener(\"abort\", abortHandler);\n    }\n\n    try {\n        const response = await fetch(url, {\n            ...options,\n            signal: controller.signal,\n        });\n        return response;\n    } catch (err) {\n        // Check if it was cancelled by external signal\n        if (externalSignal?.aborted) {\n            throw new PollinationsError(\n                \"Request was cancelled\",\n                \"CANCELLED\",\n                499, // Client Closed Request\n            );\n        }\n        if ((err as Error).name === \"AbortError\") {\n            throw new PollinationsError(\n                `Request timed out after ${timeoutMs}ms`,\n                \"TIMEOUT\",\n                408,\n            );\n        }\n        throw err;\n    } finally {\n        clearTimeout(timeoutId);\n        if (externalSignal && abortHandler) {\n            externalSignal.removeEventListener(\"abort\", abortHandler);\n        }\n    }\n}\n\n// Strip API key from URL for safe sharing\nfunction stripKeyFromUrl(url: string): string {\n    const urlObj = new URL(url);\n    urlObj.searchParams.delete(\"key\");\n    return urlObj.toString();\n}\n\n// SSE parsing result\ninterface SSEParseResult<T> {\n    chunks: T[];\n    remainingBuffer: string;\n}\n\n// Parse SSE lines from buffer and extract data\nfunction parseSSEBuffer<T>(\n    buffer: string,\n    parseChunk: (data: string) => T | null,\n): SSEParseResult<T> {\n    const lines = buffer.split(\"\\n\");\n    const remainingBuffer = lines.pop() || \"\";\n    const chunks: T[] = [];\n\n    for (const line of lines) {\n        const trimmed = line.trim();\n        if (!trimmed || trimmed === \"data: [DONE]\") continue;\n        if (trimmed.startsWith(\"data: \")) {\n            try {\n                const parsed = parseChunk(trimmed.slice(6));\n                if (parsed !== null) {\n                    chunks.push(parsed);\n                }\n            } catch {\n                // Skip invalid JSON\n            }\n        }\n    }\n\n    return { chunks, remainingBuffer };\n}\n\n/**\n * Pollinations AI Client\n *\n * A comprehensive client for interacting with the Pollinations AI API.\n * Supports image, video, text, and audio generation.\n *\n * @example Basic usage\n * ```ts\n * const client = new Pollinations({ apiKey: 'your_api_key' });\n * const { buffer } = await client.image('A cute robot');\n * ```\n *\n * @example With environment variable (auto-detected)\n * ```ts\n * // Set POLLINATIONS_API_KEY in your environment\n * const client = new Pollinations();\n * ```\n */\nexport class Pollinations {\n    private apiKey: string;\n    private baseUrl: string;\n    private maxRetries: number;\n    private textTimeout: number;\n    private imageTimeout: number;\n    private videoTimeout: number;\n\n    constructor(config: PollinationsConfig = {}) {\n        // Auto-detect API key from environment if not provided\n        const apiKey = config.apiKey || getEnvVar(\"POLLINATIONS_API_KEY\");\n\n        if (!apiKey) {\n            throw new PollinationsError(\n                \"API key is required. Get one for free at https://enter.pollinations.ai\",\n                \"API_KEY\",\n                401,\n            );\n        }\n\n        this.apiKey = apiKey;\n        this.baseUrl = config.baseUrl?.replace(/\\/$/, \"\") || DEFAULT_BASE_URL;\n        this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;\n\n        // Allow timeout to be a default fallback for all types\n        const defaultTimeout = config.timeout ?? DEFAULT_TIMEOUT;\n        this.textTimeout = config.textTimeout ?? defaultTimeout;\n        this.imageTimeout =\n            config.imageTimeout ??\n            (config.timeout ? config.timeout : DEFAULT_IMAGE_TIMEOUT);\n        this.videoTimeout =\n            config.videoTimeout ??\n            (config.timeout ? config.timeout : DEFAULT_VIDEO_TIMEOUT);\n    }\n\n    // ============================================================================\n    // Private Helpers\n    // ============================================================================\n\n    private getHeaders(contentType?: string): Record<string, string> {\n        const headers: Record<string, string> = {};\n        if (contentType) {\n            headers[\"Content-Type\"] = contentType;\n        }\n        if (this.apiKey) {\n            headers[\"Authorization\"] = `Bearer ${this.apiKey}`;\n        }\n        return headers;\n    }\n\n    private async handleErrorResponse(response: Response): Promise<never> {\n        let errorData: PollinationsErrorDetails | null = null;\n        try {\n            const json = (await response.json()) as {\n                error?: PollinationsErrorDetails;\n            };\n            if (json.error) {\n                errorData = json.error;\n            }\n        } catch {\n            // Response wasn't JSON\n        }\n\n        // Parse Retry-After header for rate limit errors\n        const retryAfter =\n            response.status === 429\n                ? (parseRetryAfter(response) ?? DEFAULT_RETRY_AFTER)\n                : undefined;\n\n        throw new PollinationsError(\n            errorData?.message ||\n                `Request failed with status ${response.status}`,\n            errorData?.code || \"UNKNOWN_ERROR\",\n            response.status,\n            errorData?.details,\n            errorData?.requestId,\n            retryAfter,\n        );\n    }\n\n    private buildQueryParams(\n        params: Record<string, unknown>,\n        includeKey: boolean = true,\n    ): string {\n        const searchParams = new URLSearchParams();\n\n        for (const [key, value] of Object.entries(params)) {\n            if (value === undefined || value === null) continue;\n\n            if (Array.isArray(value)) {\n                searchParams.set(key, value.join(\",\"));\n            } else if (typeof value === \"boolean\") {\n                searchParams.set(key, value ? \"true\" : \"false\");\n            } else {\n                searchParams.set(key, String(value));\n            }\n        }\n\n        // Add API key to query params if set and requested\n        if (includeKey && this.apiKey) {\n            searchParams.set(\"key\", this.apiKey);\n        }\n\n        return searchParams.toString();\n    }\n\n    /** Remove keys whose value is undefined (mutates and returns the body). */\n    private stripUndefined(\n        body: Record<string, unknown>,\n    ): Record<string, unknown> {\n        for (const key of Object.keys(body)) {\n            if (body[key] === undefined) delete body[key];\n        }\n        return body;\n    }\n\n    /**\n     * Run `fn` with exponential-backoff retries on retriable errors.\n     * `attempt` is passed into `fn` so callers can recompute per-attempt\n     * state (e.g. a fresh random seed) on each try.\n     */\n    private async withRetries<T>(\n        fn: (attempt: number) => Promise<T>,\n        fallbackMessage: string,\n    ): Promise<T> {\n        let lastError: Error = new Error(fallbackMessage);\n\n        for (let attempt = 0; attempt < this.maxRetries; attempt++) {\n            try {\n                return await fn(attempt);\n            } catch (err) {\n                lastError = err as Error;\n\n                // Don't retry non-retriable errors (400, 401, 403, 404, 422)\n                if (!isRetriableError(err)) {\n                    throw lastError;\n                }\n\n                if (attempt < this.maxRetries - 1) {\n                    // Use Retry-After from rate limit errors, otherwise exponential backoff\n                    const retryAfter =\n                        err instanceof PollinationsError\n                            ? err.retryAfter\n                            : undefined;\n                    await sleep(getRetryDelay(attempt, retryAfter));\n                }\n            }\n        }\n\n        throw lastError;\n    }\n\n    // ============================================================================\n    // Image Generation\n    // ============================================================================\n\n    /** Build image URL with all params (internal use) */\n    private buildImageUrl(\n        prompt: string,\n        options: ImageGenerateOptions = {},\n        seed?: number,\n    ): string {\n        const params: Record<string, unknown> = {\n            model: options.model || \"zimage\",\n            width: options.width,\n            height: options.height,\n            seed: seed !== undefined ? seed : resolveSeed(options.seed),\n            enhance: options.enhance,\n            negative_prompt: options.negativePrompt,\n            private: options.private,\n            nologo: options.nologo,\n            nofeed: options.nofeed,\n            safe: options.safe,\n            quality: options.quality,\n            image: options.referenceImage,\n            transparent: options.transparent,\n            guidance_scale: options.guidanceScale,\n            reasoning: options.reasoning,\n        };\n\n        const queryString = this.buildQueryParams(params);\n        const encodedPrompt = encodeURIComponent(prompt);\n\n        return `${this.baseUrl}/image/${encodedPrompt}${queryString ? `?${queryString}` : \"\"}`;\n    }\n\n    /**\n     * Generate an image URL from a text prompt.\n     * Hits the API first to authenticate, then returns a keyless URL that can be shared.\n     *\n     * @example\n     * ```ts\n     * const url = await pollinations.imageUrl('A beautiful sunset over mountains');\n     * // Use directly in <img src={url}> - no key exposed!\n     * ```\n     */\n    async imageUrl(\n        prompt: string,\n        options: ImageGenerateOptions = {},\n    ): Promise<string> {\n        const response = await this.image(prompt, options);\n        return response.url; // Already has key stripped\n    }\n\n    /**\n     * Generate an image and return it as binary data.\n     * Automatically retries up to 3 times with exponential backoff on retriable failures.\n     *\n     * @example\n     * ```ts\n     * const { buffer, contentType } = await pollinations.image('A cute robot');\n     * // Save to file or process the buffer\n     * ```\n     */\n    async image(\n        prompt: string,\n        options: ImageGenerateOptions = {},\n    ): Promise<ImageResponse> {\n        if (!prompt || typeof prompt !== \"string\") {\n            throw new PollinationsError(\n                \"Prompt is required and must be a string\",\n                \"INVALID_INPUT\",\n                400,\n            );\n        }\n\n        return this.withRetries(async (attempt) => {\n            // Generate new seed for each retry (or use resolved seed on first attempt)\n            const seed =\n                attempt === 0 ? resolveSeed(options.seed) : randomSeed();\n            const url = this.buildImageUrl(prompt, options, seed);\n\n            const response = await fetchWithTimeout(\n                url,\n                { headers: this.getHeaders() },\n                this.imageTimeout,\n                options.signal,\n            );\n\n            if (!response.ok) {\n                await this.handleErrorResponse(response);\n            }\n\n            const buffer = await response.arrayBuffer();\n            const contentType =\n                response.headers.get(\"content-type\") || \"image/jpeg\";\n\n            return { buffer, contentType, url: stripKeyFromUrl(url) };\n        }, \"Unknown error during image generation\");\n    }\n\n    // ============================================================================\n    // Image Editing\n    // ============================================================================\n\n    /**\n     * Edit an image using the OpenAI-compatible endpoint (POST /v1/images/edits).\n     * Accepts JSON with image URLs or multipart/form-data file uploads.\n     *\n     * @example\n     * ```ts\n     * const result = await pollinations.imageEdit('Make the sky purple', {\n     *   image: 'https://example.com/photo.jpg',\n     *   model: 'flux',\n     * });\n     * ```\n     */\n    async imageEdit(\n        prompt: string,\n        options: ImageEditOptions = {},\n    ): Promise<ImageResponse> {\n        if (!prompt || typeof prompt !== \"string\") {\n            throw new PollinationsError(\n                \"Prompt is required and must be a string\",\n                \"INVALID_INPUT\",\n                400,\n            );\n        }\n\n        const body: Record<string, unknown> = {\n            prompt,\n            model: options.model || \"flux\",\n        };\n\n        if (options.image) {\n            body.image = options.image;\n        }\n\n        const response = await fetchWithTimeout(\n            `${this.baseUrl}/v1/images/edits`,\n            {\n                method: \"POST\",\n                headers: this.getHeaders(\"application/json\"),\n                body: JSON.stringify(body),\n            },\n            this.imageTimeout,\n            options.signal,\n        );\n\n        if (!response.ok) {\n            await this.handleErrorResponse(response);\n        }\n\n        const json = (await response.json()) as {\n            data: Array<{ url?: string; b64_json?: string }>;\n        };\n\n        const item = json.data?.[0];\n        if (!item) {\n            throw new PollinationsError(\n                \"No image data in response\",\n                \"NO_IMAGE\",\n                500,\n            );\n        }\n\n        return this.resolveImageItem(\n            item,\n            options.signal,\n            \"Unexpected response format from image edit\",\n        );\n    }\n\n    // ============================================================================\n    // Image Generation (OpenAI-compatible POST /v1/images/generations)\n    // ============================================================================\n\n    /**\n     * Generate image(s) via the OpenAI-compatible POST endpoint.\n     * Supports multi-image requests (`n > 1`) and both `url` / `b64_json`\n     * response formats.\n     *\n     * Returns a single `ImageResponse` when `n === 1`, or an array otherwise.\n     *\n     * @example\n     * ```ts\n     * // Single image, size string (OpenAI style)\n     * const img = await pollinations.imageGenerate('A cute robot', {\n     *   size: '1024x1024',\n     *   model: 'flux',\n     * });\n     *\n     * // Multiple images\n     * const imgs = await pollinations.imageGenerate('A cute robot', { n: 3 });\n     * ```\n     */\n    async imageGenerate(\n        prompt: string,\n        options: ImageGenerateV1Options = {},\n    ): Promise<ImageResponse | ImageResponse[]> {\n        if (!prompt || typeof prompt !== \"string\") {\n            throw new PollinationsError(\n                \"Prompt is required and must be a string\",\n                \"INVALID_INPUT\",\n                400,\n            );\n        }\n\n        // Resolve size: prefer explicit `size`, otherwise compose from width/height\n        let size = options.size;\n        if (!size && options.width && options.height) {\n            size = `${options.width}x${options.height}`;\n        }\n\n        const body: Record<string, unknown> = {\n            prompt,\n            model: options.model || \"zimage\",\n        };\n        if (size) body.size = size;\n        if (options.n !== undefined) body.n = options.n;\n        if (options.responseFormat)\n            body.response_format = options.responseFormat;\n        if (options.reasoning !== undefined) body.reasoning = options.reasoning;\n        if (options.seed !== undefined) body.seed = resolveSeed(options.seed);\n        if (options.quality) body.quality = options.quality;\n        if (options.negativePrompt)\n            body.negative_prompt = options.negativePrompt;\n\n        const response = await fetchWithTimeout(\n            `${this.baseUrl}/v1/images/generations`,\n            {\n                method: \"POST\",\n                headers: this.getHeaders(\"application/json\"),\n                body: JSON.stringify(body),\n            },\n            this.imageTimeout,\n            options.signal,\n        );\n\n        if (!response.ok) {\n            await this.handleErrorResponse(response);\n        }\n\n        const json = (await response.json()) as {\n            data: Array<{ url?: string; b64_json?: string }>;\n        };\n\n        const items = json.data || [];\n        if (items.length === 0) {\n            throw new PollinationsError(\n                \"No image data in response\",\n                \"NO_IMAGE\",\n                500,\n            );\n        }\n\n        const results = await Promise.all(\n            items.map((item) => this.resolveImageItem(item, options.signal)),\n        );\n\n        // Unwrap when a single image was produced (most common case)\n        if (results.length === 1) {\n            const [single] = results;\n            if (single) return single;\n        }\n        return results;\n    }\n\n    /** Fetch-or-decode a single OpenAI-style image item into an ImageResponse */\n    private async resolveImageItem(\n        item: { url?: string; b64_json?: string },\n        signal?: AbortSignal,\n        invalidResponseMessage = \"Unexpected image item shape in response\",\n    ): Promise<ImageResponse> {\n        if (item.url) {\n            const imgResponse = await fetchWithTimeout(\n                item.url,\n                {},\n                this.imageTimeout,\n                signal,\n            );\n            const buffer = await imgResponse.arrayBuffer();\n            const contentType =\n                imgResponse.headers.get(\"content-type\") || \"image/png\";\n            return { buffer, contentType, url: item.url };\n        }\n        if (item.b64_json) {\n            const binary = atob(item.b64_json);\n            const bytes = new Uint8Array(binary.length);\n            for (let i = 0; i < binary.length; i++) {\n                bytes[i] = binary.charCodeAt(i);\n            }\n            return {\n                buffer: bytes.buffer as ArrayBuffer,\n                contentType: \"image/png\",\n                url: \"\",\n            };\n        }\n        throw new PollinationsError(\n            invalidResponseMessage,\n            \"INVALID_RESPONSE\",\n            500,\n        );\n    }\n\n    // ============================================================================\n    // Video Generation\n    // ============================================================================\n\n    private validateVideoDuration(_model: string, duration?: number): void {\n        if (duration === undefined) return;\n\n        if (duration < 1 || duration > 30) {\n            throw new PollinationsError(\n                `Invalid duration: ${duration}. Must be between 1-30 seconds.`,\n                \"INVALID_DURATION\",\n                400,\n            );\n        }\n    }\n\n    /** Build video URL with all params (internal use) */\n    private buildVideoUrl(\n        prompt: string,\n        options: VideoGenerateOptions = {},\n        seed?: number,\n    ): string {\n        const model = options.model || \"veo\";\n        this.validateVideoDuration(model, options.duration);\n\n        const params: Record<string, unknown> = {\n            model,\n            duration: options.duration,\n            aspectRatio: options.aspectRatio,\n            seed: seed !== undefined ? seed : resolveSeed(options.seed),\n            audio: options.audio,\n            image: options.referenceImage,\n            private: options.private,\n            nologo: options.nologo,\n            safe: options.safe,\n        };\n\n        const queryString = this.buildQueryParams(params);\n        const encodedPrompt = encodeURIComponent(prompt);\n\n        return `${this.baseUrl}/video/${encodedPrompt}${queryString ? `?${queryString}` : \"\"}`;\n    }\n\n    /**\n     * Generate a video URL from a text prompt.\n     * Hits the API first to authenticate, then returns a keyless URL that can be shared.\n     *\n     * @example\n     * ```ts\n     * const url = await pollinations.videoUrl('A cat playing piano', { model: 'veo', duration: 4 });\n     * ```\n     */\n    async videoUrl(\n        prompt: string,\n        options: VideoGenerateOptions = {},\n    ): Promise<string> {\n        const response = await this.video(prompt, options);\n        return response.url; // Already has key stripped\n    }\n\n    /**\n     * Generate a video and return it as binary data.\n     * Automatically retries up to 3 times with exponential backoff on retriable failures.\n     * Note: Video generation can take several minutes - timeout is set to 10 minutes.\n     *\n     * @example\n     * ```ts\n     * const { buffer } = await pollinations.video('A dog running in a field', { duration: 6 });\n     * ```\n     */\n    async video(\n        prompt: string,\n        options: VideoGenerateOptions = {},\n    ): Promise<VideoResponse> {\n        if (!prompt || typeof prompt !== \"string\") {\n            throw new PollinationsError(\n                \"Prompt is required and must be a string\",\n                \"INVALID_INPUT\",\n                400,\n            );\n        }\n\n        return this.withRetries(async (attempt) => {\n            const seed =\n                attempt === 0 ? resolveSeed(options.seed) : randomSeed();\n            const url = this.buildVideoUrl(prompt, options, seed);\n\n            const response = await fetchWithTimeout(\n                url,\n                { headers: this.getHeaders() },\n                this.videoTimeout,\n                options.signal,\n            );\n\n            if (!response.ok) {\n                await this.handleErrorResponse(response);\n            }\n\n            const buffer = await response.arrayBuffer();\n            const contentType =\n                response.headers.get(\"content-type\") || \"video/mp4\";\n\n            return { buffer, contentType, url: stripKeyFromUrl(url) };\n        }, \"Unknown error during video generation\");\n    }\n\n    // ============================================================================\n    // Text Generation\n    // ============================================================================\n\n    /**\n     * Generate text from a prompt.\n     * Automatically retries up to 3 times with exponential backoff on retriable failures.\n     *\n     * @example\n     * ```ts\n     * const text = await pollinations.text('Write a haiku about coding');\n     * console.log(text);\n     * ```\n     */\n    async text(\n        prompt: string,\n        options: TextGenerateOptions = {},\n    ): Promise<string> {\n        if (!prompt || typeof prompt !== \"string\") {\n            throw new PollinationsError(\n                \"Prompt is required and must be a string\",\n                \"INVALID_INPUT\",\n                400,\n            );\n        }\n\n        return this.withRetries(async (attempt) => {\n            const seed =\n                attempt === 0 ? resolveSeed(options.seed) : randomSeed();\n\n            const messages: Message[] = [];\n\n            if (options.systemPrompt) {\n                messages.push({\n                    role: \"system\",\n                    content: options.systemPrompt,\n                });\n            }\n            messages.push({ role: \"user\", content: prompt });\n\n            const body: Record<string, unknown> = {\n                messages,\n                model: options.model || \"openai\",\n                temperature: options.temperature,\n                max_tokens: options.maxTokens,\n                frequency_penalty: options.frequencyPenalty,\n                presence_penalty: options.presencePenalty,\n                seed,\n                stream: false,\n                private: options.private,\n            };\n\n            if (options.json) {\n                body.response_format = { type: \"json_object\" };\n            }\n\n            this.stripUndefined(body);\n\n            const response = await fetchWithTimeout(\n                `${this.baseUrl}/v1/chat/completions`,\n                {\n                    method: \"POST\",\n                    headers: this.getHeaders(\"application/json\"),\n                    body: JSON.stringify(body),\n                },\n                this.textTimeout,\n                options.signal,\n            );\n\n            if (!response.ok) {\n                await this.handleErrorResponse(response);\n            }\n\n            const data = (await response.json()) as ChatResponse;\n            return data.choices[0]?.message?.content || \"\";\n        }, \"Unknown error during text generation\");\n    }\n\n    /**\n     * Generate text with streaming response.\n     * Automatically retries on connection failure before streaming starts.\n     *\n     * @example\n     * ```ts\n     * for await (const chunk of pollinations.textStream('Tell me a story')) {\n     *   process.stdout.write(chunk);\n     * }\n     * ```\n     */\n    async *textStream(\n        prompt: string,\n        options: Omit<TextGenerateOptions, \"stream\"> = {},\n    ): AsyncGenerator<string> {\n        if (!prompt || typeof prompt !== \"string\") {\n            throw new PollinationsError(\n                \"Prompt is required and must be a string\",\n                \"INVALID_INPUT\",\n                400,\n            );\n        }\n\n        const messages: Message[] = [];\n\n        if (options.systemPrompt) {\n            messages.push({ role: \"system\", content: options.systemPrompt });\n        }\n        messages.push({ role: \"user\", content: prompt });\n\n        const body: Record<string, unknown> = {\n            messages,\n            model: options.model || \"openai\",\n            temperature: options.temperature,\n            max_tokens: options.maxTokens,\n            frequency_penalty: options.frequencyPenalty,\n            presence_penalty: options.presencePenalty,\n            seed: options.seed,\n            stream: true,\n            private: options.private,\n        };\n\n        if (options.json) {\n            body.response_format = { type: \"json_object\" };\n        }\n\n        this.stripUndefined(body);\n\n        // Retry connection establishment; the body is built once above.\n        const response = await this.withRetries(async () => {\n            const res = await fetchWithTimeout(\n                `${this.baseUrl}/v1/chat/completions`,\n                {\n                    method: \"POST\",\n                    headers: this.getHeaders(\"application/json\"),\n                    body: JSON.stringify(body),\n                },\n                this.textTimeout,\n                options.signal,\n            );\n\n            if (!res.ok) {\n                await this.handleErrorResponse(res);\n            }\n\n            return res;\n        }, \"Unknown error during text stream\");\n\n        const reader = response.body?.getReader();\n        if (!reader) {\n            throw new PollinationsError(\"No response body\", \"NO_BODY\", 500);\n        }\n\n        const decoder = new TextDecoder();\n        let buffer = \"\";\n\n        try {\n            while (true) {\n                const { done, value } = await reader.read();\n                if (done) break;\n\n                buffer += decoder.decode(value, { stream: true });\n                const result = parseSSEBuffer<string>(buffer, (data) => {\n                    const json = JSON.parse(data) as ChatStreamChunk;\n                    return json.choices[0]?.delta?.content || null;\n                });\n\n                buffer = result.remainingBuffer;\n                for (const content of result.chunks) {\n                    yield content;\n                }\n            }\n        } finally {\n            reader.releaseLock();\n        }\n    }\n\n    // ============================================================================\n    // Chat Completions (OpenAI-compatible)\n    // ============================================================================\n\n    /**\n     * Build the shared chat-completions request body (undefined fields stripped).\n     * `seed` is passed in explicitly so callers control resolution:\n     * `chat()` passes a per-attempt resolved seed, `chatStream()` passes the\n     * raw `options.seed` unchanged.\n     */\n    private buildChatBody(\n        messages: Message[],\n        options: Omit<ChatOptions, \"stream\">,\n        { stream, seed }: { stream: boolean; seed: number | undefined },\n    ): Record<string, unknown> {\n        return this.stripUndefined({\n            messages,\n            model: options.model || \"openai\",\n            temperature: options.temperature,\n            top_p: options.topP,\n            max_tokens: options.maxTokens,\n            frequency_penalty: options.frequencyPenalty,\n            presence_penalty: options.presencePenalty,\n            repetition_penalty: options.repetitionPenalty,\n            stop: options.stop,\n            seed,\n            stream,\n            stream_options: options.streamOptions,\n            response_format: options.responseFormat,\n            tools: options.tools,\n            tool_choice: options.toolChoice,\n            parallel_tool_calls: options.parallelToolCalls,\n            thinking: options.thinking,\n            reasoning_effort: options.reasoningEffort,\n            thinking_budget: options.thinkingBudget,\n            modalities: options.modalities,\n            audio: options.audio,\n            user: options.user,\n            logit_bias: options.logitBias,\n            logprobs: options.logprobs,\n            top_logprobs: options.topLogprobs,\n            functions: options.functions,\n            function_call: options.functionCall,\n        });\n    }\n\n    /**\n     * Create a chat completion (OpenAI-compatible).\n     * Automatically retries up to 3 times with exponential backoff on retriable failures.\n     *\n     * @example\n     * ```ts\n     * const response = await pollinations.chat([\n     *   { role: 'user', content: 'What is the capital of France?' }\n     * ]);\n     * console.log(response.choices[0].message.content);\n     * ```\n     */\n    async chat(\n        messages: Message[],\n        options: ChatOptions = {},\n    ): Promise<ChatResponse> {\n        if (!messages || !Array.isArray(messages) || messages.length === 0) {\n            throw new PollinationsError(\n                \"Messages array is required and cannot be empty\",\n                \"INVALID_INPUT\",\n                400,\n            );\n        }\n\n        return this.withRetries(async (attempt) => {\n            const seed =\n                attempt === 0 ? resolveSeed(options.seed) : randomSeed();\n\n            const body = this.buildChatBody(messages, options, {\n                stream: false,\n                seed,\n            });\n\n            const response = await fetchWithTimeout(\n                `${this.baseUrl}/v1/chat/completions`,\n                {\n                    method: \"POST\",\n                    headers: this.getHeaders(\"application/json\"),\n                    body: JSON.stringify(body),\n                },\n                this.textTimeout,\n                options.signal,\n            );\n\n            if (!response.ok) {\n                await this.handleErrorResponse(response);\n            }\n\n            return response.json() as Promise<ChatResponse>;\n        }, \"Unknown error during chat completion\");\n    }\n\n    /**\n     * Create a streaming chat completion.\n     * Automatically retries on connection failure before streaming starts.\n     *\n     * @example\n     * ```ts\n     * for await (const chunk of pollinations.chatStream([\n     *   { role: 'user', content: 'Write a poem' }\n     * ])) {\n     *   const content = chunk.choices[0]?.delta?.content;\n     *   if (content) process.stdout.write(content);\n     * }\n     * ```\n     */\n    async *chatStream(\n        messages: Message[],\n        options: Omit<ChatOptions, \"stream\"> = {},\n    ): AsyncGenerator<ChatStreamChunk> {\n        if (!messages || !Array.isArray(messages) || messages.length === 0) {\n            throw new PollinationsError(\n                \"Messages array is required and cannot be empty\",\n                \"INVALID_INPUT\",\n                400,\n            );\n        }\n\n        // chatStream preserves the raw seed (no per-attempt resolution) and\n        // builds the body once before the connection-retry loop.\n        const body = this.buildChatBody(messages, options, {\n            stream: true,\n            seed: options.seed,\n        });\n\n        // Retry connection establishment; the body is built once above.\n        const response = await this.withRetries(async () => {\n            const res = await fetchWithTimeout(\n                `${this.baseUrl}/v1/chat/completions`,\n                {\n                    method: \"POST\",\n                    headers: this.getHeaders(\"application/json\"),\n                    body: JSON.stringify(body),\n                },\n                this.textTimeout,\n                options.signal,\n            );\n\n            if (!res.ok) {\n                await this.handleErrorResponse(res);\n            }\n\n            return res;\n        }, \"Unknown error during chat stream\");\n\n        const reader = response.body?.getReader();\n        if (!reader) {\n            throw new PollinationsError(\"No response body\", \"NO_BODY\", 500);\n        }\n\n        const decoder = new TextDecoder();\n        let buffer = \"\";\n\n        try {\n            while (true) {\n                const { done, value } = await reader.read();\n                if (done) break;\n\n                buffer += decoder.decode(value, { stream: true });\n                const result = parseSSEBuffer<ChatStreamChunk>(\n                    buffer,\n                    (data) => JSON.parse(data) as ChatStreamChunk,\n                );\n\n                buffer = result.remainingBuffer;\n                for (const chunk of result.chunks) {\n                    yield chunk;\n                }\n            }\n        } finally {\n            reader.releaseLock();\n        }\n    }\n\n    // ============================================================================\n    // Audio Generation\n    // ============================================================================\n\n    /**\n     * Generate speech audio from text\n     *\n     * @example\n     * ```ts\n     * // Text-to-speech\n     * const { buffer } = await pollinations.audio('Hello, how are you today?', { voice: 'nova' });\n     *\n     * // Music generation\n     * const { buffer } = await pollinations.audio('upbeat jazz', { model: 'elevenmusic', duration: 30 });\n     * ```\n     */\n    async audio(\n        text: string,\n        options: AudioGenerateOptions = {},\n    ): Promise<AudioBinaryResponse> {\n        if (!text || typeof text !== \"string\") {\n            throw new PollinationsError(\n                \"Text is required and must be a string\",\n                \"INVALID_INPUT\",\n                400,\n            );\n        }\n\n        const params: Record<string, unknown> = {\n            voice: options.voice,\n            model: options.model,\n            duration: options.duration,\n            seed:\n                options.seed !== undefined\n                    ? resolveSeed(options.seed)\n                    : undefined,\n        };\n\n        const queryString = this.buildQueryParams(params);\n        const encodedText = encodeURIComponent(text);\n        const url = `${this.baseUrl}/audio/${encodedText}${queryString ? `?${queryString}` : \"\"}`;\n\n        const response = await fetchWithTimeout(\n            url,\n            { headers: this.getHeaders() },\n            this.textTimeout,\n            options.signal,\n        );\n\n        if (!response.ok) {\n            await this.handleErrorResponse(response);\n        }\n\n        const buffer = await response.arrayBuffer();\n        const contentType =\n            response.headers.get(\"content-type\") || \"audio/mpeg\";\n\n        return { buffer, contentType };\n    }\n\n    /**\n     * Generate speech using the OpenAI-compatible TTS endpoint (POST /v1/audio/speech).\n     *\n     * @example\n     * ```ts\n     * const { buffer } = await pollinations.audioSpeech('Hello world', { voice: 'nova' });\n     * ```\n     */\n    async audioSpeech(\n        text: string,\n        options: AudioGenerateOptions = {},\n    ): Promise<AudioBinaryResponse> {\n        if (!text || typeof text !== \"string\") {\n            throw new PollinationsError(\n                \"Text is required and must be a string\",\n                \"INVALID_INPUT\",\n                400,\n            );\n        }\n\n        const body = {\n            input: text,\n            voice: options.voice || \"alloy\",\n            model: options.model || \"elevenlabs\",\n        };\n\n        const response = await fetchWithTimeout(\n            `${this.baseUrl}/v1/audio/speech`,\n            {\n                method: \"POST\",\n                headers: this.getHeaders(\"application/json\"),\n                body: JSON.stringify(body),\n            },\n            this.textTimeout,\n            options.signal,\n        );\n\n        if (!response.ok) {\n            await this.handleErrorResponse(response);\n        }\n\n        const buffer = await response.arrayBuffer();\n        const contentType =\n            response.headers.get(\"content-type\") || \"audio/mpeg\";\n\n        return { buffer, contentType };\n    }\n\n    // ============================================================================\n    // Model Discovery\n    // ============================================================================\n\n    /**\n     * Get available text models\n     *\n     * @example\n     * ```ts\n     * const models = await pollinations.textModels();\n     * console.log(models.map(m => m.name));\n     * ```\n     */\n    async textModels(): Promise<ModelInfo[]> {\n        const response = await fetchWithTimeout(\n            `${this.baseUrl}/text/models`,\n            { headers: this.getHeaders() },\n            this.textTimeout,\n        );\n\n        if (!response.ok) {\n            await this.handleErrorResponse(response);\n        }\n\n        return response.json() as Promise<ModelInfo[]>;\n    }\n\n    /**\n     * Get available image models\n     *\n     * @example\n     * ```ts\n     * const models = await pollinations.imageModels();\n     * console.log(models.map(m => m.name));\n     * ```\n     */\n    async imageModels(): Promise<ModelInfo[]> {\n        const response = await fetchWithTimeout(\n            `${this.baseUrl}/image/models`,\n            { headers: this.getHeaders() },\n            this.textTimeout,\n        );\n\n        if (!response.ok) {\n            await this.handleErrorResponse(response);\n        }\n\n        return response.json() as Promise<ModelInfo[]>;\n    }\n\n    /**\n     * Get available models (OpenAI-compatible endpoint)\n     *\n     * @example\n     * ```ts\n     * const models = await pollinations.models();\n     * ```\n     */\n    async models(): Promise<ModelInfo[]> {\n        const response = await fetchWithTimeout(\n            `${this.baseUrl}/v1/models`,\n            { headers: this.getHeaders() },\n            this.textTimeout,\n        );\n\n        if (!response.ok) {\n            await this.handleErrorResponse(response);\n        }\n\n        return response.json() as Promise<ModelInfo[]>;\n    }\n\n    // ============================================================================\n    // Speech-to-Text (Transcription)\n    // ============================================================================\n\n    /**\n     * Transcribe audio to text\n     *\n     * @example\n     * ```ts\n     * // From a file (Node.js)\n     * import fs from 'fs';\n     * const audioBuffer = fs.readFileSync('speech.mp3');\n     * const result = await pollinations.transcribe(audioBuffer, { model: 'whisper-large-v3' });\n     * console.log(result.text);\n     *\n     * // From a Blob (browser)\n     * const result = await pollinations.transcribe(audioBlob);\n     * ```\n     */\n    async transcribe(\n        audio: ArrayBuffer | Blob,\n        options: TranscribeOptions & { responseFormat: \"verbose_json\" },\n    ): Promise<TranscriptionVerboseResponse>;\n    async transcribe(\n        audio: ArrayBuffer | Blob,\n        options?: TranscribeOptions,\n    ): Promise<TranscriptionResponse>;\n    async transcribe(\n        audio: ArrayBuffer | Blob,\n        options: TranscribeOptions = {},\n    ): Promise<TranscriptionResponse | TranscriptionVerboseResponse> {\n        const formData = new FormData();\n\n        // Convert ArrayBuffer to Blob if needed\n        const blob =\n            audio instanceof Blob\n                ? audio\n                : new Blob([audio], { type: \"audio/mpeg\" });\n\n        formData.append(\"file\", blob, \"audio.mp3\");\n        formData.append(\"model\", options.model || \"whisper-large-v3\");\n\n        if (options.language) formData.append(\"language\", options.language);\n        if (options.responseFormat)\n            formData.append(\"response_format\", options.responseFormat);\n        if (options.prompt) formData.append(\"prompt\", options.prompt);\n        if (options.temperature !== undefined)\n            formData.append(\"temperature\", String(options.temperature));\n\n        return this.withRetries<\n            TranscriptionResponse | TranscriptionVerboseResponse\n        >(async () => {\n            const headers = this.getHeaders();\n            // Don't set Content-Type - fetch sets it with boundary for FormData\n\n            const response = await fetchWithTimeout(\n                `${this.baseUrl}/v1/audio/transcriptions`,\n                {\n                    method: \"POST\",\n                    headers,\n                    body: formData,\n                },\n                this.textTimeout,\n                options.signal,\n            );\n\n            if (!response.ok) {\n                await this.handleErrorResponse(response);\n            }\n\n            if (\n                options.responseFormat === \"text\" ||\n                options.responseFormat === \"srt\" ||\n                options.responseFormat === \"vtt\"\n            ) {\n                const text = await response.text();\n                return { text };\n            }\n\n            return response.json() as Promise<\n                TranscriptionResponse | TranscriptionVerboseResponse\n            >;\n        }, \"Unknown error during transcription\");\n    }\n\n    // ============================================================================\n    // Media Upload\n    // ============================================================================\n\n    /**\n     * Upload media (image, audio, video) and get a public URL\n     *\n     * @example\n     * ```ts\n     * // Upload from ArrayBuffer\n     * const result = await pollinations.upload(imageBuffer, { contentType: 'image/jpeg' });\n     * console.log(result.url); // https://media.pollinations.ai/abc123...\n     *\n     * // Upload from Blob (browser)\n     * const result = await pollinations.upload(file);\n     * ```\n     */\n    async upload(\n        data: ArrayBuffer | Blob,\n        options: UploadOptions = {},\n    ): Promise<UploadResponse> {\n        const formData = new FormData();\n\n        const blob =\n            data instanceof Blob\n                ? data\n                : new Blob([data], {\n                      type: options.contentType || \"application/octet-stream\",\n                  });\n\n        formData.append(\"file\", blob, options.name || \"upload\");\n\n        const headers = this.getHeaders();\n\n        return this.withRetries(async () => {\n            const response = await fetchWithTimeout(\n                `https://media.pollinations.ai/upload`,\n                {\n                    method: \"POST\",\n                    headers,\n                    body: formData,\n                },\n                this.imageTimeout,\n                options.signal,\n            );\n\n            if (!response.ok) {\n                await this.handleErrorResponse(response);\n            }\n\n            return response.json() as Promise<UploadResponse>;\n        }, \"Unknown error during upload\");\n    }\n\n    // ============================================================================\n    // BYOP (Bring Your Own Pollen)\n    // ============================================================================\n\n    /**\n     * Build a BYOP authorization URL.\n     * Redirect users here to grant your app access to their Pollen balance.\n     *\n     * @example\n     * ```ts\n     * const url = pollinations.authorizeUrl({\n     *   redirectUrl: 'https://myapp.com/callback',\n     *   models: ['flux', 'openai'],\n     *   budget: 10,\n     *   permissions: ['profile', 'usage'],\n     * });\n     * // Redirect user to this URL\n     * ```\n     *\n     * Omit `budget` for the default cap.\n     */\n    static authorizeUrl(options: AuthorizeOptions): string {\n        const params = new URLSearchParams();\n        params.set(\"redirect_uri\", options.redirectUrl);\n\n        if (options.appKey) params.set(\"client_id\", options.appKey);\n        if (options.state) params.set(\"state\", options.state);\n        if (options.models?.length)\n            params.set(\"models\", options.models.join(\",\"));\n        if (options.budget !== undefined)\n            params.set(\"budget\", String(options.budget));\n        if (options.expiry !== undefined)\n            params.set(\"expiry\", String(options.expiry));\n        if (options.permissions?.length)\n            params.set(\"scope\", options.permissions.join(\" \"));\n\n        return `${options.authBaseUrl ?? AUTH_BASE_URL}/authorize?${params.toString()}`;\n    }\n\n    authorizeUrl(options: AuthorizeOptions): string {\n        return Pollinations.authorizeUrl(options);\n    }\n\n    // ============================================================================\n    // Device Flow (OAuth) — headless / CLI authentication\n    // ============================================================================\n\n    /**\n     * Start an OAuth device-code flow for headless or CLI authentication.\n     *\n     * Returns a handle immediately containing a short `userCode` and a\n     * `verificationUri` the user opens in their browser. Call `poll()` to\n     * block until the user approves (or rejects / the code expires) — it\n     * resolves to the access token.\n     *\n     * Static: does NOT require an existing SDK instance or API key. Use\n     * the returned access token to construct a `Pollinations` client.\n     *\n     * @example\n     * ```ts\n     * const auth = await Pollinations.authorizeDevice();\n     * console.log(`Visit ${auth.verificationUri} and enter: ${auth.userCode}`);\n     * const accessToken = await auth.poll();\n     * const client = new Pollinations({ apiKey: accessToken });\n     * ```\n     */\n    static async authorizeDevice(\n        options: AuthorizeDeviceOptions = {},\n    ): Promise<DeviceAuthorization> {\n        const clientId = options.clientId || DEVICE_FLOW_CLIENT_ID;\n        const scope = options.scope || DEVICE_FLOW_DEFAULT_SCOPE;\n\n        const response = await fetch(`${AUTH_BASE_URL}/api/device/code`, {\n            method: \"POST\",\n            headers: { \"Content-Type\": \"application/json\" },\n            body: JSON.stringify({ client_id: clientId, scope }),\n            signal: options.signal,\n        });\n\n        if (!response.ok) {\n            const text = await response.text().catch(() => \"\");\n            throw new PollinationsError(\n                `Failed to start device flow: ${response.status} ${text}`,\n                \"DEVICE_FLOW_START_FAILED\",\n                response.status,\n            );\n        }\n\n        const code = (await response.json()) as DeviceCodeResponse;\n        const expiresAt = new Date(Date.now() + code.expires_in * 1000);\n        const pollMs = Math.max(code.interval, 5) * 1000;\n\n        const poll = async (): Promise<string> => {\n            while (Date.now() < expiresAt.getTime()) {\n                await sleep(pollMs);\n                if (options.signal?.aborted) {\n                    throw new PollinationsError(\n                        \"Device authorization cancelled\",\n                        \"CANCELLED\",\n                        499,\n                    );\n                }\n\n                const tokenRes = await fetch(\n                    `${AUTH_BASE_URL}/api/device/token`,\n                    {\n                        method: \"POST\",\n                        headers: { \"Content-Type\": \"application/json\" },\n                        body: JSON.stringify({\n                            device_code: code.device_code,\n                            grant_type:\n                                \"urn:ietf:params:oauth:grant-type:device_code\",\n                        }),\n                    },\n                );\n\n                const body = (await tokenRes\n                    .json()\n                    .catch(() => ({}))) as DeviceTokenResponse;\n\n                if (tokenRes.ok && body.access_token) {\n                    return body.access_token;\n                }\n                if (\n                    body.error === \"authorization_pending\" ||\n                    body.error === \"slow_down\"\n                ) {\n                    continue;\n                }\n                throw new PollinationsError(\n                    body.error_description ||\n                        body.error ||\n                        \"Device flow failed\",\n                    body.error || \"DEVICE_FLOW_ERROR\",\n                    400,\n                );\n            }\n            throw new PollinationsError(\n                \"Device code expired. Call Pollinations.authorizeDevice() again.\",\n                \"EXPIRED_TOKEN\",\n                400,\n            );\n        };\n\n        return {\n            userCode: code.user_code,\n            verificationUri: code.verification_uri_complete,\n            expiresAt,\n            poll,\n        };\n    }\n\n    /**\n     * Get the authenticated user's identity via GET /api/device/userinfo.\n     * Uses the API key on this client instance.\n     *\n     * @example\n     * ```ts\n     * const user = await pollinations.userInfo();\n     * console.log(user.name, user.tier);\n     * ```\n     */\n    async userInfo(options: RequestOptions = {}): Promise<UserInfo> {\n        const response = await fetchWithTimeout(\n            `${AUTH_BASE_URL}/api/device/userinfo`,\n            { headers: this.getHeaders() },\n            this.textTimeout,\n            options.signal,\n        );\n\n        if (!response.ok) await this.handleErrorResponse(response);\n        return response.json() as Promise<UserInfo>;\n    }\n\n    // ============================================================================\n    // Account\n    // ============================================================================\n\n    /**\n     * Get user profile information\n     *\n     * @example\n     * ```ts\n     * const profile = await pollinations.accountProfile();\n     * console.log(profile.githubUsername);\n     * ```\n     */\n    async accountProfile(): Promise<AccountProfile> {\n        const response = await fetchWithTimeout(\n            `${this.baseUrl}/account/profile`,\n            { headers: this.getHeaders() },\n            this.textTimeout,\n        );\n\n        if (!response.ok) await this.handleErrorResponse(response);\n        return response.json() as Promise<AccountProfile>;\n    }\n\n    /**\n     * Get account pollen balance\n     *\n     * @example\n     * ```ts\n     * const { balance } = await pollinations.accountBalance();\n     * console.log(`Balance: ${balance} pollen`);\n     * ```\n     */\n    async accountBalance(): Promise<AccountBalance> {\n        const response = await fetchWithTimeout(\n            `${this.baseUrl}/account/balance`,\n            { headers: this.getHeaders() },\n            this.textTimeout,\n        );\n\n        if (!response.ok) await this.handleErrorResponse(response);\n        return response.json() as Promise<AccountBalance>;\n    }\n\n    /**\n     * Get usage history\n     *\n     * @example\n     * ```ts\n     * const { usage } = await pollinations.accountUsage({ limit: 50 });\n     * usage.forEach(r => console.log(r.model, r.cost_usd));\n     * ```\n     */\n    async accountUsage(options: UsageOptions = {}): Promise<UsageResponse> {\n        const params = new URLSearchParams();\n        if (options.format) params.set(\"format\", options.format);\n        if (options.days) params.set(\"days\", String(options.days));\n        if (options.limit) params.set(\"limit\", String(options.limit));\n        if (options.before) params.set(\"before\", options.before);\n        if (options.granularity) params.set(\"granularity\", options.granularity);\n        if (options.period) params.set(\"period\", options.period);\n\n        const qs = params.toString();\n        const url = `${this.baseUrl}/account/usage${qs ? `?${qs}` : \"\"}`;\n\n        const response = await fetchWithTimeout(\n            url,\n            { headers: this.getHeaders() },\n            this.textTimeout,\n        );\n\n        if (!response.ok) await this.handleErrorResponse(response);\n        return response.json() as Promise<UsageResponse>;\n    }\n\n    /**\n     * Get daily aggregated usage\n     *\n     * @example\n     * ```ts\n     * const { usage } = await pollinations.accountUsageDaily();\n     * usage.forEach(r => console.log(r.date, r.requests, r.cost_usd));\n     * ```\n     */\n    async accountUsageDaily(\n        options: DailyUsageOptions = {},\n    ): Promise<DailyUsageResponse> {\n        const params = new URLSearchParams();\n        if (options.format) params.set(\"format\", options.format);\n        if (options.days) params.set(\"days\", String(options.days));\n        if (options.granularity) params.set(\"granularity\", options.granularity);\n        if (options.period) params.set(\"period\", options.period);\n        if (options.api_key_ids && options.api_key_ids.length > 0)\n            params.set(\"api_key_ids\", options.api_key_ids.join(\",\"));\n\n        const qs = params.toString();\n        const url = `${this.baseUrl}/account/usage/daily${qs ? `?${qs}` : \"\"}`;\n\n        const response = await fetchWithTimeout(\n            url,\n            { headers: this.getHeaders() },\n            this.textTimeout,\n        );\n\n        if (!response.ok) await this.handleErrorResponse(response);\n        return response.json() as Promise<DailyUsageResponse>;\n    }\n\n    /**\n     * Validate API key and get key information\n     *\n     * @example\n     * ```ts\n     * const keyInfo = await pollinations.validateKey();\n     * console.log(keyInfo.valid, keyInfo.type, keyInfo.permissions);\n     * ```\n     */\n    async validateKey(): Promise<KeyInfo> {\n        const response = await fetchWithTimeout(\n            `${this.baseUrl}/account/key`,\n            { headers: this.getHeaders() },\n            this.textTimeout,\n        );\n\n        if (!response.ok) await this.handleErrorResponse(response);\n        return response.json() as Promise<KeyInfo>;\n    }\n\n    /**\n     * Get usage history for the API key used by this client.\n     *\n     * @example\n     * ```ts\n     * const { usage } = await pollinations.accountKeyUsage({ limit: 50 });\n     * usage.forEach(r => console.log(r.model, r.cost_usd));\n     * ```\n     */\n    async accountKeyUsage(\n        options: KeyUsageOptions = {},\n    ): Promise<UsageResponse> {\n        const params = new URLSearchParams();\n        if (options.days) params.set(\"days\", String(options.days));\n        if (options.limit) params.set(\"limit\", String(options.limit));\n        if (options.before) params.set(\"before\", options.before);\n        if (options.granularity) params.set(\"granularity\", options.granularity);\n        if (options.period) params.set(\"period\", options.period);\n\n        const qs = params.toString();\n        const url = `${this.baseUrl}/account/key/usage${qs ? `?${qs}` : \"\"}`;\n\n        const response = await fetchWithTimeout(\n            url,\n            { headers: this.getHeaders() },\n            this.textTimeout,\n        );\n\n        if (!response.ok) await this.handleErrorResponse(response);\n        return response.json() as Promise<UsageResponse>;\n    }\n\n    // ============================================================================\n    // Account Keys (CRUD)\n    // ============================================================================\n\n    /**\n     * List all API keys on the authenticated account.\n     *\n     * @example\n     * ```ts\n     * const keys = await pollinations.listKeys();\n     * keys.forEach(k => console.log(k.name, k.prefix, k.enabled));\n     * ```\n     */\n    async listKeys(options: RequestOptions = {}): Promise<AccountKey[]> {\n        const response = await fetchWithTimeout(\n            `${this.baseUrl}/account/keys`,\n            { headers: this.getHeaders() },\n            this.textTimeout,\n            options.signal,\n        );\n\n        if (!response.ok) await this.handleErrorResponse(response);\n        const body = (await response.json()) as { data?: AccountKey[] };\n        return body.data || [];\n    }\n\n    /**\n     * Create a new API key. The returned `key` field is ONLY shown once\n     * at creation — store it immediately.\n     *\n     * @example\n     * ```ts\n     * const created = await pollinations.createKey({\n     *   name: 'my-bot',\n     *   type: 'secret',\n     *   pollenBudget: 1000,\n     *   accountPermissions: ['usage'],\n     * });\n     * console.log('Save this now — it will not be shown again:', created.key);\n     * ```\n     */\n    async createKey(\n        options: CreateKeyOptions & RequestOptions,\n    ): Promise<CreatedKey> {\n        if (!options.name) {\n            throw new PollinationsError(\n                \"name is required when creating a key\",\n                \"INVALID_INPUT\",\n                400,\n            );\n        }\n\n        const body: Record<string, unknown> = {\n            name: options.name,\n            type: options.type || \"secret\",\n        };\n        if (options.expiresIn !== undefined) body.expiresIn = options.expiresIn;\n        if (options.allowedModels) body.allowedModels = options.allowedModels;\n        if (options.pollenBudget !== undefined)\n            body.pollenBudget = options.pollenBudget;\n        if (options.accountPermissions)\n            body.accountPermissions = options.accountPermissions;\n        if (options.redirectUris) body.redirectUris = options.redirectUris;\n        if (options.earningsEnabled !== undefined)\n            body.earningsEnabled = options.earningsEnabled;\n\n        const response = await fetchWithTimeout(\n            `${this.baseUrl}/account/keys`,\n            {\n                method: \"POST\",\n                headers: this.getHeaders(\"application/json\"),\n                body: JSON.stringify(body),\n            },\n            this.textTimeout,\n            options.signal,\n        );\n\n        if (!response.ok) await this.handleErrorResponse(response);\n        return response.json() as Promise<CreatedKey>;\n    }\n\n    /**\n     * Revoke an API key by ID. The id comes from `listKeys()`.\n     *\n     * @example\n     * ```ts\n     * await pollinations.revokeKey('key_abc123');\n     * ```\n     */\n    async revokeKey(id: string, options: RequestOptions = {}): Promise<void> {\n        if (!id || typeof id !== \"string\") {\n            throw new PollinationsError(\n                \"Key id is required\",\n                \"INVALID_INPUT\",\n                400,\n            );\n        }\n\n        const response = await fetchWithTimeout(\n            `${this.baseUrl}/account/keys/${encodeURIComponent(id)}`,\n            {\n                method: \"DELETE\",\n                headers: this.getHeaders(),\n            },\n            this.textTimeout,\n            options.signal,\n        );\n\n        if (!response.ok) await this.handleErrorResponse(response);\n    }\n}\n","import { Pollinations } from \"./client.js\";\nimport type {\n    AudioBinaryResponse,\n    ChatOptions,\n    ChatResponse,\n    ImageResponse,\n    Message,\n    VideoResponse,\n} from \"./types.js\";\n\nexport interface ImageResponseExt extends ImageResponse {\n    /** Save image to file (Node.js only) */\n    saveToFile: (path: string) => Promise<void>;\n    /** Get as base64 string */\n    toBase64: () => string;\n    /** Get as data URL (ready for img src) */\n    toDataURL: () => string;\n}\n\n/** Extended video response with helper methods */\nexport interface VideoResponseExt extends VideoResponse {\n    /** Save video to file (Node.js only) */\n    saveToFile: (path: string) => Promise<void>;\n    /** Get as base64 string */\n    toBase64: () => string;\n    /** Get as data URL */\n    toDataURL: () => string;\n}\n\n/** Extended audio response with helper methods */\nexport interface AudioResponseExt extends AudioBinaryResponse {\n    /** Save audio to file (Node.js only) */\n    saveToFile: (path: string) => Promise<void>;\n    /** Get as base64 string */\n    toBase64: () => string;\n    /** Get as data URL (ready for audio src) */\n    toDataURL: () => string;\n}\n\n/** Extended chat response with extra metadata */\nexport interface ChatResponseExt extends ChatResponse {\n    /** The actual text content (shortcut) */\n    text: string;\n    /** Token usage stats */\n    tokens: {\n        input: number;\n        output: number;\n        total: number;\n        cached?: number;\n        reasoning?: number;\n    };\n    /** The actual model that was used */\n    actualModel: string;\n    /** Request ID for tracking */\n    requestId: string;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/** Convert ArrayBuffer to base64 */\nfunction arrayBufferToBase64(buffer: ArrayBuffer): string {\n    try {\n        const g = globalThis as Record<string, unknown>;\n        if (typeof g.Buffer === \"function\") {\n            const NodeBuffer = g.Buffer as typeof Buffer;\n            return NodeBuffer.from(buffer).toString(\"base64\");\n        }\n    } catch {\n        // Fall through to browser implementation\n    }\n    // Browser\n    const bytes = new Uint8Array(buffer);\n    let binary = \"\";\n    for (let i = 0; i < bytes.byteLength; i++) {\n        binary += String.fromCharCode(bytes[i]);\n    }\n    return btoa(binary);\n}\n\n/** Check if running in Node.js environment */\nfunction isNodeEnvironment(): boolean {\n    try {\n        const g = globalThis as Record<string, unknown>;\n        if (g.process && typeof g.process === \"object\") {\n            const proc = g.process as { versions?: { node?: string } };\n            return typeof proc.versions?.node === \"string\";\n        }\n    } catch {\n        return false;\n    }\n    return false;\n}\n\n/** Save buffer to file (Node.js only) */\nasync function saveBufferToFile(\n    buffer: ArrayBuffer,\n    path: string,\n): Promise<void> {\n    if (!isNodeEnvironment()) {\n        throw new Error(\n            \"saveToFile() is only available in Node.js. In browsers, use toDataURL() or toBase64() instead.\",\n        );\n    }\n\n    // Dynamic import for Node.js fs - wrapped to avoid bundler issues\n    const fsModule = \"fs\";\n    const fs = await import(/* @vite-ignore */ fsModule).then(\n        (m) => m.promises,\n    );\n    const g = globalThis as Record<string, unknown>;\n    const NodeBuffer = g.Buffer as typeof Buffer;\n    await fs.writeFile(path, NodeBuffer.from(buffer));\n}\n\n/** Wrap image response with helper methods */\nexport function wrapImageResponse(response: ImageResponse): ImageResponseExt {\n    return {\n        ...response,\n        saveToFile: (path: string) => saveBufferToFile(response.buffer, path),\n        toBase64: () => arrayBufferToBase64(response.buffer),\n        toDataURL: () =>\n            `data:${response.contentType};base64,${arrayBufferToBase64(response.buffer)}`,\n    };\n}\n\n/** Wrap video response with helper methods */\nexport function wrapVideoResponse(response: VideoResponse): VideoResponseExt {\n    return {\n        ...response,\n        saveToFile: (path: string) => saveBufferToFile(response.buffer, path),\n        toBase64: () => arrayBufferToBase64(response.buffer),\n        toDataURL: () =>\n            `data:${response.contentType};base64,${arrayBufferToBase64(response.buffer)}`,\n    };\n}\n\n/** Wrap audio response with helper methods */\nexport function wrapAudioResponse(\n    response: AudioBinaryResponse,\n): AudioResponseExt {\n    return {\n        ...response,\n        saveToFile: (path: string) => saveBufferToFile(response.buffer, path),\n        toBase64: () => arrayBufferToBase64(response.buffer),\n        toDataURL: () =>\n            `data:${response.contentType};base64,${arrayBufferToBase64(response.buffer)}`,\n    };\n}\n\n/** Wrap chat response with extra metadata */\nexport function wrapChatResponse(response: ChatResponse): ChatResponseExt {\n    const usage = response.usage;\n    return {\n        ...response,\n        text: response.choices[0]?.message?.content || \"\",\n        tokens: {\n            input: usage?.prompt_tokens || 0,\n            output: usage?.completion_tokens || 0,\n            total: usage?.total_tokens || 0,\n            cached: usage?.prompt_tokens_details?.cached_tokens,\n            reasoning: usage?.completion_tokens_details?.reasoning_tokens,\n        },\n        actualModel: response.model,\n        requestId: response.id,\n    };\n}\n\n// ============================================================================\n// Conversation Helper - SIMPLIFIED & IMPROVED\n// ============================================================================\n\n/** Conversation state manager */\nexport class Conversation {\n    private messages: Message[] = [];\n    private client: Pollinations;\n    private options: ChatOptions;\n\n    constructor(options: ChatOptions = {}, client?: Pollinations) {\n        this.client = client || new Pollinations();\n        this.options = { ...options }; // Deep copy options\n    }\n\n    /** Add a system message */\n    system(content: string): this {\n        this.messages.push({ role: \"system\", content });\n        return this;\n    }\n\n    /** Add a user message without sending */\n    user(content: string): this {\n        this.messages.push({ role: \"user\", content });\n        return this;\n    }\n\n    /** Add an assistant message manually */\n    assistant(content: string): this {\n        this.messages.push({ role: \"assistant\", content });\n        return this;\n    }\n\n    /** Add a tool result message */\n    tool(toolCallId: string, content: string): this {\n        this.messages.push({ role: \"tool\", content, tool_call_id: toolCallId });\n        return this;\n    }\n\n    /** Add any message directly */\n    addMessage(message: Message): this {\n        this.messages.push(message);\n        return this;\n    }\n\n    /**\n     * Send a message (user or tool messages) and get an assistant response\n     * Automatically adds user message to history if content is provided\n     *\n     * @example\n     * ```ts\n     * const conv = new Conversation();\n     * const response = await conv.say('Hello');\n     * const followup = await conv.say('Explain that more');\n     * ```\n     */\n    async say(content: string): Promise<ChatResponseExt> {\n        this.messages.push({ role: \"user\", content });\n        return this._sendAndAddResponse();\n    }\n\n    /**\n     * Send current messages without adding a new user message\n     * Useful after calling tool() or addMessage() with pre-composed messages\n     *\n     * @example\n     * ```ts\n     * const conv = new Conversation();\n     * conv.user('Calculate 2+2');\n     * const response = await conv.send();\n     * ```\n     */\n    async send(): Promise<ChatResponseExt> {\n        return this._sendAndAddResponse();\n    }\n\n    /** Internal: send and add response to history */\n    private async _sendAndAddResponse(): Promise<ChatResponseExt> {\n        const response = await this.client.chat(this.messages, this.options);\n        const wrapped = wrapChatResponse(response);\n\n        // Add full assistant message to history (including tool_calls if present)\n        const assistantMessage: Message & { tool_calls?: unknown } = {\n            role: \"assistant\",\n            content: wrapped.text,\n        };\n        if (response.choices[0]?.message?.tool_calls) {\n            assistantMessage.tool_calls =\n                response.choices[0].message.tool_calls;\n        }\n        this.messages.push(assistantMessage as Message);\n\n        return wrapped;\n    }\n\n    /** Get the conversation history */\n    getHistory(): Message[] {\n        return structuredClone(this.messages); // Deep copy for immutability\n    }\n\n    /** Clear the conversation history */\n    clear(): this {\n        this.messages = [];\n        return this;\n    }\n\n    /**\n     * Fork the conversation (create an independent copy).\n     *\n     * Creates a new Conversation with a deep copy of the message history.\n     * Note: The forked conversation shares the same Pollinations client instance,\n     * which is intentional for efficiency. The client is stateless and thread-safe.\n     *\n     * @example\n     * ```ts\n     * const main = new Conversation();\n     * await main.say('Hello');\n     *\n     * // Fork to explore a different path\n     * const branch = main.fork();\n     * await branch.say('What if we went this way?');\n     *\n     * // Original conversation is unaffected\n     * await main.say('Let me continue the main topic');\n     * ```\n     */\n    fork(): Conversation {\n        const forked = new Conversation(this.options, this.client);\n        forked.messages = structuredClone(this.messages); // Deep copy\n        return forked;\n    }\n\n    /** Get message count */\n    get length(): number {\n        return this.messages.length;\n    }\n}\n","/**\n * Simple helper functions for quick usage without instantiating a client.\n * Perfect for beginners and simple use cases!\n *\n * @example\n * ```ts\n * import { generateImage, generateText } from '@pollinations/sdk';\n *\n * // Generate an image and save it\n * const image = await generateImage('A cute cat');\n * await image.saveToFile('cat.png');\n *\n * // Generate multiple images\n * const images = await generateImage('A cute cat', { n: 5 });\n *\n * // Generate text\n * const text = await generateText('Write a haiku');\n * ```\n */\n\nimport { Pollinations } from \"./client.js\";\nimport {\n    type AudioResponseExt,\n    type ChatResponseExt,\n    Conversation,\n    type ImageResponseExt,\n    type VideoResponseExt,\n    wrapAudioResponse,\n    wrapChatResponse,\n    wrapImageResponse,\n    wrapVideoResponse,\n} from \"./extras.js\";\nimport type {\n    AccountBalance,\n    AccountKey,\n    AccountProfile,\n    AudioGenerateOptions,\n    AuthorizeDeviceOptions,\n    AuthorizeOptions,\n    ChatOptions,\n    CreatedKey,\n    CreateKeyOptions,\n    DailyUsageOptions,\n    DailyUsageResponse,\n    DeviceAuthorization,\n    ImageEditOptions,\n    ImageGenerateOptions,\n    ImageGenerateV1Options,\n    KeyInfo,\n    KeyUsageOptions,\n    Message,\n    ModelInfo,\n    TextGenerateOptions,\n    TranscribeOptions,\n    TranscriptionResponse,\n    TranscriptionVerboseResponse,\n    UploadOptions,\n    UploadResponse,\n    UsageOptions,\n    UsageResponse,\n    UserInfo,\n    VideoGenerateOptions,\n} from \"./types.js\";\n\n// Default client instance\nlet defaultClient: Pollinations | null = null;\n\nfunction getClient(apiKey?: string): Pollinations {\n    if (apiKey) {\n        return new Pollinations({ apiKey });\n    }\n    if (!defaultClient) {\n        defaultClient = new Pollinations();\n    }\n    return defaultClient;\n}\n\n/**\n * Reset the default client (useful for testing)\n */\nexport function resetClient(): void {\n    defaultClient = null;\n}\n\n/**\n * Configure the default client with an API key\n *\n * @example\n * ```ts\n * import { configure } from '@pollinations/sdk';\n * configure({ apiKey: 'your-api-key' });\n * ```\n */\nexport function configure(options: {\n    apiKey?: string;\n    baseUrl?: string;\n}): void {\n    defaultClient = new Pollinations(options);\n}\n\n// ============================================================================\n// Options with n parameter\n// ============================================================================\n\ninterface WithN {\n    /** Number of outputs to generate (default: 1). Each gets a random seed. */\n    n?: number;\n}\n\ninterface WithRaw {\n    /** Return full API response instead of just the text (default: false) */\n    raw?: boolean;\n}\n\ntype ImageOptionsWithN = ImageGenerateOptions & WithN;\ntype VideoOptionsWithN = VideoGenerateOptions & WithN;\ntype TextOptionsWithN = TextGenerateOptions & WithN & WithRaw;\ntype AudioOptionsWithN = AudioGenerateOptions & WithN;\n\n// ============================================================================\n// Image Functions\n// ============================================================================\n\n/**\n * Get a URL for an image (generates it first, returns keyless URL)\n *\n * @example\n * ```ts\n * const url = await imageUrl('A sunset over mountains');\n * // <img src={url} /> - no API key exposed!\n * ```\n */\nexport async function imageUrl(\n    prompt: string,\n    options?: ImageGenerateOptions,\n): Promise<string> {\n    return getClient().imageUrl(prompt, options);\n}\n\n/**\n * Generate image(s) from a prompt\n *\n * @example\n * ```ts\n * // Single image\n * const image = await generateImage('A robot');\n * await image.saveToFile('robot.jpg');\n *\n * // Multiple images with n parameter\n * const images = await generateImage('A robot', { n: 5 });\n * images.forEach((img, i) => img.saveToFile(`robot-${i}.jpg`));\n * ```\n */\nexport async function generateImage(\n    prompt: string,\n    options?: ImageOptionsWithN,\n): Promise<ImageResponseExt | ImageResponseExt[]> {\n    const { n = 1, ...imageOptions } = options || {};\n    const client = getClient();\n\n    if (n === 1) {\n        const response = await client.image(prompt, imageOptions);\n        return wrapImageResponse(response);\n    }\n\n    // Multiple: run in parallel with random seeds\n    const results = await Promise.all(\n        Array.from({ length: n }, () =>\n            client.image(prompt, { ...imageOptions, seed: -1 }),\n        ),\n    );\n    return results.map(wrapImageResponse);\n}\n\n// ============================================================================\n// Image Editing Functions\n// ============================================================================\n\n/**\n * Edit an image using a text prompt (OpenAI-compatible endpoint)\n *\n * @example\n * ```ts\n * const result = await editImage('Make the sky purple', {\n *   image: 'https://example.com/photo.jpg',\n * });\n * await result.saveToFile('edited.png');\n * ```\n */\nexport async function editImage(\n    prompt: string,\n    options?: ImageEditOptions,\n): Promise<ImageResponseExt> {\n    const response = await getClient().imageEdit(prompt, options);\n    return wrapImageResponse(response);\n}\n\n/**\n * Generate image(s) via the OpenAI-compatible POST /v1/images/generations endpoint.\n *\n * @example\n * ```ts\n * // Single image, OpenAI-style size string\n * const img = await imageGenerate('A robot', { size: '1024x1024' });\n * await img.saveToFile('robot.png');\n *\n * // Multiple images\n * const imgs = await imageGenerate('A robot', { n: 3 });\n * ```\n */\nexport async function imageGenerate(\n    prompt: string,\n    options?: ImageGenerateV1Options,\n): Promise<ImageResponseExt | ImageResponseExt[]> {\n    const response = await getClient().imageGenerate(prompt, options);\n    return Array.isArray(response)\n        ? response.map(wrapImageResponse)\n        : wrapImageResponse(response);\n}\n\n// ============================================================================\n// Video Functions\n// ============================================================================\n\n/**\n * Get a URL for a video (generates it first, returns keyless URL)\n *\n * @example\n * ```ts\n * const url = await videoUrl('A bird flying', { model: 'veo', duration: 4 });\n * ```\n */\nexport async function videoUrl(\n    prompt: string,\n    options?: VideoGenerateOptions,\n): Promise<string> {\n    return getClient().videoUrl(prompt, options);\n}\n\n/**\n * Generate video(s) from a prompt\n *\n * @example\n * ```ts\n * // Single video\n * const video = await generateVideo('A cat stretching', { duration: 4 });\n * await video.saveToFile('cat.mp4');\n *\n * // Multiple videos\n * const videos = await generateVideo('A cat stretching', { n: 3, duration: 4 });\n * ```\n */\nexport async function generateVideo(\n    prompt: string,\n    options?: VideoOptionsWithN,\n): Promise<VideoResponseExt | VideoResponseExt[]> {\n    const { n = 1, ...videoOptions } = options || {};\n    const client = getClient();\n\n    if (n === 1) {\n        const response = await client.video(prompt, videoOptions);\n        return wrapVideoResponse(response);\n    }\n\n    const results = await Promise.all(\n        Array.from({ length: n }, () =>\n            client.video(prompt, { ...videoOptions, seed: -1 }),\n        ),\n    );\n    return results.map(wrapVideoResponse);\n}\n\n// ============================================================================\n// Text Functions\n// ============================================================================\n\n/**\n * Generate text from a prompt\n *\n * @example\n * ```ts\n * // Single response (just text)\n * const text = await generateText('Write a haiku');\n *\n * // Multiple responses\n * const texts = await generateText('Write a haiku', { n: 3 });\n *\n * // Full API response with raw: true\n * const response = await generateText('Write a haiku', { raw: true });\n * console.log(response.tokens, response.actualModel);\n * ```\n */\nexport async function generateText(\n    prompt: string,\n    options?: TextOptionsWithN,\n): Promise<string | string[] | ChatResponseExt | ChatResponseExt[]> {\n    const { n = 1, raw = false, ...textOptions } = options || {};\n    const client = getClient();\n\n    if (n === 1) {\n        if (raw) {\n            const response = await client.chat(\n                [{ role: \"user\", content: prompt }],\n                { ...textOptions },\n            );\n            return wrapChatResponse(response);\n        }\n        return client.text(prompt, textOptions);\n    }\n\n    // Multiple: run in parallel with random seeds\n    if (raw) {\n        const results = await Promise.all(\n            Array.from({ length: n }, () =>\n                client.chat([{ role: \"user\", content: prompt }], {\n                    ...textOptions,\n                    seed: -1,\n                }),\n            ),\n        );\n        return results.map(wrapChatResponse);\n    }\n\n    const results = await Promise.all(\n        Array.from({ length: n }, () =>\n            client.text(prompt, { ...textOptions, seed: -1 }),\n        ),\n    );\n    return results;\n}\n\n/**\n * Generate text with streaming\n *\n * @example\n * ```ts\n * for await (const chunk of generateTextStream('Tell me a story')) {\n *   process.stdout.write(chunk);\n * }\n * ```\n */\nexport async function* generateTextStream(\n    prompt: string,\n    options?: Omit<TextGenerateOptions, \"stream\">,\n): AsyncGenerator<string> {\n    yield* getClient().textStream(prompt, options);\n}\n\n// ============================================================================\n// Chat Functions\n// ============================================================================\n\n/**\n * Create chat completion(s) with extended response\n *\n * @example\n * ```ts\n * // Single completion\n * const response = await chat([{ role: 'user', content: 'Hello!' }]);\n * console.log(response.text);\n *\n * // Multiple completions\n * const responses = await chat([{ role: 'user', content: 'Hello!' }], { n: 3 });\n * ```\n */\nexport async function chat(\n    messages: Message[],\n    options?: ChatOptions & WithN,\n): Promise<ChatResponseExt | ChatResponseExt[]> {\n    const { n = 1, ...chatOptions } = options || {};\n    const client = getClient();\n\n    if (n === 1) {\n        const response = await client.chat(messages, chatOptions);\n        return wrapChatResponse(response);\n    }\n\n    const results = await Promise.all(\n        Array.from({ length: n }, () =>\n            client.chat(messages, { ...chatOptions, seed: -1 }),\n        ),\n    );\n    return results.map(wrapChatResponse);\n}\n\n/**\n * Create a streaming chat completion\n *\n * @example\n * ```ts\n * for await (const chunk of chatStream([{ role: 'user', content: 'Write a poem' }])) {\n *   const text = chunk.choices[0]?.delta?.content;\n *   if (text) process.stdout.write(text);\n * }\n * ```\n */\nexport async function* chatStream(\n    messages: Message[],\n    options?: Omit<ChatOptions, \"stream\">,\n): AsyncGenerator<import(\"./types.js\").ChatStreamChunk> {\n    yield* getClient().chatStream(messages, options);\n}\n\n/**\n * Create a new conversation with the configured client\n *\n * @example\n * ```ts\n * const convo = conversation({ model: 'openai' });\n * convo.system('You are a helpful assistant');\n * const response = await convo.say('Hello!');\n * ```\n */\nexport function conversation(options?: ChatOptions): Conversation {\n    return new Conversation(options, getClient());\n}\n\n// ============================================================================\n// Audio Functions\n// ============================================================================\n\n/**\n * Generate audio from text (TTS or music). Returns binary audio with helper methods.\n *\n * @example\n * ```ts\n * // Text-to-speech\n * const audio = await generateAudio('Hello world!', { voice: 'nova' });\n * await audio.saveToFile('speech.mp3');\n *\n * // Music generation\n * const music = await generateAudio('upbeat jazz', { model: 'elevenmusic', duration: 30 });\n * await music.saveToFile('jazz.mp3');\n *\n * // Multiple variations\n * const audios = await generateAudio('Hello world!', { n: 3, voice: 'nova' });\n * ```\n */\nexport async function generateAudio(\n    text: string,\n    options?: AudioOptionsWithN,\n): Promise<AudioResponseExt | AudioResponseExt[]> {\n    const { n = 1, ...audioOptions } = options || {};\n    const client = getClient();\n\n    if (n === 1) {\n        const response = await client.audio(text, audioOptions);\n        return wrapAudioResponse(response);\n    }\n\n    const results = await Promise.all(\n        Array.from({ length: n }, () =>\n            client.audio(text, { ...audioOptions, seed: -1 }),\n        ),\n    );\n    return results.map(wrapAudioResponse);\n}\n\n// ============================================================================\n// Model Discovery Functions\n// ============================================================================\n\n/**\n * Get available text models\n */\nexport async function getTextModels(): Promise<ModelInfo[]> {\n    return getClient().textModels();\n}\n\n/**\n * Get available image models\n */\nexport async function getImageModels(): Promise<ModelInfo[]> {\n    return getClient().imageModels();\n}\n\n/**\n * Get all available models\n */\nexport async function getModels(): Promise<ModelInfo[]> {\n    return getClient().models();\n}\n\n// ============================================================================\n// Transcription (STT) Functions\n// ============================================================================\n\n/**\n * Transcribe audio to text\n *\n * @example\n * ```ts\n * import fs from 'fs';\n * const audio = fs.readFileSync('speech.mp3');\n * const { text } = await transcribe(audio);\n * ```\n */\nexport async function transcribe(\n    audio: ArrayBuffer | Blob,\n    options: TranscribeOptions & { responseFormat: \"verbose_json\" },\n): Promise<TranscriptionVerboseResponse>;\nexport async function transcribe(\n    audio: ArrayBuffer | Blob,\n    options?: TranscribeOptions,\n): Promise<TranscriptionResponse>;\nexport async function transcribe(\n    audio: ArrayBuffer | Blob,\n    options?: TranscribeOptions,\n): Promise<TranscriptionResponse | TranscriptionVerboseResponse> {\n    return getClient().transcribe(audio, options as TranscribeOptions);\n}\n\n// ============================================================================\n// Media Upload Functions\n// ============================================================================\n\n/**\n * Upload media and get a public URL\n *\n * @example\n * ```ts\n * const result = await upload(imageBuffer, { contentType: 'image/jpeg' });\n * console.log(result.url);\n * ```\n */\nexport async function upload(\n    data: ArrayBuffer | Blob,\n    options?: UploadOptions,\n): Promise<UploadResponse> {\n    return getClient().upload(data, options);\n}\n\n// ============================================================================\n// BYOP Functions\n// ============================================================================\n\n/**\n * Build a BYOP authorization URL\n *\n * @example\n * ```ts\n * const url = authorizeUrl({\n *   redirectUrl: 'https://myapp.com/callback',\n *   models: ['flux', 'openai'],\n *   budget: 10,\n * });\n * ```\n */\nexport function authorizeUrl(options: AuthorizeOptions): string {\n    return Pollinations.authorizeUrl(options);\n}\n\n/**\n * Start OAuth device flow for headless/CLI authentication. Does NOT\n * require an existing API key — use the returned access token to\n * configure the SDK.\n *\n * @example\n * ```ts\n * const auth = await authorizeDevice();\n * console.log(`Visit ${auth.verificationUri} and enter: ${auth.userCode}`);\n * const accessToken = await auth.poll();\n * configure({ apiKey: accessToken });\n * ```\n */\nexport async function authorizeDevice(\n    options?: AuthorizeDeviceOptions,\n): Promise<DeviceAuthorization> {\n    return Pollinations.authorizeDevice(options);\n}\n\n/**\n * Get the authenticated user's identity. Uses the currently configured\n * API key (from `configure()` or the `POLLINATIONS_API_KEY` env var).\n *\n * @example\n * ```ts\n * const user = await userInfo();\n * console.log(user.name, user.tier);\n * ```\n */\nexport async function userInfo(): Promise<UserInfo> {\n    return getClient().userInfo();\n}\n\n// ============================================================================\n// Account Functions\n// ============================================================================\n\n/**\n * Get user profile\n */\nexport async function getProfile(): Promise<AccountProfile> {\n    return getClient().accountProfile();\n}\n\n/**\n * Get account balance\n */\nexport async function getBalance(): Promise<AccountBalance> {\n    return getClient().accountBalance();\n}\n\n/**\n * Get usage history\n */\nexport async function getUsage(options?: UsageOptions): Promise<UsageResponse> {\n    return getClient().accountUsage(options);\n}\n\n/**\n * Get usage history for the currently configured API key only.\n */\nexport async function getKeyUsage(\n    options?: KeyUsageOptions,\n): Promise<UsageResponse> {\n    return getClient().accountKeyUsage(options);\n}\n\n/**\n * Get daily usage summary\n */\nexport async function getDailyUsage(\n    options?: DailyUsageOptions,\n): Promise<DailyUsageResponse> {\n    return getClient().accountUsageDaily(options);\n}\n\n/**\n * Validate API key and get key info\n */\nexport async function validateKey(): Promise<KeyInfo> {\n    return getClient().validateKey();\n}\n\n/**\n * List all API keys on the authenticated account.\n *\n * @example\n * ```ts\n * const keys = await listKeys();\n * keys.forEach(k => console.log(k.name, k.prefix, k.enabled));\n * ```\n */\nexport async function listKeys(): Promise<AccountKey[]> {\n    return getClient().listKeys();\n}\n\n/**\n * Create a new API key. The returned `key` field is only shown once —\n * store it immediately.\n *\n * @example\n * ```ts\n * const created = await createKey({\n *   name: 'my-bot',\n *   type: 'secret',\n *   accountPermissions: ['usage'],\n * });\n * console.log('Save this key — it will not be shown again:', created.key);\n * ```\n */\nexport async function createKey(\n    options: CreateKeyOptions,\n): Promise<CreatedKey> {\n    return getClient().createKey(options);\n}\n\n/**\n * Revoke an API key by its id (from `listKeys()`).\n *\n * @example\n * ```ts\n * await revokeKey('key_abc123');\n * ```\n */\nexport async function revokeKey(id: string): Promise<void> {\n    return getClient().revokeKey(id);\n}\n"],"mappings":"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","names":["results"]}