# Civitai API Documentation

This document provides comprehensive documentation for the Civitai API
integration in the Oshun platform.

## Overview

The Civitai integration provides access to the Civitai ecosystem for:

- **Image Generation**: Text-to-image with SD1.5, SDXL, Flux, and Pony models
- **Video Generation**: 10 video models including Vidu, Veo3, Hunyuan, and Wan
- **Model Discovery**: Search and browse the Civitai model library
- **LoRA Training**: Train custom LoRAs for image and video generation
- **Model Downloads**: Queue and manage model downloads

## Authentication

### API Key Setup

```typescript
import { CivitaiProvider } from '@oshun/civitai-provider';

const provider = new CivitaiProvider({
  apiKey: process.env.CIVITAI_API_KEY,
});
```

### Environment Variables

| Variable                           | Description                           | Required |
| ---------------------------------- | ------------------------------------- | -------- |
| `CIVITAI_API_KEY`                  | Civitai API key for authentication    | Yes      |
| `CIVITAI_LINK_ENDPOINT`            | WebSocket endpoint for Civitai Link   | No       |
| `CIVITAI_LINK_KEY`                 | Civitai Link authentication key       | No       |
| `CIVITAI_MAX_CONCURRENT_DOWNLOADS` | Max concurrent downloads (default: 3) | No       |
| `CIVITAI_PRELOAD_ENABLED`          | Enable predictive model loading       | No       |

### Factory Functions

```typescript
// Create provider with configuration
const provider = createCivitaiProvider('your-api-key', {
  baseUrl: 'https://civitai.com/api',
  timeoutMs: 300000,
  enableCostTracking: true,
});

// Create from environment
const provider = createCivitaiProviderFromEnv();

// Specialized providers
const imageProvider = createCivitaiImageProvider('your-api-key');
const videoProvider = createCivitaiVideoProvider('your-api-key');
```

## AIR URN System

Civitai uses the AIR (Artificial Intelligence Resource) URN format to reference
models consistently.

### URN Format

```
urn:air:{ecosystem}:{type}:{source}:{id}@{version}.{format}
```

| Component   | Description            | Example Values                                                    |
| ----------- | ---------------------- | ----------------------------------------------------------------- |
| `ecosystem` | AI ecosystem           | `sd1`, `sd2`, `sdxl`, `flux`, `pony`, `video`                     |
| `type`      | Resource type          | `checkpoint`, `lora`, `lycoris`, `embedding`, `vae`, `controlnet` |
| `source`    | Model source           | `civitai`, `huggingface`                                          |
| `id`        | Model ID               | Numeric ID                                                        |
| `version`   | Version ID (optional)  | Numeric ID                                                        |
| `format`    | File format (optional) | `safetensor`, `ckpt`, `diffuser`                                  |

### URN Examples

```typescript
// Popular SDXL checkpoint
const juggernautXL = 'urn:air:sdxl:checkpoint:civitai:133005@348913';

// SD 1.5 checkpoint
const realisticVision = 'urn:air:sd1:checkpoint:civitai:4201@130072';

// Flux checkpoint
const fluxDev = 'urn:air:flux:checkpoint:civitai:618692@691639';

// LoRA
const styleLora = 'urn:air:sdxl:lora:civitai:123456@789012';
```

### Parsing and Building URNs

```typescript
import { parseAIRURN, buildAIRURN } from '@oshun/civitai-provider';

// Parse URN string
const urn = parseAIRURN('urn:air:sdxl:checkpoint:civitai:133005@348913');
console.log(urn);
// {
//   ecosystem: 'sdxl',
//   type: 'checkpoint',
//   source: 'civitai',
//   id: 133005,
//   version: 348913
// }

// Build URN from components
const urnString = buildAIRURN({
  ecosystem: 'sdxl',
  type: 'lora',
  source: 'civitai',
  id: 123456,
  version: 789012,
  format: 'safetensor',
});
// 'urn:air:sdxl:lora:civitai:123456@789012.safetensor'
```

## Image Generation

### Basic Generation

