Disciplines · Integrations

Civitai Model Management

The model management system provides:

14sections3 minread

On this page

This document covers model discovery, downloads, versioning, and lifecycle management for Civitai models in the Oshun platform.

Overview#

The model management system provides:

  • Model Discovery: Search, browse, and filter models
  • Download Management: Queue-based downloading with progress tracking
  • Version Control: Handle model versions and compatibility
  • Storage Optimization: Intelligent caching and cleanup
  • Hot-Swap: Live model switching with memory management

CivitAI Service#

The CivitAIService provides a production-grade API client with resilience patterns built in.

Initialization#

typescript
import { CivitAIService, createCivitAIService } from '@oshun/civitai-service';

const service = createCivitAIService({
  apiKey: process.env.CIVITAI_API_KEY,
  rateLimitBuffer: 60, // requests per minute
  cacheTtl: 300, // cache TTL in seconds
  maxConcurrentDownloads: 3,
  enableCache: true,
  nsfwEnabled: true,
  contentLevel: 'R', // PG, PG13, R, X, XXX
});

Configuration Options#

typescript
interface CivitAIConfig {
  apiKey: string;
  baseUrl?: string; // default: 'https://civitai.com/api/v1'
  rateLimitBuffer?: number; // default: 60
  cacheTtl?: number; // default: 300
  retryAttempts?: number; // default: 3
  retryBaseDelay?: number; // default: 1000
  enableCache?: boolean; // default: true
  maxConcurrentDownloads?: number; // default: 3
  nsfwEnabled?: boolean; // default: true
  contentLevel?: ContentLevel; // default: 'R'
}

Model Discovery#

Listing Models#

typescript
const response = await service.listModels({
  query: 'portrait', // search query
  types: ['Checkpoint'], // model types
  sort: 'Highest Rated', // sort order
  page: 1,
  limit: 20,
  nsfw: false,
});

for (const model of response.items) {
  console.log(`${model.name} (${model.type})`);
  console.log(`Creator: ${model.creator.username}`);
  console.log(`Downloads: ${model.stats.downloadCount}`);
  console.log(`Rating: ${model.stats.rating}/5`);
}

Search Parameters#

Parameter Type Description
query string Search query string
types ModelType[] Filter by model types
sort string Sort order
page number Page number (1-indexed)
limit number Results per page (max 100)
nsfw boolean Include NSFW content
tag string Filter by tag
username string Filter by creator

Model Types#

typescript
type ModelType =
  | 'Checkpoint'
  | 'TextualInversion'
  | 'Hypernetwork'
  | 'AestheticGradient'
  | 'LORA'
  | 'Controlnet'
  | 'Poses';

Sort Options#

Value Description
Highest Rated Sort by rating
Most Downloaded Sort by download count
Newest Sort by creation date

Getting Model Details#

typescript
// Get model by ID
const model = await service.getModel(133005);

console.log('Model:', model.name);
console.log('Description:', model.description);
console.log('Tags:', model.tags);
console.log('NSFW:', model.nsfw);
console.log('Commercial Use:', model.allowCommercialUse);

// List versions
for (const version of model.modelVersions) {
  console.log(`Version: ${version.name}`);
  console.log(`Base Model: ${version.baseModel}`);
  console.log(`Trained Words: ${version.trainedWords.join(', ')}`);
}

Getting Version by Hash#

typescript
// Useful for identifying models by file hash
const version = await service.getModelVersionByHash(
  'abc123def456...' // SHA256 hash
);

console.log('Model:', version.model.name);
console.log('Version:', version.name);

Listing Creators#

typescript
const creators = await service.listCreators({
  query: 'artist',
  limit: 20,
});

for (const creator of creators.items) {
  console.log(`Username: ${creator.username}`);
}

Listing Tags#

typescript
const tags = await service.listTags({
  query: 'style',
  limit: 50,
});

