Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
e750df9
rebrand: rename LTX Desktop to Director's Desktop with new logo and i…
taskmasterpeace Mar 6, 2026
927e14f
feat: add model name badges to generated images and videos
taskmasterpeace Mar 6, 2026
90a20ae
feat: replace fal.ai with Replicate for cloud image generation
taskmasterpeace Mar 6, 2026
4c14d56
feat: add Replicate video API client and job queue system
taskmasterpeace Mar 6, 2026
b486de4
docs: add Palette integration design and Phase 1 implementation plan
taskmasterpeace Mar 6, 2026
3693fa8
feat: add Palette sync infrastructure (API key, sync routes, protocol)
taskmasterpeace Mar 6, 2026
24c7366
feat: add lastFramePath field and prompt enhancement route
taskmasterpeace Mar 6, 2026
9358148
feat: add first/last frame slots, prompt enhance, variations slider, …
taskmasterpeace Mar 6, 2026
9f81326
feat: add video extend feature — continue generating from last frame
taskmasterpeace Mar 6, 2026
35e4dee
feat: add Palette connection UI in Settings with sync status and credits
taskmasterpeace Mar 6, 2026
2232a3c
chore: add dev-only electronAPI mock for browser testing
taskmasterpeace Mar 6, 2026
25a7864
feat: implement Phases 2-5 — Gallery, Library, Power Tools, Advanced …
taskmasterpeace Mar 6, 2026
33dd6d3
fix: only track own submitted job for isGenerating state
taskmasterpeace Mar 6, 2026
597d482
feat: add bulk generation system — batch queue, sweeps, pipelines, an…
taskmasterpeace Mar 9, 2026
38771df
feat: add GPU optimizations (FFN chunking, TeaCache, VRAM cleanup) an…
taskmasterpeace Mar 9, 2026
f96d656
docs: add GPU optimization results and benchmark comparison report
taskmasterpeace Mar 9, 2026
887b504
feat: add credit tracking, output naming, and Palette integration
taskmasterpeace Mar 9, 2026
c1e4bd3
feat: add video LoRA support for LTX-2 local generation
taskmasterpeace Mar 18, 2026
a6fdcd7
fix: use first-frame conditioning for video extend
taskmasterpeace Mar 18, 2026
3646251
feat: add long video generation via chain-extend pipeline
taskmasterpeace Mar 19, 2026
91a5954
feat: add FLUX.2 Klein 9B image generation with NF4 quantization
taskmasterpeace Mar 21, 2026
f49b8a8
feat: add LoRA browser with CivitAI search and local library management
taskmasterpeace Mar 21, 2026
6dce1f1
test: add NF4 quantization test script and long video tests
taskmasterpeace Mar 21, 2026
654dda3
fix: isolate bundled Python from system packages (upstream c3fac8e)
taskmasterpeace Mar 21, 2026
5176e84
fix: don't force-quit app when update is ready (upstream 049cb1f)
taskmasterpeace Mar 21, 2026
d7afe85
fix: download progress for xet protocol (upstream 5671a27)
taskmasterpeace Mar 21, 2026
8b8c2ae
feat(palette-sync): add list_loras to PaletteSyncClient
taskmasterpeace Mar 22, 2026
a0d2230
feat(palette-sync): add sync_loras to SyncHandler with LoRA download
taskmasterpeace Mar 22, 2026
4e422c2
feat(palette-sync): add Sync LoRAs button in settings
taskmasterpeace Mar 22, 2026
742dd77
feat(palette-sync): add sync-loras route and integration tests
taskmasterpeace Mar 22, 2026
136d7f8
docs: add quantized video model support design spec
taskmasterpeace Mar 23, 2026
eb56e3d
docs(quantized-models): add implementation plan for quantized video m…
taskmasterpeace Mar 23, 2026
12ad42e
feat(quantized-models): add gguf dependency, settings fields, and API…
taskmasterpeace Mar 23, 2026
b354c7c
refactor: rename DetectedModel.format to model_format to avoid shadow…
taskmasterpeace Mar 23, 2026
63fec2a
feat(quantized-models): add ModelScanner service with Protocol, impl,…
taskmasterpeace Mar 23, 2026
fba4805
fix: correct model_guide_data to target LTX 2.3 22B, add outer try/ex…
taskmasterpeace Mar 23, 2026
b59b7c2
test(quantized-models): add model guide recommendation tests
taskmasterpeace Mar 23, 2026
0ea7455
feat(quantized-models): wire ModelScanner to handler, routes, and int…
taskmasterpeace Mar 23, 2026
a85b018
feat(quantized-models): add Models tab to SettingsModal
taskmasterpeace Mar 23, 2026
736a58c
feat(quantized-models): add ModelGuideDialog popup with GPU recommend…
taskmasterpeace Mar 23, 2026
434b865
feat(quantized-models): update PipelinesHandler to route by model format
taskmasterpeace Mar 23, 2026
1a34407
feat(quantized-models): add GGUF video pipeline scaffold
taskmasterpeace Mar 23, 2026
bd13fc9
feat(quantized-models): add NF4 video pipeline scaffold
taskmasterpeace Mar 23, 2026
086b59c
docs(quantized-models): add Custom Video Models section to README
taskmasterpeace Mar 23, 2026
44b95ed
feat: implement GGUF and NF4 pipeline loading (replacing scaffolds)
taskmasterpeace Mar 23, 2026
15edf33
feat: rewrite model guide UI text in plain English
taskmasterpeace Mar 23, 2026
0289096
feat: switch default image model from Z-Image-Turbo to Flux Klein 9B
taskmasterpeace Mar 24, 2026
03969e2
feat: add plain English status messages for image model switching
taskmasterpeace Mar 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 150 additions & 1 deletion CLAUDE.md
77 changes: 71 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,43 @@ LTX Desktop is an open-source desktop app for generating videos with LTX models