```typescript
const job = await provider.generateImage({
  model: 'urn:air:sdxl:checkpoint:civitai:133005@348913',
  params: {
    prompt: 'A majestic dragon flying over a castle at sunset',
    negativePrompt: 'blurry, low quality, artifacts',
    scheduler: 'EulerA',
    steps: 20,
    cfgScale: 7,
    width: 1024,
    height: 1024,
    seed: 12345,
    clipSkip: 1,
  },
  batchSize: 4,
  callbackUrl: 'https://api.myapp.com/webhooks/civitai',
});

console.log('Job ID:', job.jobId);
console.log('Cost:', job.cost, 'Buzz');
```

### Quality Presets

```typescript
// Fast generation
const fastJob = await provider.generateImageWithPreset(
  'urn:air:sdxl:checkpoint:civitai:133005@348913',
  'A beautiful landscape',
  'fast' // 12 steps, EulerA, CFG 4
);

// Balanced quality
const balancedJob = await provider.generateImageWithPreset(
  'urn:air:sdxl:checkpoint:civitai:133005@348913',
  'A beautiful landscape',
  'balanced' // 20 steps, EulerA, CFG 6
);

// High quality
const qualityJob = await provider.generateImageWithPreset(
  'urn:air:sdxl:checkpoint:civitai:133005@348913',
  'A beautiful landscape',
  'quality' // 30 steps, DPM2MKarras, CFG 7
);

// Maximum quality
const highQualityJob = await provider.generateImageWithPreset(
  'urn:air:sdxl:checkpoint:civitai:133005@348913',
  'A beautiful landscape',
  'highQuality' // 50 steps, DPM2MKarras, CFG 7
);
```

### Preset Configuration Reference

| Preset        | Scheduler   | Steps | CFG Scale |
| ------------- | ----------- | ----- | --------- |
| `fast`        | EulerA      | 12    | 4         |
| `balanced`    | EulerA      | 20    | 6         |
| `quality`     | DPM2MKarras | 30    | 7         |
| `highQuality` | DPM2MKarras | 50    | 7         |

### Using Additional Networks

```typescript
const job = await provider.generateImage({
  model: 'urn:air:sdxl:checkpoint:civitai:133005@348913',
  params: {
    prompt: 'myperson, portrait, high quality',
    width: 1024,
    height: 1024,
  },
  additionalNetworks: [
    {
      urn: 'urn:air:sdxl:lora:civitai:123456@789012',
      strength: 0.8,
      triggerWord: 'myperson',
    },
    {
      urn: 'urn:air:sdxl:embedding:civitai:98765',
      strength: 0.5,
    },
  ],
});
```

### Using ControlNet

```typescript
const job = await provider.generateImage({
  model: 'urn:air:sdxl:checkpoint:civitai:133005@348913',
  params: {
    prompt: 'A woman standing',
    width: 1024,
    height: 1024,
  },
  controlNets: [
    {
      preprocessor: 'openpose',
      model: 'urn:air:sdxl:controlnet:civitai:111222',
      weight: 1.0,
      startStep: 0,
      endStep: 0.8,
      image: 'https://example.com/pose-reference.png',
    },
  ],
});
```

### Schedulers

| Scheduler      | Description        | Best For              |
| -------------- | ------------------ | --------------------- |
| `EulerA`       | Euler ancestral    | Fast, general purpose |
| `Euler`        | Euler              | Consistent results    |
| `DPM2M`        | DPM++ 2M           | Balanced quality      |
| `DPM2MKarras`  | DPM++ 2M Karras    | High quality          |
| `DPMSDEKarras` | DPM++ SDE Karras   | Best quality, slower  |
| `DDIM`         | DDIM               | Inpainting            |
| `UniPC`        | UniPC              | Fast convergence      |
| `LCM`          | Latent Consistency | Very fast (4-8 steps) |

## Video Generation

### Supported Video Models