for (const tag of tags.items) {
  console.log(`${tag.name}: ${tag.modelCount} models`);
}

Download Management#

Download Queue#

The service includes a priority-based download queue with concurrent download support.

typescript
// Queue a download
const downloadId = service.queueDownload({
  modelVersionId: 348913,
  destinationPath: '/models/checkpoints/',
  customFilename: 'juggernaut-xl.safetensors',
  priority: 'normal',
  verifyHash: true,
  hashAlgorithm: 'SHA256',
  onProgress: (progress) => {
    console.log(`${progress.percentage}% - ${progress.speedBps / 1024} KB/s`);
  },
});

console.log('Download queued:', downloadId);

Download Priorities#

Priority Description Use Case
urgent Immediate processing User-requested downloads
high Next in queue Auto-triggered downloads
normal Standard priority Batch downloads
low Background processing Pre-caching

Monitoring Progress#

typescript
// Get single download progress
const progress = service.getDownloadProgress(downloadId);

if (progress) {
  console.log(`Status: ${progress.status}`);
  console.log(`Progress: ${progress.percentage}%`);
  console.log(
    `Downloaded: ${progress.downloadedBytes} / ${progress.totalBytes}`
  );
  console.log(`Speed: ${progress.speedBps / 1024} KB/s`);
  console.log(`ETA: ${progress.etaSeconds} seconds`);
}

// Get all downloads
const allDownloads = service.getAllDownloads();
for (const download of allDownloads) {
  console.log(
    `${download.id}: ${download.status} - ${download.progress.percentage}%`
  );
}

// Get queue statistics
const stats = service.getDownloadStats();
console.log(`Total: ${stats.totalItems}`);
console.log(`Queued: ${stats.queued}`);
console.log(`Downloading: ${stats.downloading}`);
console.log(`Completed: ${stats.completed}`);
console.log(`Failed: ${stats.failed}`);

Download Control#

typescript
// Pause download
service.pauseDownload(downloadId);

// Resume download
service.resumeDownload(downloadId);

// Cancel download
service.cancelDownload(downloadId);

Download Status Flow#

text
queued → downloading → completed
                    → failed
         paused ↔ queued
         cancelled

Model Type Manager#

The Model Type Manager provides metadata and compatibility information for different model types.

Supported Model Types#

Type Subtypes Description
Checkpoints base, refiner, inpaint, merged Base models for generation
LoRA/LyCORIS LoRA, LoHa, LoKr, LoCon, DyLoRA, DoRA Fine-tuning adapters
VAE standard, MSE, EMA, TAESD Image encoding/decoding
Embeddings positive, negative, style, character Text embeddings
ControlNet canny, depth, openpose, lineart Conditional generation
IP-Adapters standard, plus, faceid Image-conditioned generation
Text Encoders CLIP-L, CLIP-G, T5, SigLIP Text encoding models
Upscalers ESRGAN, RealESRGAN, SwinIR Image upscaling
Motion Modules AnimateDiff v1-3, LCM Video generation
Inpainting BrushNet, PowerPaint, MAT, LaMa Image inpainting

Architecture Support#

Architecture Versions
Stable Diffusion 1.4, 1.5, 2.0, 2.1
SDXL 0.9, 1.0, Turbo, Lightning
Flux 1.0 S, D, D Hyper
Pony V6
Video LTXV, CogVideoX, SVD

Rate Limiting#

Sliding Window Rate Limiter#

The service implements a sliding window rate limiter to respect API limits.

typescript
// Check rate limit state
const rateLimitState = service.getRateLimitState();

console.log(`Remaining: ${rateLimitState.remaining}/${rateLimitState.limit}`);
console.log(`Reset at: ${rateLimitState.resetAt}`);
console.log(`Is limited: ${rateLimitState.isLimited}`);

if (rateLimitState.isLimited) {
  console.log(`Retry after: ${rateLimitState.retryAfter} seconds`);
}

