# Sogni SDK - Complete LLM Reference > @sogni-ai/sogni-client - JavaScript/Node.js SDK for AI image, video, and audio generation > Version: 4.2.0-alpha.24 | License: ISC | Platform: Node.js & Browser > Repository: https://github.com/Sogni-AI/sogni-client > API Docs: https://sdk-docs.sogni.ai ================================================================================ TABLE OF CONTENTS ================================================================================ 1. Overview & Installation 2. Quick Start Examples 3. Client Initialization 4. Image Generation 5. Video Generation - WAN 2.2 Models 6. Video Generation - LTX-2.3 Models 7. Video Generation - Seedance 2.0 Models 8. Audio Generation - ACE-Step 1.5 Models 9. LLM Text Generation 10. LLM Tool Calling & Sogni Platform Tools 11. Vision Chat (Multimodal Image Understanding) 12. Complete Parameter Reference 13. Events & Progress Tracking 14. Models, Presets & Options 15. Cost Estimation 16. Error Handling 17. Advanced Patterns 18. Type Definitions ================================================================================ 1. # OVERVIEW & INSTALLATION The Sogni SDK provides access to the Sogni Supernet - a decentralized network for AI inference. It supports: - Image Generation: Stable Diffusion, Flux, Z-Image, Z-Image Turbo, Qwen Image Edit - Video Generation: WAN 2.2 (5 workflows), LTX-2.3 models, Seedance 2.0 external API models - Audio Generation: ACE-Step 1.5 music generation (Turbo and SFT models) - LLM Text Generation: Chat completions with streaming, multi-turn, and thinking mode - LLM Tool Calling: OpenAI-compatible function calling with custom and platform tools - Sogni Platform Tools: Generate images, image edits, videos, audio-driven videos, video transforms, and music via natural language chat - Vision Chat: Multimodal image understanding via VLM (scene description, OCR, object detection, visual analysis) - Real-time Progress: WebSocket-based event system - Multiple Networks: Fast (GPU) and Relaxed (Mac) INSTALLATION: ```bash npm install @sogni-ai/sogni-client ``` REQUIREMENTS: - Node.js >=22 or modern browser - Sogni account with token balance (free signup at app.sogni.ai) - Each email-verified account is allowed 400 free Spark render credits per month. On the API, free credits can be used with Z-Image Turbo; paid credits can access all models and features. PACKAGE SHAPE: - CommonJS: `dist/index.js` - ESM: `dist-esm/index.js` - TypeScript declarations: `dist/index.d.ts` - Public root class: `SogniClient` - Public namespaces: `account`, `projects`, `chat`, `workflows`, `replay`, `stats`, `apiClient` - Commonly used methods: `sogni.chat.completions.create()`, `sogni.projects.estimateCost()`, `sogni.projects.estimateVideoCost()`, `sogni.projects.estimateAudioCost()`, `sogni.workflows.start()` ================================================================================ 2. QUICK START EXAMPLES ================================================================================ MINIMAL IMAGE GENERATION: ```javascript import { SogniClient } from '@sogni-ai/sogni-client'; // Option 1: API key auth (recommended) — no login() needed const sogni = await SogniClient.createInstance({ appId: 'my-unique-app-id', apiKey: 'your-api-key' }); // Option 2: Username/password auth // const sogni = await SogniClient.createInstance({ appId: 'my-unique-app-id' }); // await sogni.account.login('username', 'password'); await sogni.projects.waitForModels(); const project = await sogni.projects.create({ type: 'image', modelId: 'flux1-schnell-fp8', positivePrompt: 'A cat wearing a hat', numberOfMedia: 1, steps: 4, guidance: 1 }); const urls = await project.waitForCompletion(); console.log('Image URL:', urls[0]); // Valid for 24 hours ``` MINIMAL VIDEO GENERATION: ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'wan_v2.2-14b-fp8_t2v_lightx2v', positivePrompt: 'Ocean waves crashing on a beach at sunset', numberOfMedia: 1, duration: 5, fps: 16 }); const urls = await project.waitForCompletion(); console.log('Video URL:', urls[0]); ``` ================================================================================ 3. CLIENT INITIALIZATION ================================================================================ CREATING THE CLIENT: ```javascript import { SogniClient } from '@sogni-ai/sogni-client'; const sogni = await SogniClient.createInstance({ appId: 'your-unique-app-id', // Required - UUID recommended network: 'fast' // 'fast' or 'relaxed' }); ``` AUTHENTICATION - API KEY (Recommended): Get your API key: Log in to dashboard.sogni.ai and click your Username dropdown in the top-right corner to provision your key. ```javascript // API key auth — auto-authenticates via WebSocket, no login() needed const sogni = await SogniClient.createInstance({ appId: 'your-unique-app-id', network: 'fast', apiKey: 'your-api-key' }); // Client is authenticated immediately after creation ``` AUTHENTICATION - USERNAME/PASSWORD: ```javascript // Username/password login const sogni = await SogniClient.createInstance({ appId: 'your-unique-app-id', network: 'fast' }); await sogni.account.login('username', 'password'); ``` API KEY VS USERNAME/PASSWORD: - API key: Pass `apiKey` to `createInstance()`. Auto-authenticates via WebSocket header. No `login()` call needed. Most REST API calls (balance, profile, etc.) available. Sensitive operations (withdrawals, staking, 2FA) not available. - Username/password: Call `login()` after `createInstance()`. Full REST API access. ACCOUNT INFO: ```javascript // Get current user info const user = await sogni.account.me(); console.log(user.username, user.email); // Get balance await sogni.account.refreshBalance(); console.log(sogni.account.currentAccount.balance); ``` `checkAuth()` is only for cookie-auth browser flows on permitted Sogni domains. API-key auth auto-authenticates during `createInstance()`. Username/password auth uses `sogni.account.login()`. Token auth can be resumed with `sogni.setTokens()`. NETWORK TYPES: - 'fast': High-end GPU workers. Faster, higher cost. REQUIRED for video. - 'relaxed': Mac device workers. Slower, lower cost. Image only. CONNECTION EVENTS: ```javascript sogni.apiClient.on('connected', ({ network }) => { console.log('Connected to:', network); }); sogni.apiClient.on('disconnected', ({ code, reason }) => { console.log('Disconnected:', code, reason); }); ``` ================================================================================ 4. IMAGE GENERATION ================================================================================ BASIC IMAGE GENERATION: ```javascript const project = await sogni.projects.create({ type: 'image', modelId: 'flux1-schnell-fp8', positivePrompt: 'A serene mountain landscape at dawn', negativePrompt: 'blurry, low quality, watermark', stylePrompt: 'photorealistic', numberOfMedia: 1, steps: 4, guidance: 1, outputFormat: 'jpg' }); const urls = await project.waitForCompletion(); ``` WITH SIZE PRESET: ```javascript const project = await sogni.projects.create({ type: 'image', modelId: 'flux1-schnell-fp8', positivePrompt: 'Portrait of a woman', numberOfMedia: 1, sizePreset: 'portrait_7_9', steps: 4, guidance: 1 }); ``` WITH CUSTOM DIMENSIONS: ```javascript const project = await sogni.projects.create({ type: 'image', modelId: 'flux1-schnell-fp8', positivePrompt: 'Wide landscape', numberOfMedia: 1, sizePreset: 'custom', width: 1920, height: 1080, steps: 4, guidance: 1 }); ``` IMAGE-TO-IMAGE (Starting Image): ```javascript import fs from 'fs'; const project = await sogni.projects.create({ type: 'image', modelId: 'coreml-cyberrealistic_v70_768', positivePrompt: 'Transform into oil painting style', startingImage: fs.readFileSync('./input.png'), startingImageStrength: 0.7, // 0-1, higher = more original preserved numberOfMedia: 1, steps: 20, guidance: 7.5 }); ``` WITH CONTROLNET: ```javascript const project = await sogni.projects.create({ type: 'image', modelId: 'coreml-cyberrealistic_v70_768', positivePrompt: 'Professional portrait photo', numberOfMedia: 1, steps: 20, guidance: 7.5, controlNet: { name: 'openpose', image: fs.readFileSync('./pose-reference.png'), strength: 0.8, mode: 'balanced', guidanceStart: 0, guidanceEnd: 1 } }); ``` CONTROLNET TYPES: - canny: Edge detection - depth: Depth map - openpose: Body pose - lineart: Line art extraction - lineartanime: Anime-style lines - scribble: Rough sketches - softedge: Soft edge detection - tile: Texture/detail preservation - inpaint: Inpainting mask - instrp2p: Instruction-based editing - mlsd: Straight line detection - normalbae: Normal map - segmentation: Semantic segmentation - shuffle: Style shuffle - instantid: Face identity WITH CONTEXT IMAGES (Qwen Image Edit): ```javascript const project = await sogni.projects.create({ type: 'image', modelId: 'qwen_image_edit_2511_fp8_lightning', positivePrompt: 'Combine these into one scene', contextImages: [ fs.readFileSync('./image1.png'), fs.readFileSync('./image2.png'), fs.readFileSync('./image3.png') ], numberOfMedia: 1, steps: 4, guidance: 1 }); ``` GPT Image 2 uses `modelId: 'gpt-image-2'`, supports up to 16 `contextImages`, accepts `gptImageQuality: 'low' | 'medium' | 'high'`, supports `outputFormat: 'png' | 'jpg' | 'webp'`, and is Spark-only. RECOMMENDED MODELS: | Model ID | Type | Steps | Guidance | Notes | |----------|------|-------|----------|-------| | flux1-schnell-fp8 | Fast | 4 | 1 | Best for quick iteration | | z_image_turbo_bf16 | Ultra-fast | 8 | 1 | Fastest generation | | z_image_bf16 | Quality | 20 | 3 | High quality Z-Image generation | | qwen_image_edit_2511_fp8_lightning | Edit | 4 | 1 | Multi-image context | | coreml-cyberrealistic_v70_768 | SD 1.5 | 20-40 | 7.5 | Photorealistic | ================================================================================ 5. VIDEO GENERATION - WAN 2.2 MODELS ================================================================================ ## CRITICAL: WAN 2.2 FPS BEHAVIOR WAN 2.2 models ALWAYS generate video at 16fps internally. The 'fps' parameter (16 or 32) only controls POST-RENDER frame interpolation: - fps: 16 -> No interpolation, output is 16fps - fps: 32 -> Frames are doubled via interpolation, output is 32fps Frame calculation: duration \* 16 + 1 (IGNORES fps setting) Example: 5 seconds always = 81 frames generated, regardless of fps MODEL VARIANTS: - Speed models (with \_lightx2v suffix): 4-step, faster, good quality - Quality models (without suffix): More steps, slower, best quality WORKFLOW REFERENCE TABLE: | Workflow | Model ID | Assets Required | |----------|----------|-----------------| | Text-to-Video | wan_v2.2-14b-fp8_t2v_lightx2v | None | | Image-to-Video | wan_v2.2-14b-fp8_i2v_lightx2v | referenceImage | | Sound-to-Video | wan_v2.2-14b-fp8_s2v_lightx2v | referenceImage + referenceAudio | | Animate-Move | wan_v2.2-14b-fp8_animate-move_lightx2v | referenceImage + referenceVideo | | Animate-Replace | wan_v2.2-14b-fp8_animate-replace_lightx2v | referenceImage + referenceVideo | TEXT-TO-VIDEO: ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'wan_v2.2-14b-fp8_t2v_lightx2v', positivePrompt: 'A hummingbird hovering near a flower, slow motion', negativePrompt: 'blurry, distorted', numberOfMedia: 1, duration: 5, fps: 16, shift: 5.0 // Motion intensity: 1.0-8.0 }); const urls = await project.waitForCompletion(); ``` IMAGE-TO-VIDEO: ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'wan_v2.2-14b-fp8_i2v_lightx2v', positivePrompt: 'The subject slowly turns their head and smiles', referenceImage: fs.readFileSync('./portrait.jpg'), numberOfMedia: 1, duration: 5, fps: 16 }); ``` IMAGE-TO-VIDEO WITH END FRAME (Interpolation): ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'wan_v2.2-14b-fp8_i2v_lightx2v', positivePrompt: 'Smooth transition between poses', referenceImage: fs.readFileSync('./start-pose.jpg'), referenceImageEnd: fs.readFileSync('./end-pose.jpg'), numberOfMedia: 1, duration: 5, fps: 16 }); ``` SOUND-TO-VIDEO (Lip Sync): ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'wan_v2.2-14b-fp8_s2v_lightx2v', positivePrompt: '', // Optional for s2v referenceImage: fs.readFileSync('./face.jpg'), referenceAudio: fs.readFileSync('./speech.m4a'), audioStart: 0, // Where to start in audio file (seconds) audioDuration: 5, // How much audio to use (seconds) numberOfMedia: 1, duration: 5, fps: 16 }); ``` ANIMATE-MOVE (Motion Transfer): ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'wan_v2.2-14b-fp8_animate-move_lightx2v', positivePrompt: '', referenceImage: fs.readFileSync('./character.jpg'), // Subject to animate referenceVideo: fs.readFileSync('./motion-source.mp4'), // Motion source videoStart: 0, // Where to start in video (seconds) numberOfMedia: 1, duration: 5, fps: 16 }); ``` ANIMATE-REPLACE (Subject Replacement): ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'wan_v2.2-14b-fp8_animate-replace_lightx2v', positivePrompt: '', referenceImage: fs.readFileSync('./new-character.jpg'), // New subject referenceVideo: fs.readFileSync('./original-video.mp4'), // Video with subject to replace videoStart: 0, numberOfMedia: 1, duration: 5, fps: 16 }); ``` WAN 2.2 VIDEO PARAMETERS: | Parameter | Type | Range | Default | Notes | |-----------|------|-------|---------|-------| | duration | number | 1-10 | - | Seconds of video | | fps | number | 16, 32 | 16 | Only controls interpolation | | shift | number | 1.0-8.0 | 5.0/8.0 | Motion intensity | | steps | number | 4-50 | varies | More = quality, slower | | teacacheThreshold | number | 0.0-1.0 | 0 | Speedup optimization | | audioStart | number | 0+ | 0 | s2v: audio start position | | audioDuration | number | 1-30 | 30 | s2v: audio length to use | | videoStart | number | 0+ | 0 | animate: video start position | ================================================================================ 6. VIDEO GENERATION - LTX-2.3 MODELS ================================================================================ ## CRITICAL: LTX FPS BEHAVIOR (Different from WAN!) LTX-2.3 models generate at the ACTUAL specified FPS (1-60 range). There is NO post-render interpolation. Frame calculation: duration * fps + 1 Frame count must follow pattern: 1 + n*8 (valid: 1, 9, 17, 25, 33, 41, ...) The SDK automatically snaps to valid frame counts. Example: 5 seconds at 24fps = 121 frames (1 + 15\*8 = 121) LTX-2.3 22B MODELS (Recommended): - Speed models (with \_distilled suffix): 8-step, faster, good quality - Quality models (with \_dev suffix): 20-step, slower, best quality | Workflow | Model ID (Fast) | Model ID (Quality) | | -------------------- | ---------------------------- | ---------------------- | | Text-to-Video | ltx23-22b-fp8_t2v_distilled | ltx23-22b-fp8_t2v_dev | | Image-to-Video | ltx23-22b-fp8_i2v_distilled | ltx23-22b-fp8_i2v_dev | | Audio-to-Video | ltx23-22b-fp8_a2v_distilled | ltx23-22b-fp8_a2v_dev | | Image+Audio-to-Video | ltx23-22b-fp8_ia2v_distilled | ltx23-22b-fp8_ia2v_dev | VIDEO-TO-VIDEO CONTROLNET (LTX-2.3): | Workflow | Model ID (Fast) | Model ID (Quality) | |----------|-----------------|---------------------| | Video-to-Video (ControlNet) | ltx23-22b-fp8_v2v_distilled | ltx23-22b-fp8_v2v_dev | LTX-2.3 TEXT-TO-VIDEO: ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'ltx23-22b-fp8_t2v_dev', positivePrompt: 'A butterfly landing on a flower', numberOfMedia: 1, duration: 8, fps: 24 }); ``` LTX-2.3 IMAGE-TO-VIDEO WITH KEYFRAMES: ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'ltx23-22b-fp8_i2v_dev', positivePrompt: 'Smooth camera movement', referenceImage: fs.readFileSync('./start.jpg'), referenceImageEnd: fs.readFileSync('./end.jpg'), firstFrameStrength: 0.6, // 0-1, how closely to match start lastFrameStrength: 0.6, // 0-1, how closely to match end numberOfMedia: 1, duration: 8, fps: 24 }); ``` LTX-2.3 VIDEO-TO-VIDEO WITH CONTROLNET: ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'ltx23-22b-fp8_v2v_distilled', // Must use v2v model for ControlNet positivePrompt: 'Transform into anime style', referenceVideo: fs.readFileSync('./source-video.mp4'), controlNet: { name: 'canny', // 'canny', 'pose', 'depth', or 'detailer' strength: 0.6 // Recommended: canny/depth 0.6, pose/detailer 0.85 }, numberOfMedia: 1, duration: 5, fps: 24 }); ``` LTX VIDEO PARAMETERS: | Parameter | Type | Range | Default | Notes | |-----------|------|-------|---------|-------| | duration | number | 4-20 | - | Seconds of video | | fps | number | 1-60 | 24 | Actual generation FPS | | firstFrameStrength | number | 0.0-1.0 | 0.6 | Keyframe matching | | lastFrameStrength | number | 0.0-1.0 | 0.6 | Keyframe matching | ================================================================================ 7. VIDEO GENERATION - SEEDANCE 2.0 MODELS ================================================================================ Seedance 2.0 models use the external API path. They generate at fixed 24fps and currently support 4-15 second direct SDK outputs. Seedance models are premium/external API models and are Spark-only. Seedance 2.0 Fast accepts the same optional image, video, and audio references and caps output at 720p. Seedance can combine reference media in one request: up to 9 image assets, 3 video assets, 3 audio assets, and 12 total assets. Text+audio-only is unsupported; use at least one image or video reference with audio references. Prompt-visible reference tags use `@Image1`, `@Video1`, and `@Audio1`, counted independently by modality in attachment order. Assign every useful reference a role and prefer positive preservation constraints. Exact readable text/logos, lip-sync, voice cloning, and real-human-reference behavior need review. SEEDANCE MODEL IDS: | Model ID | Context Assets | Notes | |----------|----------------|-------| | seedance-2-0 | Optional image, video, and audio refs | 24fps, 4-15s, 1080p | | seedance-2-0-fast | Optional image, video, and audio refs | 24fps, 4-15s, 720p cap | SEEDANCE TEXT-TO-VIDEO: ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'seedance-2-0', positivePrompt: 'A cinematic neon skyline time lapse', numberOfMedia: 1, duration: 5, fps: 24, width: 1920, height: 1088, tokenType: 'spark' }); ``` SEEDANCE MULTIMODAL CONTEXT: Use URL arrays for loose Seedance context references that should not lock first/last frames. URLs must be HTTPS and reachable by the vendor. Use role-tagged prompts such as `Use @Image1 for product identity, @Video1 for camera movement, and @Audio1 for music rhythm. Keep the product silhouette and logo placement consistent.` ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'seedance-2-0', positivePrompt: 'Use @Image1 as the product identity, @Image2 for detail inserts, @Video1 for camera movement, and @Audio1 for music rhythm. Create one cohesive launch spot with smooth continuity and crisp product preservation.', duration: 8, fps: 24, width: 1920, height: 1088, referenceImageUrls: [ 'https://cdn.example.com/product-front.png', 'https://cdn.example.com/product-detail.png' ], referenceVideoUrls: ['https://cdn.example.com/motion-reference.mp4'], referenceAudioUrls: ['https://cdn.example.com/music-reference.m4a'] }); ``` SEEDANCE IMAGE-TO-VIDEO: ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'seedance-2-0', positivePrompt: 'slow push-in, soft parallax, cinematic lighting', referenceImage: fs.readFileSync('./subject.jpg'), duration: 5, fps: 24 }); ``` SEEDANCE VIDEO-TO-VIDEO: ```javascript const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'seedance-2-0', positivePrompt: 'Restyle this clip as a painted anime scene', referenceVideo: fs.readFileSync('./source.mp4'), duration: 5, fps: 24 }); ``` Chat/tool aliases: `seedance2` and `seedance2-fast`. V2V uses `seedance2` as the model selector and `seedance-v2v` as the control mode. For focused endpoint coverage with server-side Seedance prompt expansion, see `examples/workflow_partner_seedance_video.mjs`. It covers Seedance T2V, I2V, IA2V, V2V, and multimodal context through the hosted Sogni tools and hosted workflow endpoint. ================================================================================ 8. AUDIO GENERATION - ACE-STEP 1.5 MODELS ================================================================================ ACE-Step 1.5 models generate music from text descriptions with optional lyrics. Two model variants are available: MODEL VARIANTS: | Model ID | Name | Description | |----------|------|-------------| | ace_step_1.5_turbo | Fast & Catchy | Quick generation, best quality sound | | ace_step_1.5_sft | More Control | More accurate lyrics, less stable | TEXT-TO-MUSIC (Instrumental): ```javascript const project = await sogni.projects.create({ type: 'audio', modelId: 'ace_step_1.5_turbo', positivePrompt: 'Upbeat electronic dance music with synth leads and driving bass', numberOfMedia: 1, duration: 30, // seconds (10-600) bpm: 128, // beats per minute (30-300) keyscale: 'C major', timesignature: '4', // 4/4 time steps: 8, outputFormat: 'mp3' }); const urls = await project.waitForCompletion(); console.log(urls[0]); // Audio URL (valid 24 hours) ``` TEXT-TO-MUSIC (With Lyrics): ```javascript const project = await sogni.projects.create({ type: 'audio', modelId: 'ace_step_1.5_sft', positivePrompt: 'Soft acoustic folk ballad with fingerpicked guitar', lyrics: 'Verse 1:\nWalking down a quiet road\nWith the wind upon my face\n\nChorus:\nThis is where I find my peace\nIn this gentle, open space', language: 'en', numberOfMedia: 2, // Generate 2 versions duration: 60, bpm: 90, keyscale: 'A minor', timesignature: '3', // 3/4 waltz time steps: 12, composerMode: true, creativity: 0.85, promptStrength: 2.0 }); ``` MULTIPLE VERSIONS: Use `numberOfMedia` (1-4) to generate multiple variations of the same prompt. Each version uses a different random seed, producing unique interpretations. ACE-STEP 1.5 AUDIO PARAMETERS: | Parameter | Type | Range | Default | Notes | |-----------|------|-------|---------|-------| | duration | number | 10-600 | 30 | Seconds of audio | | bpm | number | 30-300 | 120 | Beats per minute | | keyscale | string | see below | C major | Musical key and scale | | timesignature | string | 2, 3, 4, 6 | 4 | Time signature (2/4, 3/4, 4/4, 6/8) | | lyrics | string | - | - | Song lyrics (omit for instrumental) | | language | string | en, ja, zh, etc. | en | Lyrics language code (51 languages) | | composerMode | boolean | - | true | AI composer for higher quality | | promptStrength | number | 0-10 | 2.0 | Prompt adherence (higher = stricter) | | creativity | number | 0-2 | 0.85 | Composition temperature | | shift | number | 1-5 | 3 | Denoising distribution (turbo only) | | steps | number | 4-16 | 8 | Inference steps | | outputFormat | string | mp3, wav, flac | mp3 | Audio output format | SUPPORTED KEYS: C, C#, Db, D, D#, Eb, E, F, F#, Gb, G, G#, Ab, A, A#, Bb, B (each with major and minor variants, e.g., "C major", "A minor") TIME SIGNATURES: - 2 = 2/4 time (marches, polka) - 3 = 3/4 time (waltzes, ballads) - 4 = 4/4 time (most pop, rock, hip-hop) - 6 = 6/8 time (compound time, folk dances) SUPPORTED LANGUAGES: en (English), ja (Japanese), zh (Chinese), es (Spanish), de (German), fr (French), pt (Portuguese), ru (Russian), it (Italian), nl (Dutch), pl (Polish), tr (Turkish), vi (Vietnamese), cs (Czech), fa (Persian), id (Indonesian), ko (Korean), uk (Ukrainian), hu (Hungarian), ar (Arabic), sv (Swedish), ro (Romanian), el (Greek), and more. Use 'unknown' for auto-detect. ================================================================================ 9. LLM TEXT GENERATION ================================================================================ The Sogni SDK supports LLM text generation through the Supernet with socket-native chat completions, hosted REST chat completions, durable hosted chat runs, streaming, multi-turn conversations, thinking/reasoning controls, structured outputs, and tool calling. DEFAULT LLM MODEL: qwen3.6-35b-a3b-gguf-iq4xs PRIMARY CHAT SURFACES: - `sogni.chat.completions.create(params)` - socket-native chat. Returns `ChatCompletionResult` for `stream: false` and `ChatStream` for `stream: true`. - `sogni.chat.hosted.create(params)` - hosted REST chat completion at `/v1/chat/completions`; can execute hosted Sogni tools server-side. - `sogni.chat.runs.{create,get,cancel,streamEvents}` - durable hosted runs at `/v1/chat/runs`; the server owns the LLM/tool loop and clients can reconnect through SSE event replay. CHAT COMPLETION (Non-Streaming): ```javascript const response = await sogni.chat.completions.create({ model: 'qwen3.6-35b-a3b-gguf-iq4xs', messages: [ { role: 'system', content: 'You are a helpful assistant.' }, { role: 'user', content: 'Explain quantum computing briefly.' } ], max_tokens: 4096, temperature: 0.7, top_p: 0.9 }); console.log(response.content); console.log(response.finishReason); console.log(response.usage); ``` STREAMING CHAT COMPLETION: ```javascript const stream = await sogni.chat.completions.create({ model: 'qwen3.6-35b-a3b-gguf-iq4xs', messages: [{ role: 'user', content: 'Tell me a story about a cat' }], max_tokens: 4096, stream: true }); for await (const chunk of stream) { if (chunk.content) process.stdout.write(chunk.content); if (chunk.tool_calls) { // Tool-call deltas can stream incrementally. } } ``` MULTI-TURN CONVERSATION: ```javascript const messages = [{ role: 'system', content: 'You are a helpful assistant.' }]; // Turn 1 messages.push({ role: 'user', content: 'What is the Sogni Supernet?' }); const response1 = await sogni.chat.completions.create({ model: 'qwen3.6-35b-a3b-gguf-iq4xs', messages }); messages.push({ role: 'assistant', content: response1.content }); // Turn 2 (with context from turn 1) messages.push({ role: 'user', content: 'How does it compare to centralized services?' }); const response2 = await sogni.chat.completions.create({ model: 'qwen3.6-35b-a3b-gguf-iq4xs', messages }); console.log(response2.content); ``` THINKING MODE: Control model reasoning/thinking via `think`: - `think: true` sends `chat_template_kwargs: { enable_thinking: true }`. - `think: false` sends `chat_template_kwargs: { enable_thinking: false }`. - Omit `think` to use server defaults. Streaming chunks and completion results expose generated text through `content` and tool invocations through `tool_calls`. For structured outputs from thinking-capable models, prefer tool calling or `response_format` instead of parsing prose. STRUCTURED OUTPUT: ```javascript const result = await sogni.chat.completions.create({ model: 'qwen3.6-35b-a3b-gguf-iq4xs', messages: [{ role: 'user', content: 'Return a two-item todo list as JSON.' }], response_format: { type: 'json_schema', json_schema: { name: 'todo_list', strict: true, schema: { type: 'object', properties: { items: { type: 'array', items: { type: 'object', properties: { title: { type: 'string' }, priority: { type: 'string', enum: ['low', 'medium', 'high'] } }, required: ['title', 'priority'], additionalProperties: false } } }, required: ['items'], additionalProperties: false } } } }); console.log(result.content); ``` HOSTED REST CHAT: ```javascript const hosted = await sogni.chat.hosted.create({ model: 'qwen3.6-35b-a3b-gguf-iq4xs', messages: [{ role: 'user', content: 'Write one concise product caption.' }], think: false, tokenType: 'spark' }); console.log(hosted.choices[0].message.content); ``` DURABLE CHAT RUNS: ```javascript const run = await sogni.chat.runs.create({ model: 'qwen3.6-35b-a3b-gguf-iq4xs', messages: [{ role: 'user', content: 'Plan a 3-shot product video.' }], tokenType: 'spark', sessionId: 'session-123', idempotencyKey: 'message-123' }); for await (const event of sogni.chat.runs.streamEvents(run.runId)) { console.log(event.type, event.payload); } ``` Durable chat runs use uploaded HTTP(S) URLs for media references so run state, event replay, and recovery can resolve the same media after the initial request. Socket-native and hosted non-durable vision chat can accept inline image data URIs after SDK validation. LLM CHAT PARAMETERS: | Parameter | Type | Default | Notes | |-----------|------|---------|-------| | model | string | qwen3.6-35b-a3b-gguf-iq4xs | LLM model ID | | messages | array | - | Chat messages [{role, content}] | | max_tokens | number | 4096 | Maximum output tokens | | temperature | number | 0.7 | Sampling temperature (0-2) | | top_p | number | 0.9 | Nucleus sampling (0-1) | | top_k | number | model default | Top-k sampling | | min_p | number | model default | Minimum probability sampling | | repetition_penalty | number | model default | Repetition penalty | | frequency_penalty | number | 0 | Repetition penalty (-2 to 2) | | presence_penalty | number | 0 | Topic freshness penalty (-2 to 2) | | stream | boolean | false | Enable token-by-token streaming | | tools | array | - | Tool definitions for function calling | | tool_choice | string/object | auto | Tool selection: 'auto', 'none', 'required', or specific function | | sogni_tools | boolean/string | - | Inject hosted Sogni creative tools | | sogni_tool_execution | boolean | false | Ask server to execute eligible hosted tools | | autoExecuteTools | boolean | false | Client-side non-streaming Sogni tool loop | | think | boolean | server default | Per-request thinking control | | taskProfile | string | - | 'general', 'coding', or 'reasoning' preset hint | | response_format | object | - | OpenAI-compatible text/json_object/json_schema constraint | MESSAGE ROLES: - 'system': System instructions (first message) - 'user': User input - 'assistant': Model responses (and tool call requests) - 'tool': Tool execution results (with tool_call_id) CHAT COMPLETION RESULT SHAPE: ```typescript interface ChatCompletionResult { jobID: string; content: string; role: string; finishReason: string; usage: { prompt_tokens: number; completion_tokens: number; total_tokens?: number }; timeTaken: number; workerName?: string; cost?: LLMJobCost; tool_calls?: ToolCall[]; toolHistory?: ToolHistoryEntry[]; } ``` ================================================================================ 10. LLM TOOL CALLING & SOGNI PLATFORM TOOLS ================================================================================ TOOL CALLING (Function Calling): Define custom tools the LLM can invoke during conversations. The LLM decides when to use a tool, returns structured arguments, and you execute the function locally before feeding results back for a natural language answer. DEFINING TOOLS (OpenAI-compatible format): ```javascript const tools = [ { type: 'function', function: { name: 'get_weather', description: 'Get current weather for a location', parameters: { type: 'object', properties: { location: { type: 'string', description: 'City name or location' } }, required: ['location'] } } }, { type: 'function', function: { name: 'calculate', description: 'Evaluate a math expression', parameters: { type: 'object', properties: { expression: { type: 'string', description: 'Math expression to evaluate' } }, required: ['expression'] } } } ]; ``` TOOL CALLING FLOW: ```javascript // 1. Send message with tools const messages = [{ role: 'user', content: "What's the weather in Austin, TX?" }]; const response = await sogni.chat.completions.create({ model: 'qwen3.6-35b-a3b-gguf-iq4xs', messages, tools, tool_choice: 'auto' }); // 2. Check if LLM wants to call a tool if (response.tool_calls?.length) { messages.push({ role: 'assistant', content: response.content || null, tool_calls: response.tool_calls }); for (const toolCall of response.tool_calls) { const args = JSON.parse(toolCall.function.arguments); // 3. Execute the tool locally const result = await executeMyTool(toolCall.function.name, args); // 4. Feed result back messages.push({ role: 'tool', tool_call_id: toolCall.id, name: toolCall.function.name, content: JSON.stringify(result) }); } // 5. Get final natural language response const finalResponse = await sogni.chat.completions.create({ model: 'qwen3.6-35b-a3b-gguf-iq4xs', messages, tools }); console.log(finalResponse.content); } ``` MULTI-ROUND TOOL CALLING: The LLM may call multiple tools in sequence (e.g., get weather for two cities). Implement a loop that continues until the LLM returns a content response without tool calls, typically up to 5 rounds. SOGNI PLATFORM TOOLS — MEDIA GENERATION VIA CHAT: Combine LLM intelligence with Sogni's media generation capabilities. The LLM detects when a user wants to create media, enhances the prompt, and calls Sogni's generation APIs automatically: - Image Generation: "Create an image of a cyberpunk city at night" - Image Editing / Reference-Guided Images: "Edit this portrait to look like a renaissance painting" - Video Generation: "Generate a video of ocean waves crashing at sunset" - Sound-to-Video: "Turn this song into a music video" - Video-to-Video: "Restyle this video as anime" - Music Generation: "Compose a jazz song about the rain" CANONICAL HOSTED CREATIVE-TOOL SURFACE (`SogniTools.all`, 24 tools): The full hosted surface executes server-side via `sogni.chat.hosted.create()` / `sogni.chat.runs.create()`. The default `creative-tools` value of `sogni_tools` injects this surface server-side; `sogni_tools: "creative-agent"` adds workflow control and asset-manifest tools on top. The client-side `sogni.chat.tools.execute()` path directly dispatches only the core generation tools (`generate_image`, `edit_image`, `generate_video`, `sound_to_video`, `video_to_video`, `generate_music`); composition and post-production tools should be routed through hosted chat or durable runs. - `generate_image`, `edit_image`, `generate_video`, `generate_music`, `sound_to_video`, `video_to_video` — core media-generation tools with creative-agent naming. - `restore_photo`, `apply_style`, `refine_result`, `change_angle` — image-edit adapters backed by the shared image-edit workflow. - `animate_photo` — image-to-video, with multi-source fan-out via `sourceImageIndices`. Fan-out (>1 source image) is composed into one MP4 by default; opt out with `stitched: false` for a flat clip list. - `stitch_video` — concatenate selected video clips (with optional audio overlay via `audioIndex`) into one MP4. - `orbit_video` — generate orbit clips around a subject and stitch them into one MP4. - `dance_montage` — generate dance clips and stitch when multi-clip. - `extend_video` — append new content to an existing video while preserving the original portion. - `replace_video_segment` — replace a bounded window inside an existing video. Replacement sources can use `replacementStartSeconds` / `replacementEndSeconds` to splice a trimmed source slice. - `overlay_video` — burn static text or image overlays onto an existing video. - `add_subtitles` — burn subtitle cues onto an existing video. - `enhance_prompt` — model-ready image/video/music/edit prompt expansion. - `compose_script` — scripts, storyboards, trailers, social shorts, campaign beats, and video prompts. - `compose_lyrics`, `compose_instrumental` — vocal lyrics or instrumental music structures. - `compose_workflow`, `compose_workflow_template` — durable workflow and workflow-template planners. PER-REQUEST MEDIA CONTEXT: Generated images, videos, and audio are addressable by stable indices across tool rounds. Every hosted Sogni tool result returns `startIndex` and `indices` in its envelope so a later tool can target the result with `sourceImageIndex`, `videoIndices`, `audioIndex`, etc., without the model having to copy URLs back into prompt text. COMPOSITION TOOLS: `stitch_video`, `orbit_video`, `dance_montage`, and `animate_photo` fan-out return a single composed MP4 URL. Per-clip source URLs are preserved on the result envelope for inspection. MEDIA-CONDITIONED TOOL INPUTS: - `source_image_url`, `reference_image_urls` - `reference_image_url`, `reference_image_end_url` - `reference_audio_url`, `reference_audio_identity_url` - `reference_video_url` These direct media arguments use inline base64-encoded `data:` URIs. Tool image inputs accept PNG/JPEG, tool audio inputs accept MP3/M4A/WAV, and tool video inputs accept MP4 or MOV/QuickTime. For uploaded or Sogni-hosted HTTP(S) assets, pass media through request-level `mediaReferences` / `mediaContext` or through `sogni.workflows` dependencies. DEFAULT GENERATION MODELS (used by the canonical generation tools): | Tool | Model ID | Description | |------|----------|-------------| | `generate_image` | z_image_turbo_bf16 | Z-Image Turbo, ultra-fast 8-step generation | | `edit_image` | workflow/model-dependent | Reference-guided image editing with edit-capable Qwen/Flux models | | `generate_video` | ltx23-22b-fp8_t2v_distilled / ltx23-22b-fp8_i2v_distilled / Seedance selectors | Text-to-video or image-to-video | | `sound_to_video` | ltx23-22b-fp8_a2v_distilled / ltx23-22b-fp8_ia2v_distilled | Audio-driven video generation | | `video_to_video` | ltx23-22b-fp8_v2v_distilled / seedance-2-0 / WAN animate models | Video transformation / motion transfer | | `generate_music` | ace_step_1.5_turbo | ACE-Step 1.5 Turbo, fast music generation | PLATFORM TOOL WORKFLOW: 1. User sends natural language request (e.g., "Make me an image of a dragon") 2. LLM detects media generation intent 3. LLM enhances the prompt for optimal output quality 4. LLM calls the appropriate Sogni generation tool with structured parameters 5. Your code executes the Sogni project creation (image/video/audio) 6. Result URL is returned and opened automatically See `workflow_text_chat_sogni_tools.mjs` for a composition-pipeline example covering the core image/video/music flows. See `workflow_creative_agent_tools.mjs` for server-side hosted Sogni tool injection with `sogni_tools`. Pass `SogniTools.all` (or individual tool defs) to the LLM via `tools` and execute calls through `sogni.chat.hosted.create()` / `sogni.chat.runs.create()`. DURABLE CREATIVE WORKFLOWS: Use `sogni.workflows` for `/v1/creative-agent/workflows` coverage: `start`, `list`, `get`, `events`, `streamEvents`, `resume`, `reseed`, `cancel`. `start({ input })` runs an inline plan; `start({ workflowId, inputs })` runs a saved template by id. Saved templates are managed through `sogni.workflows.templates` — `list`, `get`, `create`, `update`, `delete`, `fork`. `resume(workflowId)` releases a workflow paused in `waiting_for_user`; `reseed(workflowId, { seedOverrides })` clones a completed run with new seeds. These endpoints use the SDK's active auth. See `workflow_creative_agent_workflows.mjs`. EXAMPLE CLI USAGE: ```bash # Generate an image through natural language node workflow_text_chat_sogni_tools.mjs "Create an image of a cyberpunk city" # Generate a video through natural language node workflow_text_chat_sogni_tools.mjs "Generate a video of ocean waves at sunset" # Generate music through natural language node workflow_text_chat_sogni_tools.mjs "Compose a jazz song about the rain" # Generate multiple items node workflow_text_chat_sogni_tools.mjs -n 4 "Create images of fantasy landscapes" # Server-side hosted creative tools node workflow_creative_agent_tools.mjs "Create an orbit video plan for a crystal perfume bottle" # Durable creative-agent workflow node workflow_creative_agent_workflows.mjs "A chrome monorail over neon gardens" --watch # Tool calling with external tools (weather, time, math, conversions) node workflow_text_chat_tool_calling.mjs "What's the weather in Austin, TX?" ``` ================================================================================ 11. VISION CHAT (MULTIMODAL IMAGE UNDERSTANDING) ================================================================================ The Sogni SDK supports multimodal vision chat via VLM (Vision-Language Model) workers on the Sogni network. Send images alongside text messages for scene description, OCR/text extraction, object detection, structured visual analysis, and multi-image comparison. VLM MODEL: | Model ID | Name | Description | |----------|------|-------------| | qwen3.6-35b-a3b-gguf-iq4xs | Qwen3.6 35B VLM | Vision-language model with 262,144 native context length | MULTIMODAL MESSAGE FORMAT: Images are sent as base64-encoded JPEG or PNG data URIs using the OpenAI-compatible `image_url` content type within a multipart user message: ```javascript // Build a multimodal user message with image + text const messages = [ { role: 'system', content: 'You are a visual analysis assistant.' }, { role: 'user', content: [ { type: 'image_url', image_url: { url: 'data:image/jpeg;base64,...' } }, { type: 'text', text: 'Describe this image in detail.' } ] } ]; const stream = await sogni.chat.completions.create({ model: 'qwen3.6-35b-a3b-gguf-iq4xs', messages, max_tokens: 4096, stream: true, think: false, taskProfile: 'general' }); for await (const chunk of stream) { if (chunk.content) process.stdout.write(chunk.content); } ``` QWEN3.6 PRESET SELECTION: - `think: true, taskProfile: 'general'` -> thinking mode for general tasks - `think: true, taskProfile: 'coding'` -> thinking mode for precise coding - `think: false, taskProfile: 'general'` -> instruct / non-thinking general - `think: false, taskProfile: 'reasoning'` -> instruct / non-thinking reasoning MANUAL OVERRIDES: You can override the preset with explicit sampling params: `temperature`, `top_p`, `top_k`, `min_p`, `presence_penalty`, `repetition_penalty`. MULTI-IMAGE COMPARISON: Send two images in the same message for side-by-side analysis: ```javascript const userMessage = { role: 'user', content: [ { type: 'image_url', image_url: { url: imageDataUri1 } }, { type: 'image_url', image_url: { url: imageDataUri2 } }, { type: 'text', text: 'Compare these two images in detail.' } ] }; ``` LOADING LOCAL IMAGES: ```javascript import * as fs from 'node:fs'; import * as path from 'node:path'; const buffer = fs.readFileSync('./photo.jpg'); const base64 = buffer.toString('base64'); const dataUri = `data:image/jpeg;base64,${base64}`; ``` VISION INPUT LIMITS: JPEG or PNG only, max 20 images per request, max 10MB per image, longest side capped at 1024px. This 1024px dimension cap applies only to vision `image_url` inputs, not to media-generation tool image inputs. VISION CAPABILITIES: - Scene description: Main subject, background, colors, lighting, mood, spatial relationships, composition, and visible text - OCR / Text extraction: All visible text with approximate location and layout preservation, multi-language identification - Object detection: Object identification with location (top-left, center, etc.), relative size, visual attributes, and spatial relationships - Structured analysis: Subject, composition, lighting, color palette, technical aspects, mood, artistic style, and contextual elements - Multi-image comparison: Side-by-side analysis of subject matter, color palette, composition, mood, quality, and notable differences EXAMPLE CLI USAGE: ```bash # Interactive vision chat node workflow_text_chat_vision.mjs # Pre-load an image node workflow_text_chat_vision.mjs --image photo.jpg # In-chat commands: /describe, /ocr, /objects, /analyze, /compare ``` See `workflow_text_chat_vision.mjs` for a complete interactive vision chat implementation with all commands and multi-turn conversation support. ================================================================================ 12. COMPLETE PARAMETER REFERENCE ================================================================================ BASE PARAMETERS (Both Image and Video): ```typescript { modelId: string; // Required - model identifier numberOfMedia: number; // Required - how many to generate positivePrompt: string; // Required - what to create negativePrompt?: string; // What to avoid stylePrompt?: string; // Style description steps?: number; // Inference steps guidance?: number; // Guidance scale network?: 'fast' | 'relaxed'; seed?: number; // Reproducibility seed tokenType?: 'sogni' | 'spark'; disableNSFWFilter?: boolean; loras?: string[]; // LoRA IDs loraStrengths?: number[]; // LoRA weights (0-2) } ``` IMAGE-SPECIFIC PARAMETERS: ```typescript { type: 'image'; sizePreset?: string; // e.g., 'square_hd', 'portrait_7_9' width?: number; // If sizePreset is 'custom' height?: number; // If sizePreset is 'custom' sampler?: string; // Model-specific scheduler?: string; // Model-specific numberOfPreviews?: number; // Preview images during generation startingImage?: File | Buffer | Blob; startingImageStrength?: number; // 0-1 contextImages?: (File | Buffer | Blob)[]; controlNet?: ControlNetParams; outputFormat?: 'png' | 'jpg' | 'webp'; } ``` VIDEO-SPECIFIC PARAMETERS: ```typescript { type: 'video'; duration?: number; // Seconds fps?: number; // Model-dependent behavior! shift?: number; // Motion intensity (1.0-8.0) teacacheThreshold?: number;// Speedup (0.0-1.0) width?: number; height?: number; sampler?: string; scheduler?: string; referenceImage?: File | Buffer | Blob; referenceImageEnd?: File | Buffer | Blob; referenceAudio?: File | Buffer | Blob; referenceVideo?: File | Buffer | Blob; audioStart?: number; // Seconds into audio audioDuration?: number; // Seconds of audio videoStart?: number; // Seconds into video firstFrameStrength?: number; // LTX-2.3 only (0-1) lastFrameStrength?: number; // LTX-2.3 only (0-1) trimEndFrame?: boolean; controlNet?: VideoControlNetParams; // LTX-2.3 only outputFormat?: 'mp4'; } ``` AUDIO-SPECIFIC PARAMETERS: ```typescript { type: 'audio'; duration?: number; // 10-600 seconds bpm?: number; // 30-300 beats per minute keyscale?: string; // e.g., 'C major', 'A minor' timesignature?: string; // '2', '3', '4', or '6' lyrics?: string; // Song lyrics (omit for instrumental) language?: string; // Language code (default: 'en') composerMode?: boolean; // AI composer mode (default: true) promptStrength?: number; // 0-10, prompt adherence creativity?: number; // 0-2, composition temperature shift?: number; // 1-5, denoising distribution sampler?: string; // Model-specific scheduler?: string; // Model-specific outputFormat?: 'mp3' | 'wav' | 'flac'; } ``` ================================================================================ 13. EVENTS & PROGRESS TRACKING ================================================================================ PROMISE-BASED COMPLETION: ```javascript const project = await sogni.projects.create({ ... }); const urls = await project.waitForCompletion(); // urls is string[] of result URLs ``` PROJECT EVENTS: ```javascript project.on('progress', (percent) => { console.log(`Overall: ${percent}%`); }); project.on('jobStarted', (job) => { console.log(`Job ${job.id} started on ${job.workerName}`); }); project.on('jobCompleted', (job) => { console.log(`Job ${job.id} done:`, job.resultUrl); }); project.on('jobFailed', (job) => { console.log(`Job ${job.id} failed:`, job.error); }); project.on('completed', (urls) => { console.log('All done:', urls); }); project.on('failed', (error) => { console.error('Project failed:', error.message); }); ``` JOB EVENTS: ```javascript const job = project.jobs[0]; job.on('progress', ({ step, stepCount, progress }) => { console.log(`Step ${step}/${stepCount} (${progress}%)`); }); job.on('preview', (previewUrl) => { console.log('Preview available:', previewUrl); }); job.on('completed', () => { console.log('Result:', job.resultUrl); }); job.on('failed', (error) => { console.error('Job failed:', error); }); ``` External API-backed jobs may not report diffusion steps. The SDK keeps project/job progress finite by using provider progress or ETA-derived progress, and direct provider result URLs are preserved on `job.resultUrl` / `job.getResultUrl()`. PROJECT PROPERTIES: ```javascript project.id; // string project.status; // 'pending' | 'queued' | 'processing' | 'completed' | 'failed' | 'canceled' project.progress; // number (0-100) project.queuePosition; // number | null project.eta; // number | null (seconds) project.jobs; // Job[] project.resultUrls; // string[] (after completion) ``` JOB PROPERTIES: ```javascript job.id; // string job.status; // 'pending' | 'initiating' | 'processing' | 'completed' | 'failed' | 'canceled' job.progress; // number (0-100) job.step; // number (current step) job.stepCount; // number (total steps) job.seed; // number job.previewUrl; // string | null job.resultUrl; // string | null job.hasResultMedia; // boolean job.isNSFW; // boolean job.workerName; // string job.eta; // string | null job.etaSeconds; // number | null job.type; // 'image' | 'video' ``` FETCHING RESULTS: ```javascript // Get signed URL (valid ~1 hour) const signedUrl = await job.getResultUrl(); // Download as blob const blob = await job.getResultData(); ``` ================================================================================ 14. MODELS, PRESETS & OPTIONS ================================================================================ WAIT FOR MODELS: ```javascript const models = await sogni.projects.waitForModels(); // Returns AvailableModel[] ``` GET AVAILABLE MODELS: ```javascript const models = sogni.projects.availableModels; // or const models = await sogni.projects.getAvailableModels('fast'); // Returns: { id, name, workerCount, media: 'image' | 'video' }[] ``` GET ALL SUPPORTED MODELS: ```javascript const allModels = await sogni.projects.getSupportedModels(); // Returns full model list with tiers ``` GET SIZE PRESETS: ```javascript const presets = await sogni.projects.getSizePresets('fast', 'flux1-schnell-fp8'); /* Returns: [ { id: 'square', label: 'Square', width: 512, height: 512, ratio: '1:1' }, { id: 'square_hd', label: 'Square HD', width: 1024, height: 1024, ratio: '1:1' }, { id: 'portrait_7_9', label: 'Portrait: Standard', width: 896, height: 1152, ratio: '7:9' }, { id: 'landscape_7_4', label: 'Landscape: Widescreen', width: 1344, height: 768, ratio: '7:4' }, ... ] */ ``` GET SAMPLER/SCHEDULER OPTIONS: ```javascript const options = await sogni.projects.getModelOptions('flux1-schnell-fp8'); /* Returns: { sampler: { allowed: ['euler', 'euler_a', 'dpm_pp_2m', ...], default: 'euler' }, scheduler: { allowed: ['simple', 'karras', 'linear', ...], default: 'simple' } } */ ``` ================================================================================ 15. COST ESTIMATION ================================================================================ ESTIMATE IMAGE COST: ```javascript const cost = await sogni.projects.estimateCost({ network: 'fast', tokenType: 'sogni', model: 'flux1-schnell-fp8', imageCount: 4, stepCount: 4, previewCount: 0, sizePreset: 'square_hd' }); console.log(cost.sogni); // Cost in Sogni tokens console.log(cost.spark); // Cost in Spark tokens console.log(cost.usd); // Cost in USD ``` ESTIMATE VIDEO COST: ```javascript const cost = await sogni.projects.estimateVideoCost({ tokenType: 'sogni', model: 'wan_v2.2-14b-fp8_t2v_lightx2v', width: 512, height: 512, duration: 5, fps: 16, steps: 4, numberOfMedia: 1 }); ``` CHECK BALANCE: ```javascript await sogni.account.refreshBalance(); const balance = sogni.account.currentAccount.balance; console.log(balance.sogni, balance.spark); ``` ================================================================================ 16. ERROR HANDLING ================================================================================ TRY-CATCH PATTERN: ```javascript try { const project = await sogni.projects.create({ ... }); const urls = await project.waitForCompletion(); } catch (error) { if (error.code) { // API error with code console.error(`Error ${error.code}: ${error.message}`); } else { // Network or other error console.error(error.message); } } ``` EVENT-BASED ERROR HANDLING: ```javascript project.on('failed', (error) => { console.error('Project failed:', error.code, error.message); }); project.on('jobFailed', (job) => { console.error('Job failed:', job.error); }); ``` CANCEL A PROJECT: ```javascript await sogni.projects.cancel(project.id); // or await project.cancel(); ``` COMMON ERROR SCENARIOS: - Insufficient balance - Invalid model ID - Missing required parameters (e.g., referenceImage for i2v) - Network unavailable - NSFW content detected (if filter enabled) - Invalid dimensions or parameters ================================================================================ 17. ADVANCED PATTERNS ================================================================================ BATCH PROCESSING: ```javascript const images = ['image1.jpg', 'image2.jpg', 'image3.jpg']; const projects = []; for (const img of images) { const project = await sogni.projects.create({ type: 'video', network: 'fast', modelId: 'wan_v2.2-14b-fp8_i2v_lightx2v', referenceImage: fs.readFileSync(img), positivePrompt: 'camera slowly zooms in', numberOfMedia: 1, duration: 5, fps: 16 }); projects.push(project); } const results = await Promise.all(projects.map((p) => p.waitForCompletion())); ``` IMAGE ENHANCEMENT: ```javascript // After a job completes, enhance it const enhancedProject = await job.enhance('medium', { // Optional overrides steps: 30 }); const enhancedUrls = await enhancedProject.waitForCompletion(); ``` TOKEN MANAGEMENT: ```javascript // Use Spark tokens instead of Sogni const project = await sogni.projects.create({ type: 'image', tokenType: 'spark' // ... other params }); ``` USING LORAS: ```javascript const project = await sogni.projects.create({ type: 'image', modelId: 'flux1-schnell-fp8', positivePrompt: 'Portrait from multiple angles', loras: ['multiple_angles'], loraStrengths: [0.9], numberOfMedia: 1 }); ``` ================================================================================ 18. TYPE DEFINITIONS ================================================================================ PROJECT PARAMS: ```typescript type ProjectParams = ImageProjectParams | VideoProjectParams; interface BaseProjectParams { modelId: string; numberOfMedia: number; positivePrompt: string; negativePrompt?: string; stylePrompt?: string; steps?: number; guidance?: number; network?: 'fast' | 'relaxed'; disableNSFWFilter?: boolean; seed?: number; tokenType?: 'sogni' | 'spark'; loras?: string[]; loraStrengths?: number[]; } interface ImageProjectParams extends BaseProjectParams { type: 'image'; numberOfPreviews?: number; startingImage?: File | Buffer | Blob; startingImageStrength?: number; contextImages?: (File | Buffer | Blob)[]; sampler?: string; scheduler?: string; sizePreset?: string | 'custom'; width?: number; height?: number; controlNet?: ControlNetParams; outputFormat?: 'png' | 'jpg' | 'webp'; } interface VideoProjectParams extends BaseProjectParams { type: 'video'; duration?: number; fps?: number; shift?: number; teacacheThreshold?: number; referenceImage?: File | Buffer | Blob; referenceImageEnd?: File | Buffer | Blob; referenceAudio?: File | Buffer | Blob; referenceVideo?: File | Buffer | Blob; audioStart?: number; audioDuration?: number; videoStart?: number; trimEndFrame?: boolean; width?: number; height?: number; sampler?: string; scheduler?: string; firstFrameStrength?: number; lastFrameStrength?: number; outputFormat?: 'mp4'; controlNet?: VideoControlNetParams; } ``` CONTROLNET TYPES: ```typescript type ControlNetName = | 'canny' | 'depth' | 'inpaint' | 'instrp2p' | 'lineart' | 'lineartanime' | 'mlsd' | 'normalbae' | 'openpose' | 'scribble' | 'segmentation' | 'shuffle' | 'softedge' | 'tile' | 'instantid'; type ControlNetMode = 'balanced' | 'prompt_priority' | 'cn_priority'; interface ControlNetParams { name: ControlNetName; image?: File | Buffer | Blob; strength?: number; mode?: ControlNetMode; guidanceStart?: number; guidanceEnd?: number; } type VideoControlNetName = 'canny' | 'pose' | 'depth' | 'detailer'; interface VideoControlNetParams { name: VideoControlNetName; strength?: number; } ``` MODEL TYPES: ```typescript interface AvailableModel { id: string; name: string; workerCount: number; media: 'image' | 'video'; } interface SupportedModel extends AvailableModel { SID: number; tier: string; } interface SizePreset { id: string; label: string; width: number; height: number; ratio: string; aspect: string; } ``` STATUS TYPES: ```typescript type ProjectStatus = 'pending' | 'queued' | 'processing' | 'completed' | 'failed' | 'canceled'; type JobStatus = 'pending' | 'initiating' | 'processing' | 'completed' | 'failed' | 'canceled'; ``` ERROR TYPE: ```typescript interface ErrorData { code: number; message: string; } ``` ================================================================================ END OF DOCUMENT ================================================================================ For additional resources: - Examples: https://github.com/Sogni-AI/sogni-client/tree/main/examples - API Docs: https://sdk-docs.sogni.ai - Support: https://www.sogni.ai/support