| Model     | Name              | Max Duration | LoRA | Image-to-Video |
| --------- | ----------------- | ------------ | ---- | -------------- |
| `vidu-q1` | Vidu Q1           | 8s           | No   | Yes            |
| `veo3`    | Google Veo3       | 10s          | No   | Yes            |
| `hailuo`  | Hailuo (MiniMax)  | 6s           | No   | Yes            |
| `kling`   | Kling             | 5s           | No   | Yes            |
| `ltxv`    | Lightricks LTXV   | 4s           | No   | No             |
| `hunyuan` | Hunyuan (Tencent) | 8s           | Yes  | Yes            |
| `wan-2.1` | Wan 2.1 (Alibaba) | 8s           | Yes  | Yes            |
| `wan-2.2` | Wan 2.2 (Alibaba) | 8s           | Yes  | Yes            |
| `mochi`   | Mochi             | 5s           | No   | No             |
| `haiper`  | Haiper            | 4s           | No   | Yes            |

### Basic Video Generation

```typescript
const job = await provider.generateVideo({
  model: 'wan-2.1',
  params: {
    prompt: 'A person walking through a field of flowers',
    negativePrompt: 'blurry, distorted',
    duration: 4,
    width: 1280,
    height: 720,
    quality: 'standard',
    movement: 'medium',
    enhancePrompt: true,
    seed: 12345,
  },
  callbackUrl: 'https://api.myapp.com/webhooks/video',
});
```

### Convenience Methods

```typescript
// Wan 2.1 video
const wanJob = await provider.generateWanVideo(
  'A beautiful sunset over the ocean',
  { duration: 6, quality: 'professional' },
  [{ urn: 'urn:air:video:lora:civitai:123456', strength: 0.8 }]
);

// Hunyuan video
const hunyuanJob = await provider.generateHunyuanVideo(
  'A cat playing with yarn',
  { duration: 4, movement: 'large' }
);

// Vidu video
const viduJob = await provider.generateViduVideo('Abstract flowing colors', {
  quality: 'professional',
});
```

### Image-to-Video

```typescript
const job = await provider.generateVideo({
  model: 'wan-2.1',
  params: {
    prompt: 'The scene comes to life with subtle movement',
    referenceImage: 'https://example.com/source-image.png',
    duration: 4,
    movement: 'small',
  },
});
```

### Video Quality Modes

| Mode           | Description      | Cost Multiplier |
| -------------- | ---------------- | --------------- |
| `draft`        | Fast preview     | 0.5x            |
| `standard`     | Balanced quality | 1.0x            |
| `professional` | Highest quality  | 1.5x            |

## Job Management

### Job Status Flow

```
queued → processing → completed
                   → failed
                   → cancelled
```

### Getting Job Status

```typescript
// Get job by ID
const job = provider.getJob('job-id');
console.log('Status:', job.status);
console.log('Cost:', job.cost);

// Get job status from API
const status = await provider.getJobStatus('job-id');
console.log('Availability:', status.availability);
console.log('Blob URL:', status.blobUrl);

// Get jobs by token
const jobs = await provider.getJobsByToken('token');
```

### Waiting for Completion

```typescript
// Wait for job with default timeout
const completedJob = await provider.waitForJob('job-id');
console.log('Result URL:', completedJob.result.blobUrl);

// Wait with custom timeout
const job = await provider.waitForJob('job-id', 60000); // 60 seconds

// Generate and wait
const result = await provider.generateImageAndWait({
  model: 'urn:air:sdxl:checkpoint:civitai:133005@348913',
  params: { prompt: 'A landscape' },
});
console.log('Image URL:', result.blobUrl);
```

### Cancelling Jobs

```typescript
await provider.cancelJob('job-id');
```

### Event Handling

```typescript
// Listen for job events
provider.on('job:submitted', ({ job }) => {
  console.log('Job submitted:', job.jobId);
});

provider.on('job:started', ({ jobId }) => {
  console.log('Job started:', jobId);
});

provider.on('job:completed', ({ job }) => {
  console.log('Job completed:', job.jobId, job.result?.blobUrl);
});

provider.on('job:failed', ({ jobId, error }) => {
  console.error('Job failed:', jobId, error);
});

provider.on('cost:recorded', ({ jobId, cost }) => {
  console.log('Cost recorded:', jobId, cost, 'Buzz');
});
```