Rate Limit Configuration#

Setting Default Description
Window 60 seconds Sliding window duration
Max Requests 60 Requests per window
Retry Delay Exponential Backoff on 429 response

Circuit Breaker#

Circuit States#

The circuit breaker protects against cascading failures:

text
closed → (failures exceed threshold) → open
  ↑                                      ↓
  └──────── (success threshold met) ← half_open
                                         ↑
                        (timeout elapsed) ┘

Checking Circuit State#

typescript
const circuitState = service.getCircuitBreakerState();

console.log(`State: ${circuitState.state}`);
console.log(`Failures: ${circuitState.failures}`);
console.log(`Successes: ${circuitState.successes}`);

if (circuitState.state === 'open') {
  console.log(`Opened at: ${circuitState.openedAt}`);
}

Circuit Breaker Configuration#

Setting Default Description
Failure Threshold 5 Failures to open circuit
Success Threshold 3 Successes to close circuit
Timeout 30 seconds Time before half-open
Monitor Window 60 seconds Failure tracking window

Request Caching#

Cache Configuration#

typescript
// Cache is enabled by default
const service = createCivitAIService({
  apiKey: process.env.CIVITAI_API_KEY,
  enableCache: true,
  cacheTtl: 300, // 5 minutes
});

// Check cache statistics
const cacheStats = service.getCacheStats();
console.log(`Size: ${cacheStats.size}`);
console.log(`Hits: ${cacheStats.hits}`);
console.log(`Misses: ${cacheStats.misses}`);
console.log(
  `Hit Rate: ${(cacheStats.hits / (cacheStats.hits + cacheStats.misses)) * 100}%`
);

// Clear cache
service.clearCache();

Cache Behavior#

  • GET requests are cached by default
  • Cache key is generated from endpoint + params
  • LRU eviction when cache reaches max size
  • Automatic cleanup of expired entries

Bypassing Cache#

typescript
// Force fresh request
const model = await service.request('/models/133005', {
  useCache: false,
});

Content Filtering#

Content Levels#

Level Description Includes
PG Safe for all ages PG only
PG13 Teen appropriate PG, PG13
R Adult themes PG, PG13, R
X Explicit content PG, PG13, R, X
XXX All content Everything

Configuring Content Filters#

typescript
const service = createCivitAIService({
  apiKey: process.env.CIVITAI_API_KEY,
  nsfwEnabled: true,
  contentLevel: 'R',
});

// Check if content is allowed
const isAllowed = service.isContentLevelAllowed('PG13');
console.log('PG13 allowed:', isAllowed);

Event System#

Event Types#

Event Description Data
request_start Request initiated endpoint, method, url
request_complete Request succeeded endpoint, method, duration
request_error Request failed endpoint, method, error
rate_limited Rate limit hit endpoint, waitTime
circuit_open Circuit opened endpoint
cache_hit Cache hit endpoint, cacheKey
cache_miss Cache miss endpoint, cacheKey
download_start Download queued downloadId, request

Subscribing to Events#

typescript
// Subscribe to events
service.on('request_complete', (event) => {
  console.log(
    `${event.data.method} ${event.data.endpoint} - ${event.data.duration}ms`
  );
});

service.on('rate_limited', (event) => {
  console.warn(`Rate limited! Wait ${event.data.waitTime}ms`);
});

service.on('circuit_open', (event) => {
  console.error(`Circuit breaker opened for ${event.data.endpoint}`);
});

// Unsubscribe
const listener = (event) => console.log(event);
service.on('cache_hit', listener);
service.off('cache_hit', listener);

Analytics#

Request Analytics#

typescript
const analytics = service.getAnalytics();

console.log(`Total Requests: ${analytics.totalRequests}`);
console.log(`Successful: ${analytics.successfulRequests}`);
console.log(`Failed: ${analytics.failedRequests}`);
console.log(`Rate Limited: ${analytics.rateLimitedRequests}`);
console.log(`Avg Response Time: ${analytics.averageResponseTimeMs}ms`);

