UNPKG

nekoai-js

Version:

A lightweight JavaScript/TypeScript API for NovelAI image generation and director tools

406 lines (309 loc) 12.9 kB
# 🐾 NekoAI-JS <div align="center"> <img src="https://raw.githubusercontent.com/Nya-Foundation/NekoAI-JS/main/assets/banner.png" alt="NekoAI-JS Banner" width="800" /> <h3>🎨 A lightweight JavaScript/TypeScript API for NovelAI image generation and director tools.</h3> <div> <a href="https://github.com/Nya-Foundation/NekoAI-JS/blob/main/LICENSE"><img src="https://img.shields.io/github/license/Nya-Foundation/nekoai-js.svg" alt="License"/></a> <a href="https://github.com/Nya-Foundation/NekoAI-JS/actions/workflows/release.yml"><img src="https://github.com/Nya-Foundation/NekoAI-JS/actions/workflows/release.yml/badge.svg" alt="Builds & Release"/></a> <a href="https://www.npmjs.com/package/nekoai-js"><img src="https://img.shields.io/npm/v/nekoai-js.svg" alt="npm version"/></a> <a href="https://deepwiki.com/Nya-Foundation/NekoAI-JS"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"/></a> </div> </div> ## 🌈 Introduction > 🐾 **NekoAI-JS** is a **lightweight** and **easy-to-use** JavaScript/TypeScript wrapper for NovelAI's image generation capabilities. This package makes it simple to integrate NovelAI's powerful image generation and manipulation tools into your JavaScript applications with minimal code overhead. > > Built with modern JavaScript/TypeScript features for both browser and Node.js environments, it provides full access to NovelAI's latest models (V3, V4, V4.5) and Director tools while maintaining a clean interface. This project is based on the [NekoAI-API](https://github.com/Nya-Foundation/NekoAI-API) Python package. ### 📄 License Change Notice > **Important**: This project has transitioned from MIT to **AGPL-3.0** license to ensure better compliance and alignment with our inspiration source. As this work builds significantly upon concepts and approaches from NekoAI-API, we've adopted a more appropriate license that better reflects the collaborative nature of open-source development and provides stronger copyleft protections for the community. ## 🌟 Core Capabilities | Feature | Description | | --------------------------- | ------------------------------------------------------------------------------------------------------ | | 🚀 **Lightweight** | Focuses on image generation and Director tools, providing a simple and easy-to-use interface. | | ⚙️ **Parameterized** | Provides strongly typed interfaces to easily set up generation parameters with validation. | | 🔑 **Token Authentication** | Supports direct token authentication for API access. | | 🎬 **Real-time Streaming** | Stream V4/V4.5 generation progress in real-time, watching each denoising step as it happens. | | 🌐 **Cross-Platform** | Works in both browser and Node.js environments. | | ✨ **Latest Models** | Full support for V3, V4, and V4.5 models including multi-character generation. | | 🛠️ **Director Tools** | Complete support for all NovelAI Director tools like line art, background removal, and emotion change. | | 🔄 **TypeScript Support** | Full TypeScript definitions for all API parameters and responses. | | 🔁 **Automatic Retries** | Built-in retry mechanism for handling rate limits and temporary API failures. | ## 📦 Installation ```sh # Using npm npm install nekoai-js # Using yarn yarn add nekoai-js # Using pnpm pnpm add nekoai-js ``` For Node.js environments, you may need to install the optional canvas dependency for image processing: ```sh # Using npm npm install canvas # Using yarn yarn add canvas # Using pnpm pnpm add canvas ``` This is not required for browser environments, as they use the native Canvas API. ## 🚀 Usage ### 🔑 Initialization Import the package and initialize a client with your NovelAI access token. ```javascript // ESM import { NovelAI } from "nekoai-js"; // CommonJS const { NovelAI } = require("nekoai-js"); // Initialize with token const client = new NovelAI({ token: "your_access_token", }); ``` ### 🖼️ Image Generation Generate images with the `generateImage` method. The method takes parameters directly or as a `Metadata` object. ```javascript import { NovelAI, Model, Resolution, Sampler } from "nekoai-js"; // Initialize client const client = new NovelAI({ token: "your_access_token", }); // Generate using parameters directly const images = await client.generateImage({ prompt: "1girl, cute, anime style, detailed", model: Model.V4_5_CUR, resPreset: Resolution.NORMAL_PORTRAIT, n_samples: 1, seed: 1234567890, // Fixed seed for reproducibility }); // Save images (Node.js environment) for (const image of images) { await image.save("./output"); console.log(`Image saved: ${image.filename}`); } // Get image data URL (browser environment) for (const image of images) { const dataUrl = image.toDataURL(); console.log(`Image data URL: ${dataUrl.substring(0, 50)}...`); } ``` ### Multi-Character Generation (V4.5) V4.5 models support generating multiple characters with character-specific prompts and positioning. ```javascript import { NovelAI, Model, Resolution } from "nekoai-js"; // Initialize client const client = new NovelAI({ token: "your_access_token", }); // Create character prompts with positioning const characterPrompts = [ { prompt: "girl, red hair, red dress", uc: "bad hands, bad anatomy", center: { x: 0.3, y: 0.3 }, }, { prompt: "boy, blue hair, blue uniform", uc: "bad hands, bad anatomy", center: { x: 0.7, y: 0.7 }, }, ]; // Generate image with multiple characters const images = await client.generateImage({ prompt: "two people standing together, park background", model: Model.V4_5_CUR, resPreset: Resolution.NORMAL_LANDSCAPE, characterPrompts, }); // Process the resulting images for (const image of images) { // Browser const dataUrl = image.toDataURL(); // Node.js await image.save("./output"); } ``` ### Image to Image To perform `img2img` action, set `action` parameter to `Action.IMG2IMG`, and provide a base64-encoded image. ```javascript import { NovelAI, Action } from "nekoai-js"; import { readFileSync } from "fs"; // Node.js only // Initialize client const client = new NovelAI({ token: "your_access_token", }); // Read image and convert to base64 (Node.js) const image = readFileSync("./input/image.png"); const base64Image = image.toString("base64"); // Browser version: // const base64Image = await fileToBase64(imageFile); // You'll need to implement fileToBase64 const images = await client.generateImage({ prompt: "1girl, fantasy outfit", action: Action.IMG2IMG, width: 512, height: 768, image: base64Image, strength: 0.5, // Lower = more similar to original noise: 0.1, }); for (const image of images) { await image.save("./output"); } ``` ### Director Tools NovelAI offers several Director tools for image manipulation, all accessible through dedicated methods. ```javascript import { NovelAI } from "nekoai-js"; import { readFileSync } from "fs"; // Node.js only // Initialize client const client = new NovelAI({ token: "your_access_token", }); // Line Art const lineArtResult = await client.lineArt("./input/image.png"); await lineArtResult.save("./output"); // Background Removal const bgRemovalResult = await client.backgroundRemoval("./input/image.png"); await bgRemovalResult.save("./output"); // Change Emotion const emotionResult = await client.changeEmotion({ image: "./input/image.png", emotion: "happy", prompt: "neutral", emotionLevel: 0, // Normal level }); await emotionResult.save("./output"); // Other Director Tools const declutterResult = await client.declutter("./input/image.png"); const colorizeResult = await client.colorize("./input/image.png"); ``` All Director Tool methods automatically handle ZIP-compressed responses from the API, extracting the image data for you. This works across both Node.js and browser environments. ### Flexible Image Input The library supports multiple image input formats for cross-platform compatibility. Here are examples of using various input types with Director tools: #### Node.js Environment ```javascript import { NovelAI } from "nekoai-js"; import { readFileSync } from "fs"; const client = new NovelAI({ token: "your_access_token", }); // 1. Using a file path const result1 = await client.lineArt("./input/image.png"); // 2. Using a Uint8Array const imageData = readFileSync("./input/image.png"); const result2 = await client.lineArt(imageData); // 3. Using a base64 string const base64Data = readFileSync("./input/image.png").toString("base64"); const result3 = await client.backgroundRemoval(base64Data); // 4. Using a remote URL const result4 = await client.declutter("https://example.com/image.png"); ``` #### Browser Environment ```javascript import { NovelAI } from "nekoai-js"; const client = new NovelAI({ token: "your_access_token", }); // 1. Using a File from input element const fileInput = document.getElementById("fileInput"); fileInput.addEventListener("change", async (e) => { const file = e.target.files[0]; const result = await client.lineArt(file); // Display result const img = document.createElement("img"); img.src = result.toDataURL(); document.body.appendChild(img); }); // 2. Using a Blob const response = await fetch("https://example.com/image.png"); const blob = await response.blob(); const result = await client.backgroundRemoval(blob); // 3. Using an image element const imgElement = document.getElementById("sourceImage"); const result = await client.changeEmotion({ image: imgElement, targetEmotion: "happy", }); // 4. Using a canvas element const canvas = document.getElementById("sourceCanvas"); const result = await client.colorize(canvas); // 5. Using a data URL const result = await client.declutter("data:image/png;base64,iVBORw0KGg..."); ``` ### Using Custom Hosts NekoAI-JS supports using custom hosts for API requests. This is useful if you need to use a different endpoint or if you're using a proxy server. ```javascript import { NovelAI, Host, createCustomHost } from "nekoai-js"; // Initialize client const client = new NovelAI({ token: "your_access_token", }); // Method 1: Use predefined hosts const images1 = await client.generateImage( { prompt: "1girl, cute, anime style", model: Model.V3, }, Host.API, // Use the API host instead of default WEB host ); // Method 2: Create and use a custom host const customHost = createCustomHost( "https://your-custom-host.com", "binary/octet-stream", "custom-host-name", ); const images2 = await client.generateImage( { prompt: "1girl, cute, anime style", model: Model.V4, }, customHost, ); // Custom hosts also work with director tools const lineArtResult = await client.lineArt("./input/image.png", customHost); ``` You can use custom hosts for: 1. Connection to third-party API providers 2. Working with proxies 3. Connecting to local NovelAI servers 4. Load balancing between multiple endpoints ### Custom Retry Configuration NekoAI-JS includes a built-in retry mechanism for handling rate limits and temporary API failures. By default, retries are enabled with reasonable defaults, but you can customize this behavior: ```javascript import { NovelAI, Model } from "nekoai-js"; // Initialize client with custom retry settings const client = new NovelAI({ token: "your_access_token", retry: { enabled: true, // Enable retries maxRetries: 5, // Maximum 5 retry attempts baseDelay: 2000, // Start with 2 second delay maxDelay: 60000, // Maximum delay of 1 minute retryStatusCodes: [429], // Only retry on rate limit errors }, }); // Generate image with retry try { const images = await client.generateImage({ prompt: "1girl, cute, anime style", model: Model.V4_5_CUR, }); console.log("Success after potential retries!"); } catch (error) { console.error("Failed even after retries:", error); } ``` You can also disable retries completely if needed: ```javascript const client = new NovelAI({ token: "your_access_token", retry: { enabled: false, // Disable retries }, }); ``` The retry mechanism uses exponential backoff with jitter to prevent overwhelming the API service when it's under stress. ## References [NovelAI Documentation](https://docs.novelai.net/) [NovelAI Backend API](https://api.novelai.net/docs) [NovelAI Unofficial Knowledgebase](https://naidb.miraheze.org/wiki/Using_the_API) [NekoAI-API Python Package](https://github.com/Nya-Foundation/NekoAI-API)