## Model Discovery

### Searching Models

```typescript
const models = await provider.searchModels({
  query: 'realistic portrait',
  types: ['Checkpoint', 'LORA'],
  baseModels: ['SDXL 1.0'],
  tags: ['photorealistic'],
  sort: 'Highest Rated',
  page: 1,
  limit: 20,
  nsfw: false,
});

for (const model of models) {
  console.log(`${model.name} by ${model.creator.username}`);
  console.log(`Downloads: ${model.downloadCount}`);
  console.log(`Rating: ${model.rating} (${model.ratingCount} ratings)`);
}
```

### Getting Model Details

```typescript
// Get model by ID
const model = await provider.getModel(133005);
console.log('Name:', model.name);
console.log('Type:', model.type);
console.log('Versions:', model.versions.length);

// Get specific version
const version = await provider.getModelVersion(348913);
console.log('Version:', version.name);
console.log('Base Model:', version.baseModel);
console.log('Trained Words:', version.trainedWords);
```

### Building Model URN

```typescript
// Build URN from model and version
const urn = provider.buildModelURN(
  133005, // modelId
  348913, // versionId
  'sdxl', // ecosystem
  'checkpoint' // type
);
// 'urn:air:sdxl:checkpoint:civitai:133005@348913'
```

## Cost Estimation

### Image Generation Cost

```typescript
import { estimateImageCost } from '@oshun/civitai-provider';

// Estimate cost
const estimate = estimateImageCost(
  'sdxl', // ecosystem
  2, // number of LoRAs
  4, // batch size
  false // is draft mode
);

console.log('Base cost:', estimate.baseCost);
console.log('Network cost:', estimate.networkCost);
console.log('Total cost:', estimate.totalCost, 'Buzz');
console.log('Breakdown:', estimate.breakdown);
```

### Cost by Ecosystem

| Ecosystem | Base Cost | Draft Cost |
| --------- | --------- | ---------- |
| `sd1`     | 2 Buzz    | -          |
| `sd2`     | 2 Buzz    | -          |
| `sdxl`    | 5 Buzz    | 3 Buzz     |
| `flux`    | 8 Buzz    | -          |
| `pony`    | 4 Buzz    | -          |

### Video Generation Cost

```typescript
import { estimateVideoCost } from '@oshun/civitai-provider';

const estimate = estimateVideoCost(
  'wan-2.1', // model
  6, // duration in seconds
  'professional' // quality
);

console.log('Total cost:', estimate.totalCost, 'Buzz');
```

### Video Cost Per Second

| Model     | Base Cost/Second |
| --------- | ---------------- |
| `vidu-q1` | 15 Buzz          |
| `veo3`    | 25 Buzz          |
| `hailuo`  | 12 Buzz          |
| `kling`   | 18 Buzz          |
| `ltxv`    | 8 Buzz           |
| `hunyuan` | 10 Buzz          |
| `wan-2.1` | 10 Buzz          |
| `wan-2.2` | 12 Buzz          |
| `mochi`   | 8 Buzz           |
| `haiper`  | 10 Buzz          |

### Cost Tracking

```typescript
// Get total Buzz spent in session
const totalSpent = provider.getTotalBuzzSpent();
console.log('Total spent:', totalSpent, 'Buzz');

// Estimate before generating
const imageEst = provider.estimateImageCost(
  'urn:air:sdxl:checkpoint:civitai:133005@348913',
  2 // LoRA count
);

const videoEst = provider.estimateVideoCost(
  'wan-2.1',
  6, // duration
  'standard'
);
```

## Error Handling

### Error Codes

