novelai-image-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,371 @@
1
+ /**
2
+ * Supported NovelAI image generation models
3
+ */
4
+ declare enum NovelAIModel {
5
+ /** V4.5 Full - Latest model with T5 encoding and multi-character support */
6
+ V45_Full = "nai-diffusion-4-5-full",
7
+ /** V4 Curated - More conservative aesthetic choices */
8
+ V4_Curated = "nai-diffusion-4-curated",
9
+ /** V4 Inpainting - For image editing and inpainting tasks */
10
+ Inpainting = "nai-diffusion-4-inpainting"
11
+ }
12
+
13
+ /**
14
+ * Supported sampling algorithms for image generation
15
+ */
16
+ declare enum NovelAISampler {
17
+ /** Standard Euler sampler */
18
+ Euler = "k_euler",
19
+ /** Euler Ancestral - recommended for anime-style generations */
20
+ EulerAncestral = "k_euler_ancestral",
21
+ /** DPM++ 2M - stable and aesthetic */
22
+ DPM_2M = "k_dpmpp_2m",
23
+ /** DPM++ 2S Ancestral */
24
+ DPM_2S_Ancestral = "k_dpmpp_2s_ancestral",
25
+ /** DPM++ SDE */
26
+ DPM_SDE = "k_dpmpp_sde",
27
+ /** DDIM V3 */
28
+ DDIM = "ddim_v3"
29
+ }
30
+ /**
31
+ * Preset negative prompt configurations
32
+ */
33
+ declare enum UCPreset {
34
+ /** Heavy - Low Quality + Bad Anatomy */
35
+ Heavy = 0,
36
+ /** Light - Low Quality only */
37
+ Light = 1,
38
+ /** None - Use custom negative prompt only */
39
+ None = 2
40
+ }
41
+ /**
42
+ * Noise schedule algorithms
43
+ */
44
+ declare enum NoiseSchedule {
45
+ Native = "native",
46
+ Karras = "karras",
47
+ Exponential = "exponential",
48
+ Polyexponential = "polyexponential"
49
+ }
50
+
51
+ /**
52
+ * V4 condition input structure for prompts
53
+ * Used by both v4_prompt and v4_negative_prompt
54
+ */
55
+ interface V4ConditionInput {
56
+ caption: {
57
+ base_caption: string;
58
+ char_captions: string[];
59
+ };
60
+ use_coords: boolean;
61
+ use_order: boolean;
62
+ legacy_uc?: boolean;
63
+ }
64
+ /**
65
+ * Parameters block for the generate-image API
66
+ * Note: Mixed casing is intentional - matches strict API schema
67
+ */
68
+ interface NovelAIParameters {
69
+ width: number;
70
+ height: number;
71
+ scale: number;
72
+ sampler: NovelAISampler | string;
73
+ steps: number;
74
+ n_samples: number;
75
+ seed: number;
76
+ negative_prompt: string;
77
+ v4_prompt: V4ConditionInput;
78
+ v4_negative_prompt: V4ConditionInput;
79
+ qualityToggle: boolean;
80
+ ucPreset: UCPreset | number;
81
+ params_version: number;
82
+ noise_schedule: NoiseSchedule | string;
83
+ sm: boolean;
84
+ sm_dyn: boolean;
85
+ prefer_brownian: boolean;
86
+ deliberate_euler_ancestral_bug: boolean;
87
+ legacy: boolean;
88
+ legacy_v3_extend: boolean;
89
+ }
90
+ /**
91
+ * Root payload structure for /ai/generate-image endpoint
92
+ */
93
+ interface GenerateImagePayload {
94
+ input: string;
95
+ model: NovelAIModel | string;
96
+ action: 'generate';
97
+ parameters: NovelAIParameters;
98
+ }
99
+ /**
100
+ * SDK configuration options
101
+ */
102
+ interface ClientConfig {
103
+ /** NovelAI Persistent API Token (pst-...) */
104
+ token: string;
105
+ /** Base URL for the image API (default: https://image.novelai.net) */
106
+ baseUrl?: string;
107
+ /** Request timeout in milliseconds (default: 60000) */
108
+ timeout?: number;
109
+ }
110
+ /**
111
+ * Options for building an image generation request
112
+ */
113
+ interface ImageGenerationOptions {
114
+ model?: NovelAIModel;
115
+ width?: number;
116
+ height?: number;
117
+ prompt?: string;
118
+ characterPrompts?: string[];
119
+ negativePrompt?: string;
120
+ seed?: number;
121
+ steps?: number;
122
+ scale?: number;
123
+ sampler?: NovelAISampler;
124
+ ucPreset?: UCPreset;
125
+ qualityToggle?: boolean;
126
+ smea?: boolean;
127
+ smeaDyn?: boolean;
128
+ noiseSchedule?: NoiseSchedule;
129
+ }
130
+
131
+ /**
132
+ * Metadata extracted from generated images
133
+ */
134
+ interface ImageMetadata {
135
+ seed?: number;
136
+ prompt?: string;
137
+ model?: string;
138
+ sampler?: string;
139
+ steps?: number;
140
+ scale?: number;
141
+ }
142
+ /**
143
+ * Response from a successful image generation
144
+ */
145
+ interface ImageResponse {
146
+ /** Generated image(s) as Buffer (Node.js) or Uint8Array (Browser) */
147
+ images: Uint8Array[];
148
+ /** Optional metadata parsed from response */
149
+ metadata?: ImageMetadata;
150
+ }
151
+
152
+ /**
153
+ * Fluent builder for constructing NovelAI image generation requests
154
+ * Provides method chaining and compile-time type safety
155
+ */
156
+ declare class ImageRequestBuilder {
157
+ private client;
158
+ private model;
159
+ private width;
160
+ private height;
161
+ private prompt;
162
+ private characterPrompts;
163
+ private negativePrompt;
164
+ private seed;
165
+ private steps;
166
+ private scale;
167
+ private sampler;
168
+ private ucPreset;
169
+ private qualityToggle;
170
+ private smea;
171
+ private smeaDyn;
172
+ private noiseSchedule;
173
+ constructor(client: NovelAIClient);
174
+ /**
175
+ * Set the model to use for generation
176
+ */
177
+ setModel(model: NovelAIModel): this;
178
+ /**
179
+ * Set the output image dimensions
180
+ * @throws ValidationError if dimensions are not multiples of 64
181
+ */
182
+ setSize(width: number, height: number): this;
183
+ /**
184
+ * Set the main prompt (base scene description)
185
+ * For multi-character prompts, use the array overload
186
+ */
187
+ setPrompt(base: string, characters?: string[]): this;
188
+ /**
189
+ * Add character prompts for multi-character scenes
190
+ */
191
+ addCharacter(characterPrompt: string): this;
192
+ /**
193
+ * Set the negative prompt (what to avoid in generation)
194
+ */
195
+ setNegativePrompt(negative: string): this;
196
+ /**
197
+ * Set the random seed for reproducible generations
198
+ */
199
+ setSeed(seed: number): this;
200
+ /**
201
+ * Set the number of sampling steps
202
+ * @throws ValidationError if steps are out of range (1-50)
203
+ */
204
+ setSteps(steps: number): this;
205
+ /**
206
+ * Set the guidance scale (CFG)
207
+ * @throws ValidationError if scale is out of range (0-10)
208
+ */
209
+ setScale(scale: number): this;
210
+ /**
211
+ * Set the sampling algorithm
212
+ */
213
+ setSampler(sampler: NovelAISampler): this;
214
+ /**
215
+ * Set the UC preset (predefined negative prompt configuration)
216
+ */
217
+ setUCPreset(preset: UCPreset): this;
218
+ /**
219
+ * Toggle automatic quality tags insertion
220
+ */
221
+ setQualityToggle(enabled: boolean): this;
222
+ /**
223
+ * Enable SMEA (Sinusoidal Multipass Euler Ancestral)
224
+ * @param dynamic - If true, enables dynamic SMEA variant
225
+ */
226
+ enableSMEA(dynamic?: boolean): this;
227
+ /**
228
+ * Disable SMEA
229
+ */
230
+ disableSMEA(): this;
231
+ /**
232
+ * Set the noise schedule algorithm
233
+ */
234
+ setNoiseSchedule(schedule: NoiseSchedule): this;
235
+ /**
236
+ * Build the V4 condition input structure for prompts
237
+ */
238
+ private buildV4ConditionInput;
239
+ /**
240
+ * Build the formatted input string for the API
241
+ * Combines base prompt with character prompts using pipe delimiter
242
+ */
243
+ private buildInputString;
244
+ /**
245
+ * Build the complete API payload
246
+ */
247
+ buildPayload(): GenerateImagePayload;
248
+ /**
249
+ * Execute the image generation request
250
+ */
251
+ generate(): Promise<ImageResponse>;
252
+ }
253
+
254
+ /**
255
+ * Main entry point for the NovelAI Image SDK
256
+ *
257
+ * @example
258
+ * ```typescript
259
+ * const client = new NovelAIClient({ token: process.env.NAI_TOKEN });
260
+ *
261
+ * const result = await client.image()
262
+ * .setPrompt('1girl, cyberpunk, neon lights')
263
+ * .setSize(832, 1216)
264
+ * .generate();
265
+ *
266
+ * fs.writeFileSync('output.png', result.images[0]);
267
+ * ```
268
+ */
269
+ declare class NovelAIClient {
270
+ private readonly apiClient;
271
+ /**
272
+ * Create a new NovelAI client
273
+ * @param config - Client configuration including token and optional base URL
274
+ */
275
+ constructor(config: ClientConfig);
276
+ /**
277
+ * Start building an image generation request
278
+ * @returns A new ImageRequestBuilder instance
279
+ */
280
+ image(): ImageRequestBuilder;
281
+ /**
282
+ * Execute a generation request (called internally by the builder)
283
+ * @internal
284
+ */
285
+ _execute(payload: GenerateImagePayload): Promise<ImageResponse>;
286
+ }
287
+
288
+ /**
289
+ * Base error class for all NovelAI SDK errors
290
+ */
291
+ declare class NovelAIError extends Error {
292
+ readonly statusCode?: number;
293
+ constructor(message: string, statusCode?: number);
294
+ }
295
+ /**
296
+ * Authentication error (401/403)
297
+ * Thrown when the API token is invalid or expired
298
+ */
299
+ declare class NovelAIAuthError extends NovelAIError {
300
+ constructor(message?: string);
301
+ }
302
+ /**
303
+ * Payment required error (402)
304
+ * Thrown when the user has insufficient Anlas credits
305
+ */
306
+ declare class NovelAIPaymentError extends NovelAIError {
307
+ constructor(message?: string);
308
+ }
309
+ /**
310
+ * Validation error (400)
311
+ * Thrown when the API rejects the payload due to schema issues
312
+ */
313
+ declare class NovelAIValidationError extends NovelAIError {
314
+ readonly details?: string;
315
+ constructor(message: string, details?: string);
316
+ }
317
+ /**
318
+ * Network error
319
+ * Thrown on timeouts, connection failures, or other network issues
320
+ */
321
+ declare class NovelAINetworkError extends NovelAIError {
322
+ readonly cause?: Error;
323
+ constructor(message: string, cause?: Error);
324
+ }
325
+ /**
326
+ * Rate limit error (429)
327
+ * Thrown when too many requests are made
328
+ */
329
+ declare class NovelAIRateLimitError extends NovelAIError {
330
+ readonly retryAfter?: number;
331
+ constructor(message?: string, retryAfter?: number);
332
+ }
333
+ /**
334
+ * Server error (500+)
335
+ * Thrown when the NovelAI server encounters an internal error
336
+ */
337
+ declare class NovelAIServerError extends NovelAIError {
338
+ readonly correlationId?: string;
339
+ constructor(message?: string, correlationId?: string);
340
+ }
341
+
342
+ /**
343
+ * Convert Uint8Array to Base64 string (useful for browser display)
344
+ */
345
+ declare function toBase64(data: Uint8Array): string;
346
+ /**
347
+ * Convert Uint8Array to data URL for direct use in img src
348
+ */
349
+ declare function toDataURL(data: Uint8Array, mimeType?: string): string;
350
+
351
+ /**
352
+ * Validates that image dimensions are multiples of 64
353
+ * @throws ValidationError if dimensions are invalid
354
+ */
355
+ declare function validateResolution(width: number, height: number): void;
356
+ /**
357
+ * Validates that step count is within acceptable range
358
+ * @throws ValidationError if steps are out of range
359
+ */
360
+ declare function validateSteps(steps: number): void;
361
+ /**
362
+ * Validates that scale (CFG) is within acceptable range
363
+ * @throws ValidationError if scale is out of range
364
+ */
365
+ declare function validateScale(scale: number): void;
366
+ /**
367
+ * Validates that seed is a valid unsigned 32-bit integer
368
+ */
369
+ declare function validateSeed(seed: number): void;
370
+
371
+ export { type ClientConfig, type GenerateImagePayload, type ImageGenerationOptions, type ImageMetadata, ImageRequestBuilder, type ImageResponse, NoiseSchedule, NovelAIAuthError, NovelAIClient, NovelAIError, NovelAIModel, NovelAINetworkError, type NovelAIParameters, NovelAIPaymentError, NovelAIRateLimitError, NovelAISampler, NovelAIServerError, NovelAIValidationError, UCPreset, type V4ConditionInput, toBase64, toDataURL, validateResolution, validateScale, validateSeed, validateSteps };