## Features

- Text-to-video generation
- Image-to-video generation
- Audio-to-video generation
- Video edit generation (Retake)
- Video Editor Interface
- Video Editing Projects
### Generation
- **Text-to-video** — generate video clips from text prompts
- **Image-to-video** — animate a still image into video
- **Audio-to-video** — drive video generation from an audio track
- **Image generation** — create images with ZIT (local) or fal API
- **Image editing (img2img)** — edit existing images with ZIT Edit
- **Video Retake** — re-generate portions of an existing video
- **IC-LoRA** — identity-consistent generation with LoRA weights
- **Video Extend** — continue generating from the last frame of a video
- **Prompt Enhancement** — AI-powered prompt rewriting (via LTX API or Palette)

### Batch Generation
- **Batch Builder** — queue multiple generation jobs at once
- **List mode** — add prompts one-by-one with per-job settings
- **Import mode** — bulk-import prompts from CSV, JSON, or plain text files
- **Grid Sweep mode** — combinatorial parameter sweeps (prompts × seeds × models)
- **Timeline import** — import an edited timeline as a batch to re-generate all segments

### Library & Organization
- **Gallery** — browse, filter, and manage all generated images and videos
- **Prompt Library** — save, tag, and reuse favorite prompts
- **Characters** — store character descriptions for consistent generation
- **Styles** — save and apply visual style presets
- **References** — manage reference images for guided generation
- **Wildcards** — define placeholder tokens that expand to random values