| Code                 | Description                | Retryable |
| -------------------- | -------------------------- | --------- |
| `AUTH_FAILED`        | Invalid API key            | No        |
| `RATE_LIMITED`       | Rate limit exceeded        | Yes       |
| `INSUFFICIENT_BUZZ`  | Not enough Buzz balance    | No        |
| `MODEL_NOT_FOUND`    | Model doesn't exist        | No        |
| `INVALID_PARAMETERS` | Invalid generation params  | No        |
| `JOB_NOT_FOUND`      | Job doesn't exist          | No        |
| `JOB_FAILED`         | Generation failed          | No        |
| `TIMEOUT`            | Request timed out          | Yes       |
| `NETWORK_ERROR`      | Network connectivity issue | Yes       |

### Error Handling Example

```typescript
import { CivitaiError } from '@oshun/civitai-provider';

try {
  const result = await provider.generateImageAndWait({
    model: modelUrn,
    params: { prompt: 'Test' },
  });
} catch (error) {
  if (error instanceof CivitaiError) {
    switch (error.code) {
      case 'RATE_LIMITED':
        console.log('Rate limited. Retry after:', error.details?.retryAfter);
        break;
      case 'INSUFFICIENT_BUZZ':
        console.log('Not enough Buzz. Please top up your account.');
        break;
      case 'MODEL_NOT_FOUND':
        console.log('Model not found:', error.details?.model);
        break;
      case 'TIMEOUT':
        console.log('Request timed out. Retrying...');
        break;
      default:
        console.error('Error:', error.message);
    }
  }
}
```

## Configuration Reference

### CivitaiConfig

```typescript
interface CivitaiConfig {
  /** API key (required) */
  apiKey: string;

  /** Base API URL */
  baseUrl?: string; // default: 'https://civitai.com/api'

  /** Request timeout in milliseconds */
  timeoutMs?: number; // default: 300000 (5 minutes)

  /** Enable cost tracking */
  enableCostTracking?: boolean; // default: true

  /** Default scheduler for image generation */
  defaultScheduler?: Scheduler; // default: 'EulerA'

  /** Default number of steps */
  defaultSteps?: number; // default: 20

  /** Default CFG scale */
  defaultCfgScale?: number; // default: 7

  /** Poll interval for job status (ms) */
  pollIntervalMs?: number; // default: 2000

  /** Maximum poll attempts */
  maxPollAttempts?: number; // default: 150
}
```

## Popular Models

The provider includes pre-defined URNs for popular models:

```typescript
import { POPULAR_MODELS } from '@oshun/civitai-provider';

// SD 1.5 models
POPULAR_MODELS.realisticVision; // Realistic Vision
POPULAR_MODELS.deliberate; // Deliberate
POPULAR_MODELS.dreamshaper; // DreamShaper

// SDXL models
POPULAR_MODELS.juggernautXL; // Juggernaut XL
POPULAR_MODELS.realvisXL; // RealVisXL
POPULAR_MODELS.animagineXL; // Animagine XL

// Flux models
POPULAR_MODELS.fluxDev; // Flux.1 Dev

// Pony models
POPULAR_MODELS.ponyDiffusion; // Pony Diffusion
```

## TypeScript Types

```typescript
import type {
  // URN Types
  AIRURN,
  AIEcosystem,
  ResourceType,
  ModelSource,
  ModelFormat,

  // Generation Types
  ImageGenerationParams,
  ImageGenerationRequest,
  VideoGenerationParams,
  VideoGenerationRequest,
  AdditionalNetwork,
  ControlNetConfig,

  // Video Types
  VideoModel,
  VideoQuality,
  MovementAmplitude,

  // Job Types
  GenerationJob,
  JobStatus,
  JobResult,
  JobAvailability,

  // Model Types
  ModelInfo,
  ModelVersionInfo,
  ModelSearchQuery,
  ModelTypeFilter,
  ModelSort,

  // Cost Types
  CostEstimate,
  BuzzBalance,

  // Configuration
  CivitaiConfig,
  Scheduler,
} from '@oshun/civitai-provider';
```

## Related Documentation

- [Model Management](./model-management.md) - Managing models, downloads, and
  versions
- [Training Guide](./training.md) - Training custom LoRAs
- [Best Practices](./best-practices.md) - Optimization and cost management