// Per-endpoint counts
for (const [endpoint, count] of Object.entries(analytics.endpointCounts)) {
  console.log(`${endpoint}: ${count} requests`);
}

// Error distribution
for (const [code, count] of Object.entries(analytics.errorCounts)) {
  console.log(`${code}: ${count} errors`);
}

// Reset analytics
service.resetAnalytics();

The Civitai Link provider enables real-time model synchronization via WebSocket.

Initialization#

typescript
import { CivitaiLinkProvider } from '@oshun/civitai-link';

const link = new CivitaiLinkProvider({
  endpoint: process.env.CIVITAI_LINK_ENDPOINT,
  apiKey: process.env.CIVITAI_LINK_KEY,
  autoReconnect: true,
  reconnectDelay: 5000,
  heartbeatInterval: 30000,
});

await link.connect();

Hot-Swap Models#

typescript
// Swap to a different model
await link.swapModel({
  modelVersionId: 348913,
  slot: 'checkpoint',
  priority: 'high',
});

// Check memory stats
const memory = await link.getMemoryStats();
console.log(`VRAM Used: ${memory.vramUsed / 1024 / 1024} MB`);
console.log(`VRAM Free: ${memory.vramFree / 1024 / 1024} MB`);
console.log(`RAM Used: ${memory.ramUsed / 1024 / 1024} MB`);

Download Queue#

typescript
// Queue download with priority
link.queueDownload({
  modelVersionId: 348913,
  priority: 'high',
  onProgress: (progress) => {
    console.log(`${progress.filename}: ${progress.percentage}%`);
  },
});

// Get queue status
const queue = link.getDownloadQueue();
for (const item of queue) {
  console.log(`${item.id}: ${item.status}`);
}

Predictive Loading#

typescript
// Enable predictive loading based on usage patterns
link.enablePredictiveLoading({
  analyzeUsagePatterns: true,
  preloadThreshold: 0.7, // 70% confidence
});

// Get preload recommendations
const recommendations = await link.getPreloadRecommendations();
for (const rec of recommendations) {
  console.log(`Recommend preloading: ${rec.modelName}`);
  console.log(`Usage frequency: ${rec.usageFrequency}`);
  console.log(`Confidence: ${rec.confidence}`);
}

Storage Optimization#

typescript
// Analyze storage usage
const analysis = await link.analyzeStorage();

console.log(`Total models: ${analysis.totalModels}`);
console.log(`Total size: ${analysis.totalSize / 1024 / 1024 / 1024} GB`);
console.log(`Duplicates: ${analysis.duplicates.length}`);

// Get cleanup suggestions
const suggestions = await link.getCleanupSuggestions();
for (const suggestion of suggestions) {
  console.log(`Suggest removing: ${suggestion.modelName}`);
  console.log(`Reason: ${suggestion.reason}`);
  console.log(`Space savings: ${suggestion.sizeSaved / 1024 / 1024} MB`);
}

// Execute cleanup
await link.executeCleanup(suggestions.map((s) => s.modelVersionId));

Best Practices#

Efficient API Usage#

  1. Use caching: Enable caching for repeated queries
  2. Batch requests: Combine multiple model lookups when possible
  3. Respect rate limits: Monitor rate limit state proactively
  4. Handle errors gracefully: Implement retry logic with backoff

Download Management#

  1. Use priorities wisely: Reserve urgent for user-initiated downloads
  2. Monitor progress: Provide feedback to users on download status
  3. Verify hashes: Always verify downloaded files
  4. Clean up failures: Remove failed downloads from queue

Model Organization#

  1. Use consistent naming: Follow a naming convention for downloaded models
  2. Track versions: Maintain metadata about model versions
  3. Regular cleanup: Remove unused models periodically
  4. Monitor disk space: Set alerts for low disk space