declare enum Host { WEB = "https://image.novelai.net", API = "https://api.novelai.net", TEXT = "https://text.novelai.net" } declare enum Model { V3 = "nai-diffusion-3", V3_INP = "nai-diffusion-3-inpainting", V4 = "nai-diffusion-4-full", V4_INP = "nai-diffusion-4-full-inpainting", V4_CUR = "nai-diffusion-4-curated-preview", V4_CUR_INP = "nai-diffusion-4-curated-inpainting", V4_5 = "nai-diffusion-4-5-full", V4_5_INP = "nai-diffusion-4-5-full-inpainting", V4_5_CUR = "nai-diffusion-4-5-curated", V4_5_CUR_INP = "nai-diffusion-4-5-curated-inpainting", FURRY = "nai-diffusion-furry-3", FURRY_INP = "nai-diffusion-furry-3-inpainting" } /** * Text generation models available through the OpenAI-compatible endpoints * on https://text.novelai.net (use client.listTextModels() for the live list) */ declare enum TextModel { GLM_4_6 = "glm-4-6", XIALONG = "xialong-v1" } declare enum Controlnet { PALETTESWAP = "hed", FORMLOCK = "midas", SCRIBBLER = "fake_scribble", BUILDINGCONTROL = "mlsd", LANDSCAPER = "uniformer" } declare enum Action { GENERATE = "generate", INPAINT = "infill", IMG2IMG = "img2img" } declare enum DirectorTools { LINEART = "lineart", SKETCH = "sketch", BACKGROUND_REMOVAL = "bg-removal", EMOTION = "emotion", DECLUTTER = "declutter", COLORIZE = "colorize" } declare enum EmotionOptions { NEUTRAL = "neutral", HAPPY = "happy", SAD = "sad", ANGRY = "angry", SCARED = "scared", SURPRISED = "surprised", TIRED = "tired", EXCITED = "excited", NERVOUS = "nervous", THINKING = "thinking", CONFUSED = "confused", SHY = "shy", DISGUSTED = "disgusted", SMUG = "smug", BORED = "bored", LAUGHING = "laughing", IRRITATED = "irritated", AROUSED = "aroused", EMBARRASSED = "embarrassed", WORRIED = "worried", LOVE = "love", DETERMINED = "determined", HURT = "hurt", PLAYFUL = "playful" } declare enum EmotionLevel { NORMAL = 0, SLIGHTLY_WEAK = 1, WEAK = 2, EVEN_WEAKER = 3, VERY_WEAK = 4, WEAKEST = 5 } declare enum Resolution { SMALL_PORTRAIT = "small_portrait", SMALL_LANDSCAPE = "small_landscape", SMALL_SQUARE = "small_square", NORMAL_PORTRAIT = "normal_portrait", NORMAL_LANDSCAPE = "normal_landscape", NORMAL_SQUARE = "normal_square", LARGE_PORTRAIT = "large_portrait", LARGE_LANDSCAPE = "large_landscape", LARGE_SQUARE = "large_square", WALLPAPER_PORTRAIT = "wallpaper_portrait", WALLPAPER_LANDSCAPE = "wallpaper_landscape" } declare const RESOLUTION_DIMENSIONS: Record; declare enum Sampler { EULER = "k_euler", EULER_ANC = "k_euler_ancestral", DPM2S_ANC = "k_dpmpp_2s_ancestral", DPM2M = "k_dpmpp_2m", DPMSDE = "k_dpmpp_sde", DPM2MSDE = "k_dpmpp_2m_sde", DDIM = "ddim_v3" } declare enum Noise { NATIVE = "native", KARRAS = "karras", EXPONENTIAL = "exponential", POLYEXPONENTIAL = "polyexponential" } /** * Configuration for API request retries */ interface RetryConfig { /** * Whether to enable retry for failed requests * @default true */ enabled?: boolean; /** * Maximum number of retry attempts * @default 3 */ maxRetries?: number; /** * Base delay between retries in milliseconds * Will be used with exponential backoff * @default 1000 (1 second) */ baseDelay?: number; /** * Maximum delay between retries in milliseconds * @default 30000 (30 seconds) */ maxDelay?: number; /** * HTTP status codes that should trigger a retry * @default [429, 500, 502, 503, 504] */ retryStatusCodes?: number[]; } interface PositionCoords { x: number; y: number; } /** * Flexible image input types * This allows images to be passed in various formats for cross-platform compatibility */ type ImageInput = string | Blob | File | ArrayBuffer | Uint8Array | { data: Uint8Array; } | { url: string; } | HTMLImageElement | HTMLCanvasElement; /** * Result from parsing an image */ interface ParsedImage { width: number; height: number; base64: string; } /** * Character caption for V4 prompts */ interface CharacterCaption { char_caption: string; centers: PositionCoords[]; } /** * Character prompt for V4/V4.5 multi-character generation */ interface CharacterPrompt { prompt: string; uc?: string; center?: PositionCoords; enabled?: boolean; } /** * V4 caption format for prompts */ interface V4CaptionFormat { base_caption: string; char_captions: CharacterCaption[]; } /** * V4 prompt format with multi-character support */ interface V4PromptFormat { caption: V4CaptionFormat; use_coords: boolean; use_order: boolean; } /** * V4 format for negative prompts */ interface V4NegativePromptFormat { caption: V4CaptionFormat; legacy_uc: boolean; } /** * Condition input used by director reference (character reference) parameters */ interface V4ConditionInput { caption: V4CaptionFormat; legacy_uc?: boolean; use_coords?: boolean; use_order?: boolean; } /** * img2img sub-object sent alongside V4.5 inpainting when the * inpaint img2img strength is below 1 */ interface V4Img2Img { strength: number; color_correct: boolean; } interface Metadata { prompt?: string; model?: Model; action?: Action; resPreset?: Resolution; negative_prompt?: string; qualityToggle?: boolean; ucPreset?: 0 | 1 | 2 | 3; width?: number; height?: number; n_samples?: number; steps?: number; scale?: number; dynamic_thresholding?: boolean; seed?: number; extra_noise_seed?: number; sampler?: Sampler; sm?: boolean; sm_dyn?: boolean; cfg_rescale?: number; noise_schedule?: Noise; /** Source image. Accepts any ImageInput (path, Blob, URL, raw base64, ...) */ image?: ImageInput; strength?: number; img2img?: V4Img2Img; noise?: number; controlnet_strength?: number; controlnet_condition?: string; controlnet_model?: Controlnet; add_original_image?: boolean; /** Inpainting mask (white = repaint). Accepts any ImageInput */ mask?: ImageInput; /** Reference images for vibe transfer. Accept any ImageInput; V4 models encode them into vibe tokens automatically */ reference_image_multiple?: ImageInput[]; reference_information_extracted_multiple?: number[]; reference_strength_multiple?: number[]; /** Reference images. For character reference: 1024x1536, 1536x1024 or 1472x1472 with black padding */ director_reference_images?: ImageInput[]; /** For character reference: set caption.base_caption to "character" or "character&style" */ director_reference_descriptions?: V4ConditionInput[]; /** 0-1 per reference image */ director_reference_information_extracted?: number[]; /** 0-1 per reference image */ director_reference_strength_values?: number[]; /** Fidelity slider (0-1) per reference image */ director_reference_secondary_strength_values?: number[]; params_version?: 1 | 2 | 3; autoSmea?: boolean; characterPrompts?: CharacterPrompt[]; v4_prompt?: V4PromptFormat; v4_negative_prompt?: V4NegativePromptFormat; skip_cfg_above_sigma?: number | null; use_coords?: boolean; legacy_uc?: boolean; normalize_reference_strength_multiple?: boolean; deliberate_euler_ancestral_bug?: boolean; prefer_brownian?: boolean; /** Sent to the API as inpaint_img2img_strength (default 1) */ inpaintImg2ImgStrength?: number; color_correct?: boolean; image_format?: string; legacy?: boolean; legacy_v3_extend?: boolean; stream?: string | null; } interface ImageOptions { filename: string; data: Uint8Array; } interface DirectorRequestBase { req_type: string; width: number; height: number; image: string; } interface LineArtRequest extends DirectorRequestBase { req_type: "lineart"; } interface SketchRequest extends DirectorRequestBase { req_type: "sketch"; } interface BackgroundRemovalRequest extends DirectorRequestBase { req_type: "bg-removal"; } interface DeclutterRequest extends DirectorRequestBase { req_type: "declutter"; } interface ColorizeRequest extends DirectorRequestBase { req_type: "colorize"; prompt: string; defry: number; } interface EmotionRequest extends DirectorRequestBase { req_type: "emotion"; prompt: string; defry: number; } type DirectorRequest = LineArtRequest | SketchRequest | BackgroundRemovalRequest | DeclutterRequest | ColorizeRequest | EmotionRequest; interface NovelAIOptions { token: string; host?: Host | string; /** Host used for text generation endpoints (default: Host.TEXT) */ textHost?: Host | string; /** * Request timeout in milliseconds. Covers the time until the API responds * (for image generation that includes the generation itself). * @default 120000 */ timeout?: number; retry?: RetryConfig; verbose?: boolean; } interface NovelAIResponse { statusCode: number; statusText: string; headers: Record; data: ArrayBuffer | ReadableStream | null; } /** * Options for the enhance() convenience method — img2img re-generation at a * scaled-up resolution, mirroring the web UI's Enhance feature. */ type EnhanceOptions = Omit & { /** Target resolution multiplier relative to the source image (default: 1.5) */ upscaleFactor?: number; }; interface TagSuggestion { tag: string; confidence?: number; count?: number; } type ChatRole = "system" | "user" | "assistant"; interface ChatMessage { role: ChatRole; content: string; } /** * Options for text generation via the OpenAI-compatible endpoints. * Unknown keys are passed through to the API untouched. */ interface TextGenerationOptions { /** Model id (default: TextModel.ERATO) */ model?: string; max_tokens?: number; temperature?: number; top_p?: number; top_k?: number; min_p?: number; frequency_penalty?: number; presence_penalty?: number; stop?: string | string[]; seed?: number; logit_bias?: Record; n?: number; [key: string]: unknown; } interface ChatCompletionChoice { index: number; message: ChatMessage; finish_reason: string | null; } interface ChatCompletion { id: string; object: string; created: number; model: string; choices: ChatCompletionChoice[]; usage?: { prompt_tokens: number; completion_tokens: number; total_tokens: number; }; } interface ChatCompletionChunkChoice { index: number; delta: Partial; finish_reason: string | null; } interface ChatCompletionChunk { id: string; object: string; created: number; model: string; choices: ChatCompletionChunkChoice[]; } interface Completion { id: string; object: string; created: number; model: string; choices: { index: number; text: string; finish_reason: string | null; }[]; usage?: { prompt_tokens: number; completion_tokens: number; total_tokens: number; }; } /** * Represents an image generated by NovelAI */ declare class Image { /** * The filename of the image */ readonly filename: string; /** * Raw binary image data */ readonly data: Uint8Array; /** * Create a new Image instance * * @param options - Configuration options for the image * @param options.filename - The filename of the image * @param options.data - Raw binary data of the image */ constructor(options: ImageOptions); /** * Get the size of the image in bytes */ get size(): number; /** * Convert the image data to a base64 string * * @returns Base64 encoded image data */ toBase64(): string; /** * Create a data URL for the image * * @returns Data URL for the image (suitable for browser use) */ toDataURL(): string; /** * Save the image to disk (Node.js environment only) * * @param outputPath - Path to save the image to. If a directory is provided, * the image is saved with its original filename in that directory. * @returns Promise that resolves to the full path of the saved file */ save(outputPath: string): Promise; /** * Create a Blob from the image data (browser environment only) * * @returns Blob representing the image */ toBlob(): Blob; /** * Create a File object from the image data (browser environment only) * * @returns File object representing the image */ toFile(): File; } /** * Enum for event types in the msgpack event. */ declare enum EventType { INTERMEDIATE = "intermediate", FINAL = "final" } /** * A single msgpack event object in the return of `generate_image` method or director tools. */ declare class MsgpackEvent { /** * The type of event (intermediate or final) */ readonly event_type: EventType; /** * Sample index */ readonly samp_ix: number; /** * Step index */ readonly step_ix: number; /** * Generation ID */ readonly gen_id: string; /** * Sigma value */ readonly sigma: number; /** * Image data (JPEG for intermediate, PNG for final) */ readonly image: Image; constructor(options: { event_type: EventType; samp_ix: number; step_ix: number; gen_id: string; sigma: number; image: Image; }); toString(): string; } /** * NovelAI client for image generation, director tools and text generation */ declare class NovelAI { private token; private host; private textHost; private timeout; private retryConfig?; private verbose; private headers; /** * Cache of vibe tokens to avoid re-encoding the same images */ private vibeCache; /** * Create a new NovelAI client * * @param options - Client configuration options * @param options.token - NovelAI access token * @param options.host - API host for image endpoints (default: Host.WEB) * @param options.textHost - API host for text endpoints (default: Host.TEXT) * @param options.timeout - Request timeout in milliseconds (default: 120000) * @param options.retry - Configuration for request retries (default: enabled with 3 retries) * @param options.verbose - Whether to log additional information (default: false) */ constructor(options: NovelAIOptions); /** * Generate images using NovelAI's API * * @param metadata - Generation parameters * @param stream - Whether to stream intermediate steps (V4/V4.5 models only, default: false) * @param isOpus - Whether the user has Opus subscription (for cost estimation logging, default: false) * @param forceZip - Route V4 models through the ZIP endpoint instead of the event stream (default: false) * @returns Array of Image objects, or an AsyncGenerator of MsgpackEvent objects when streaming */ generateImage(metadata: Metadata): Promise; generateImage(metadata: Metadata, stream: false, isOpus?: boolean, forceZip?: boolean): Promise; generateImage(metadata: Metadata, stream: true, isOpus?: boolean): Promise>; generateImage(metadata: Metadata, stream: boolean, isOpus?: boolean, forceZip?: boolean): Promise>; /** * Resolve all image-bearing metadata fields to raw base64 strings, * accepting any supported ImageInput format. */ private resolveImageInputs; /** * Convert an ImageInput to a raw base64 string. * Strings are treated as data URLs, remote URLs, file paths (Node.js, when * the file exists), or raw base64 (fallback) — in that order. */ private resolveToBase64; /** * Make a buffered request to the NovelAI API. * The timeout covers the time until the response is fully received. */ private request; /** * Open a streaming request. The timeout covers time-to-headers only, so * long-running streams are not aborted mid-generation. */ private openStream; /** * Parse a streaming response body into MsgpackEvent objects */ private parseEventStream; /** * Extract images from ZIP response (V3 models) */ private extractImagesFromZip; /** * Extract final images from a buffered event stream response (V4 models) */ private extractImagesFromMsgpack; /** * Get response data as ArrayBuffer */ private getResponseBuffer; /** * Convert AbortError into a friendly timeout message */ private handleRequestError; /** * Use a Director tool with the specified request * * @param request - Director tool request * @returns Promise resolving to an Image object */ useDirectorTool(request: DirectorRequest): Promise; /** * Extract the first image from a single-image ZIP response, falling back * to the raw bytes when the response is not a ZIP. */ private unzipSingleImage; /** * Create a director tool request with common parameters */ private createDirectorRequest; /** * Convert an image to line art */ lineArt(image: ImageInput): Promise; /** * Convert an image to sketch */ sketch(image: ImageInput): Promise; /** * Remove the background from an image */ backgroundRemoval(image: ImageInput): Promise; /** * Declutter an image (remove noise, distractions, etc.) */ declutter(image: ImageInput): Promise; /** * Colorize a sketch or line art * * @param image - Image input (path, Blob, File, URL, etc.) * @param prompt - Additional prompt to add to the request * @param defry - Defry value (0-5, default: 0) */ colorize(image: ImageInput, prompt?: string, defry?: number): Promise; /** * Change the emotion of a character in an image * * @param image - Image input (path, Blob, File, URL, etc.) * @param emotion - Target emotion to change to * @param prompt - Additional prompt to add to the request * @param emotionLevel - Strength of the emotion change (default: NORMAL) */ changeEmotion(image: ImageInput, emotion?: string, prompt?: string, emotionLevel?: EmotionLevel): Promise; /** * Upscale an image using NovelAI's dedicated upscaler * * Note: this endpoint lives on api.novelai.net and requires an active * subscription; the upscaled image is returned as-is (no re-generation). * * @param image - Image input (path, Blob, File, URL, etc.) * @param scale - Upscale factor, 2 or 4 (default: 4) * @returns Promise resolving to the upscaled Image */ upscale(image: ImageInput, scale?: 2 | 4): Promise; /** * Enhance an image — img2img re-generation at a scaled-up resolution, * mirroring the web UI's Enhance feature. The target resolution is the * source size multiplied by upscaleFactor, clamped to the API's pixel budget. * * @param image - Image input (path, Blob, File, URL, etc.) * @param options - Enhance options plus any generation metadata * (upscaleFactor default 1.5, strength 0.5, noise 0) * @returns Promise resolving to an array of Image objects */ enhance(image: ImageInput, options?: EnhanceOptions): Promise; /** * Get tag suggestions for a partial tag query * * @param prompt - The incomplete tag query * @param model - The image model to get suggestions for (default: V4.5) * @param lang - Query language, "en" or "jp" (default: "en") * @returns Promise resolving to an array of tag suggestions */ suggestTags(prompt: string, model?: Model, lang?: "en" | "jp"): Promise; /** * Encode images to vibe tokens using the /encode-vibe endpoint. * Uses caching to avoid unnecessary API calls for previously processed images. */ private encodeVibe; /** * Fetch vibe token from the API */ private fetchVibeToken; /** * SHA-256 hash of a base64 image, used as vibe cache key. * Uses Web Crypto, available in browsers and Node.js 18+. */ private getImageHash; /** * Generate a chat completion using NovelAI's text models * * @param messages - Chat messages, or a plain string treated as a single user message * @param options - Generation options (model, max_tokens, temperature, ...) * @returns Promise resolving to a ChatCompletion in OpenAI format */ chat(messages: string | ChatMessage[], options?: TextGenerationOptions): Promise; /** * Generate a chat completion, streaming the response chunk by chunk * * @param messages - Chat messages, or a plain string treated as a single user message * @param options - Generation options (model, max_tokens, temperature, ...) * @returns AsyncGenerator of ChatCompletionChunk objects in OpenAI format */ chatStream(messages: string | ChatMessage[], options?: TextGenerationOptions): Promise>; /** * Generate a raw text completion using NovelAI's text models * * @param prompt - The prompt to continue * @param options - Generation options (model, max_tokens, temperature, ...) * @returns Promise resolving to a Completion in OpenAI format */ completion(prompt: string, options?: TextGenerationOptions): Promise; /** * List available text generation models * * @returns Promise resolving to an array of model ids */ listTextModels(): Promise; private normalizeMessages; /** * Parse an OpenAI-style SSE stream into completion chunks */ private parseChatStream; /** * Make a JSON request with timeout, retry and error handling */ private requestJson; } /** * Creates a timestamp-based filename * @param prefix - Optional prefix for the filename * @param extension - File extension (default: 'png') * @returns Formatted filename */ declare function createFilename(prefix?: string, extension?: string): string; /** * Ensures a directory exists, creating it if necessary (Node.js only, no-op in browser) * @param dir - Directory path */ declare function ensureDirectoryExists(dir: string): Promise; /** * Save binary data to a file (Node.js environment only) * @param data - Binary data as Uint8Array * @param filepath - File path to save to */ declare function saveBinaryFile(data: Uint8Array, filepath: string): Promise; /** * Converts file size to human-readable format * @param bytes - Size in bytes * @returns Formatted size string */ declare function formatFileSize(bytes: number): string; /** * Error thrown for non-2xx API responses. Carries the HTTP status and the * error message returned by the NovelAI API, when available. */ declare class NovelAIApiError extends Error { readonly status: number; readonly statusText: string; constructor(status: number, statusText: string, apiMessage?: string); } /** * A single parsed Server-Sent Event */ interface SSEEvent { event?: string; data: string; } /** * Minimal incremental Server-Sent Events parser. * Feed raw bytes, get complete events out. */ declare class SSEStream { private buffer; private decoder; feed(chunk: Uint8Array): Generator; flush(): Generator; } /** * Real-time msgpack parser that processes streaming data chunk by chunk. * Handles the length-prefixed msgpack format used by NovelAI's V4 API. */ declare class StreamingMsgpackParser { private buffer; private expectedMessageLength; /** * Feed a chunk of data to the parser and yield any complete events */ feedChunk(chunk: Uint8Array): Generator; } /** * Real-time parser for the SSE flavor of NovelAI's event stream * (used by V4 inpainting). Yields MsgpackEvent objects. */ declare class StreamingSSEParser { private sse; feedChunk(chunk: Uint8Array): Generator; flush(): Generator; } /** * Auto-detect format and parse stream data into individual events * * @param streamData - Raw stream data (msgpack or SSE format) * @returns Array of MsgpackEvent objects */ declare function parseStreamEvents(streamData: Uint8Array): MsgpackEvent[]; declare const DEFAULT_RETRY_CONFIG: Required; /** * Execute a function with retry logic * * @param fn - Async function to execute with retry logic * @param retryConfig - Configuration for retry behavior * @returns Promise that resolves with the result of the function */ declare function withRetry(fn: () => Promise, retryConfig?: RetryConfig): Promise; /** * Convert a base64 string to a Uint8Array * @param base64 - Base64 encoded string * @returns Uint8Array of the data */ declare function base64ToUint8Array(base64: string): Uint8Array; /** * Convert a Uint8Array to a base64 string * @param array - Uint8Array data * @returns Base64 encoded string */ declare function uint8ArrayToBase64(array: Uint8Array): string; /** * Parse an image from various input types and return width, height, and base64 data * Supports browser and Node.js environments with various input formats * * @param input - Various image input formats (path, Blob, File, ArrayBuffer, etc.) * @returns Promise resolving to a ParsedImage object with width, height, and base64 data */ declare function parseImage(input: ImageInput): Promise; /** Maximum total pixel count accepted by the generation API */ declare const MAX_PIXELS = 3047424; /** * Scale image dimensions by a factor, clamped to the API's pixel budget and * floored to multiples of 64 (the generation API's dimension granularity). * * @param width - Source width * @param height - Source height * @param factor - Desired scale factor * @param maxPixels - Maximum total pixel count (default: MAX_PIXELS) * @returns Scaled [width, height] tuple */ declare function scaleDimensions(width: number, height: number, factor: number, maxPixels?: number): [number, number]; /** * Prepares metadata for API request * @param metadata - Processed metadata object * @returns Formatted API request payload */ declare function prepareMetadataForApi(metadata: Metadata): any; /** * Calculates the Anlas cost based on parameters * @param metadata - Metadata object with parameters * @param isOpus - Whether user has Opus subscription * @returns Estimated Anlas cost */ declare function calculateCost(metadata: Metadata, isOpus?: boolean): number; /** * Deduplicate tags in a comma-separated string (case-insensitive) * Segments that are part of weighted groups (containing "::") are preserved * as-is and never deduplicated, since a naive comma split cannot tell where * a weight group starts or ends. * * @param prompt - Prompt string with tags separated by commas * @returns Deduplicated prompt string */ declare function deduplicateTags(prompt: string): string; /** * Image Metadata Parser for AI-generated images * Extracts metadata from various AI image generation tools (Stable Diffusion WebUI, NovelAI, etc.) * Supports multiple image formats and metadata storage methods */ /** * Metadata types that can be extracted from AI-generated images */ declare enum MetadataType { STABLE_DIFFUSION_WEBUI = "SD-WEBUI", NOVELAI = "NOVELAI", UNKNOWN = "UNKNOWN", NONE = "NONE" } /** * Structured metadata with keyword and text pairs */ interface MetadataEntry { keyword: string; text: string; } /** * Result of metadata extraction including type and entries */ interface ImageMetadata { type: MetadataType; entries: MetadataEntry[]; raw?: any; } /** * Summary of basic image metadata and AI generation information */ interface ImageSummary { dimensions: { width: number; height: number; }; hasMetadata: boolean; metadataType: MetadataType; generationTool?: string; positivePrompt?: string; negative_prompt?: string; parameters?: Record; rawEntries: MetadataEntry[]; } /** * Extract metadata from an AI-generated image * @param input - Various image input formats * @returns Promise resolving to extracted image metadata */ declare function extractImageMetadata(input: ImageInput): Promise; /** * Extract a simple summary of an AI-generated image * @param input - Various image input formats * @returns Promise resolving to image summary */ declare function getImageSummary(input: ImageInput): Promise; export { Action, type CharacterCaption, type CharacterPrompt, type ChatCompletion, type ChatCompletionChunk, type ChatMessage, type ChatRole, type Completion, Controlnet, DEFAULT_RETRY_CONFIG, type DirectorRequest, DirectorTools, EmotionLevel, EmotionOptions, type EnhanceOptions, EventType, Host, Image, type ImageInput, type ImageOptions, MAX_PIXELS, type Metadata, Model, MsgpackEvent, Noise, NovelAI, NovelAIApiError, type NovelAIOptions, type NovelAIResponse, type ParsedImage, type PositionCoords, RESOLUTION_DIMENSIONS, Resolution, type RetryConfig, SSEStream, Sampler, StreamingMsgpackParser, StreamingSSEParser, type TagSuggestion, type TextGenerationOptions, TextModel, type V4CaptionFormat, type V4ConditionInput, type V4Img2Img, type V4NegativePromptFormat, type V4PromptFormat, base64ToUint8Array, calculateCost, createFilename, deduplicateTags, ensureDirectoryExists, extractImageMetadata, formatFileSize, getImageSummary, parseImage, parseStreamEvents, prepareMetadataForApi, saveBinaryFile, scaleDimensions, uint8ArrayToBase64, withRetry };