### Palette Cloud Integration
- **Directors Palette sync** — connect to [Directors Palette](https://directorspal.com) for cloud-synced library content
- **Email/password login** — authenticate directly or via deep link
- **Credit balance & cost tracking** — view remaining credits in the header, see estimated cost on Generate buttons before submitting
- **Automatic credit deduction** — API-slot jobs automatically deduct credits after successful generation
- **Seedance video generation** — generate videos via Seedance 1.5 Pro through the Replicate API

### Editor & Export
- **Video Editor** — multi-track timeline editor with clips, transitions, and keyframes
- **Video Projects** — save and reopen editing sessions
- **FFmpeg export** — export final videos with configurable codec and quality settings

## Local vs API mode

Expand All @@ -37,6 +68,27 @@ LTX Desktop is an open-source desktop app for generating videos with LTX models

In API-only mode, available resolutions/durations may be limited to what the API supports.

## Custom Video Models

Directors Desktop supports multiple LTX 2.3 model formats, so you can run on GPUs with less VRAM.

| Your GPU VRAM | Recommended Format | File Size |
|---------------|-------------------|-----------|
| 32 GB+ | BF16 (auto-downloaded) | ~43 GB |
| 20-31 GB | [FP8 Checkpoint](https://huggingface.co/Lightricks/LTX-Video-2.3-22b-distilled) | ~22 GB |
| 16-19 GB | [GGUF Q5_K](https://huggingface.co/city96/LTX-Video-2.3-22b-0.9.7-dev-gguf) | ~15 GB |
| 10-15 GB | [GGUF Q4_K](https://huggingface.co/city96/LTX-Video-2.3-22b-0.9.7-dev-gguf) | ~12 GB |

### Setup

1. Download the model file for your GPU from the links above
2. Open **Settings → Models** and set your model folder
3. If using GGUF or NF4, also download the [distilled LoRA](https://huggingface.co/Lightricks/LTX-Video-2.3-22b-distilled)
4. Select your model from the dropdown
5. Generate!

The app also has a built-in **Model Guide** (Settings → Models → Open Model Guide) that detects your GPU and recommends the best format automatically.

## System requirements

### Windows (local generation)
Expand Down Expand Up @@ -96,10 +148,22 @@ Used for Z Image Turbo text-to-image generation in API mode. When enabled, image

Create an API key in the [fal dashboard](https://fal.ai/dashboard/keys).

### Replicate API key (optional)

Used for Seedance 1.5 Pro video generation. When enabled, video generation requests are sent to Replicate.

Create an API key in the [Replicate dashboard](https://replicate.com/account/api-tokens).

### Gemini API key (optional)

Used for AI prompt suggestions. When enabled, prompt context and frames may be sent to Google Gemini.

### Directors Palette account (optional)

Connect to [Directors Palette](https://directorspal.com) to sync library content (characters, styles, references), use cloud-based prompt enhancement, and track credit usage. Sign in via email/password in **Settings > Palette Connection**.

Credits are consumed when generating via API-backed models (cloud video, Seedance, cloud image). Local GPU generations are free. Credit balance and per-generation costs are displayed in the UI.

## Architecture

LTX Desktop is split into three main layers:
Expand All @@ -113,6 +177,7 @@ LTX Desktop is split into three main layers:
- **Backend (`backend/`)**: Python + FastAPI local server.
- Orchestrates generation, model downloads, and GPU execution.
- Calls external APIs only when API-backed features are used.
- Output files follow the naming convention `dd_{model}_{prompt_slug}_{timestamp}.{ext}` for easy identification.

```mermaid
graph TD
Expand Down
44 changes: 44 additions & 0 deletions backend/_routes/batch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Route handlers for /api/queue/batch/* — batch generation endpoints."""

from __future__ import annotations

from fastapi import APIRouter, Depends

from api_types import BatchSubmitRequest, BatchSubmitResponse, BatchStatusResponse
from state import get_state_service
from app_handler import AppHandler

router = APIRouter(prefix="/api/queue", tags=["batch"])


@router.post("/submit-batch", response_model=BatchSubmitResponse)
def route_batch_submit(
req: BatchSubmitRequest,
handler: AppHandler = Depends(get_state_service),
) -> BatchSubmitResponse:
return handler.batch.submit_batch(req, handler.job_queue)


@router.get("/batch/{batch_id}/status", response_model=BatchStatusResponse)
def route_batch_status(
batch_id: str,
handler: AppHandler = Depends(get_state_service),
) -> BatchStatusResponse:
return handler.batch.get_batch_status(batch_id, handler.job_queue)


@router.post("/batch/{batch_id}/cancel")
def route_batch_cancel(
batch_id: str,
handler: AppHandler = Depends(get_state_service),
) -> dict[str, str]:
handler.batch.cancel_batch(batch_id, handler.job_queue)
return {"status": "cancelled"}


@router.post("/batch/{batch_id}/retry-failed", response_model=BatchSubmitResponse)
def route_batch_retry(
batch_id: str,
handler: AppHandler = Depends(get_state_service),
) -> BatchSubmitResponse:
return handler.batch.retry_failed(batch_id, handler.job_queue)
18 changes: 18 additions & 0 deletions backend/_routes/contact_sheet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""Route for contact sheet generation."""
from __future__ import annotations

from fastapi import APIRouter, Depends

from api_types import GenerateContactSheetRequest, GenerateContactSheetResponse
from app_handler import AppHandler
from state import get_state_service

router = APIRouter(prefix="/api/contact-sheet", tags=["contact-sheet"])


@router.post("/generate", response_model=GenerateContactSheetResponse)
def route_generate_contact_sheet(
req: GenerateContactSheetRequest,
handler: AppHandler = Depends(get_state_service),
) -> GenerateContactSheetResponse:
return handler.contact_sheet.generate(req)
27 changes: 27 additions & 0 deletions backend/_routes/enhance_prompt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Prompt enhancement route."""
from __future__ import annotations

from fastapi import APIRouter, Depends
from pydantic import BaseModel

from app_handler import AppHandler
from state import get_state_service

router = APIRouter(tags=["enhance"])


class EnhancePromptRequest(BaseModel):
prompt: str = ""
mode: str = "text-to-video"
model: str = "ltx-fast"
imagePath: str | None = None


@router.post("/api/enhance-prompt")
def enhance_prompt(
req: EnhancePromptRequest,
handler: AppHandler = Depends(get_state_service),
):
return handler.enhance_prompt.enhance(
req.prompt, req.mode, req.model, image_path=req.imagePath,
)
Loading