Transform tsr into a unified server/client tool for remote image generation on junkpile (ROCm GPU server), with model-specific Docker images, a models database, and full image management capabilities.
┌─────────────────────────────────────────────────────────────────────┐
│ junkpile (server) │
├─────────────────────────────────────────────────────────────────────┤
│ ┌──────────────────────┐ ┌────────────────────────────────────┐ │
│ │ sd-server:pony │◄───│ tsr serve (FastAPI) │ │
│ │ sd-server:illustrious│ │ - POST /api/generate │ │
│ │ sd-server:flux │ │ - GET/POST/DELETE /api/images │ │
│ │ (Docker/ROCm) │ │ - GET /api/models, /api/loras │ │
│ └──────────────────────┘ │ - POST /api/download (CivitAI) │ │
│ │ - GET/POST /api/db/* (models.db) │ │
│ ┌──────────────────────┐ │ │ │
│ │ models.db │◄───┤ │ │
│ │ (SQLite: CivitAI + │ └────────────────────────────────────┘ │
│ │ local file cache) │ ▲ │
│ └──────────────────────┘ │ :8080 │
└──────────────────────────────────────────────│──────────────────────┘
│ HTTP
┌──────────────────────────────────────────────│──────────────────────┐
│ local machine │ │
├──────────────────────────────────────────────┼──────────────────────┤
│ tsr generate "prompt" --remote junkpile │
│ tsr images list --remote junkpile │
│ tsr images delete <id> --remote junkpile │
│ tsr models list --remote junkpile │
│ tsr models switch pony --remote junkpile │
│ tsr dl 999258 --remote junkpile │
│ tsr db search "pony" --remote junkpile │
└─────────────────────────────────────────────────────────────────────┘
Create parameterized Dockerfiles that produce model-family-specific images with optimal defaults baked in. Each image knows its best sampler, scheduler, resolution, CFG scale, and negative prompt.
- Objective: Define optimal generation parameters per model family
- Files:
rocm-docker/model-defaults.toml - Dependencies: None
- Implementation:
- Create TOML with sections:
[sd15],[sdxl],[pony],[illustrious],[flux] - Each section:
width,height,steps,cfg_scale,sampler,scheduler,negative_prompt - Reference:
models.mdhas the research already
- Create TOML with sections:
- Objective: Single Dockerfile that builds model-specific images via build args
- Files:
rocm-docker/Dockerfile.sd-server - Dependencies: Step 1.1
- Implementation:
- Add
ARG MODEL_FAMILY=sdxlwith validation - Inject defaults from model-defaults.toml as ENV vars
- Keep entrypoint.sh flexible (env vars override baked defaults)
- Build targets:
sd-server:pony,sd-server:illustrious,sd-server:flux
- Add
- Objective: Automated build of all model-specific images
- Files:
rocm-docker/build-all.sh - Dependencies: Step 1.2
- Implementation:
- Loop through model families, build each with appropriate args
- Tag pattern:
sd-server:{family} - Push to registry (optional)
Move the SQLite database from rocm-docker into tensors as a proper module with full CRUD operations, exposed via CLI and API.
- Objective: SQLite wrapper with schema management and CRUD operations
- Files:
tensors/db.py,tensors/schema.sql - Dependencies: None
- Implementation:
- Move schema from
rocm-docker/import_models.pytotensors/schema.sql Databaseclass with connection management, migrations- Methods:
scan_files(),link_civitai(),cache_model(),search_models(),get_triggers() - Use existing
tensors/api.pyfor CivitAI fetches - Config:
DATA_DIR / "models.db"
- Move schema from
- Objective: Expose database operations via
tsr dbsubcommand group - Files:
tensors/cli.py - Dependencies: Step 2.1
- Implementation:
tsr db scan <directory>— Scan safetensors, compute hashes, store metadatatsr db link— Match unlinked files to CivitAI by hashtsr db cache <model_id>— Fetch and cache full CivitAI model datatsr db list— List local files with CivitAI info (uses view)tsr db search <query>— Search cached models offlinetsr db triggers <file>— Show trigger words for a LoRA- All commands support
--jsonoutput
- Objective: Expose database queries via HTTP API
- Files:
tensors/server/routes.py - Dependencies: Step 2.1
- Implementation:
GET /api/db/files— List local filesGET /api/db/models— Search cached modelsGET /api/db/models/{id}— Get model detailsGET /api/db/triggers/{file_path}— Get trigger wordsPOST /api/db/scan— Trigger directory scanPOST /api/db/link— Trigger CivitAI linking
Extend the existing FastAPI server with image gallery management, model switching, and CivitAI download capabilities.
- Objective: CRUD for generated images with metadata
- Files:
tensors/server/routes.py,tensors/server/gallery.py - Dependencies: Phase 2
- Implementation:
GET /api/images— List images (paginated, newest first), metadata from sidecar JSONGET /api/images/{id}— Get image fileGET /api/images/{id}/meta— Get generation metadataDELETE /api/images/{id}— Delete image + sidecarPOST /api/images/{id}/edit— Update metadata (tags, notes)- Images stored in
DATA_DIR / "gallery/"with{timestamp}_{seed}.png+.jsonsidecar - Gallery config: output directory, max storage, cleanup policy
- Objective: List available models, switch active model, hot-reload
- Files:
tensors/server/routes.py - Dependencies: None
- Implementation:
GET /api/models— List available checkpoints (scan models directory)GET /api/models/active— Current loaded model infoPOST /api/models/switch— Switch model (calls sd-server reload or container swap)GET /api/loras— List available LoRAs- Container strategy: either reload sd-server with new model, or run multiple containers per model family
- Objective: Download models directly to server via API
- Files:
tensors/server/routes.py - Dependencies: Step 2.1
- Implementation:
POST /api/download— Accept model/version ID or hash, download to appropriate directory- Stream progress via SSE or polling endpoint
- Auto-scan and link after download
- Use existing
tensors/api.pydownload logic
- Objective: Full generation control with gallery integration
- Files:
tensors/server/routes.py - Dependencies: Step 3.1
- Implementation:
POST /api/generate— Forward to sd-server, save result to gallery- Accept all sd-server params: prompt, negative, width, height, steps, cfg, sampler, scheduler, seed, loras
- Return image ID, metadata, and base64 (optional)
- Support batch generation
- Auto-increment seed for batches
Add --remote flag to existing commands to talk to a remote tsr server instead of local operations or direct CivitAI API.
- Objective: HTTP client wrapper for tsr server API
- Files:
tensors/client.py - Dependencies: Phase 3
- Implementation:
TsrClientclass wrapping httpx- Methods mirror server endpoints:
generate(),list_images(),delete_image(),list_models(),switch_model(),download(),db_search() - Handle streaming responses for downloads
- Auth: API key header (optional, future)
- Objective: Configure remote server URL in config.toml
- Files:
tensors/config.py - Dependencies: None
- Implementation:
- Add
[remotes]section:junkpile = "http://junkpile:8080" --remote <name>flag resolves to URL from config--remote <url>accepts direct URL- Default remote configurable:
default_remote = "junkpile"
- Add
- Objective: All relevant commands work against remote server
- Files:
tensors/cli.py - Dependencies: Step 4.1, Step 4.2
- Implementation:
tsr generate— Use remote if--remote, else local sd-servertsr images list/delete/show— New subcommand group for gallerytsr models list/switch— New subcommand grouptsr dl— Proxy through remote if--remotetsr db *— All db commands support--remote- Consistent UX: same output format local vs remote
Scripts and configs for deploying and managing sd-server containers on junkpile.
- Objective: Run multiple sd-server containers, one per model family
- Files:
rocm-docker/docker-compose.yml - Dependencies: Phase 1
- Implementation:
- Service per model family:
sd-pony,sd-illustrious,sd-flux - Shared volumes:
/models,/loras,/output - Each on different port: 1234, 1235, 1236
- tsr server routes to correct container based on active model
- Health checks
- Service per model family:
- Objective: One-command deploy/update on junkpile
- Files:
rocm-docker/deploy.sh - Dependencies: Step 5.1
- Implementation:
- Copy files to junkpile
- Build images
- Pull models if missing
- Start containers
- Start tsr server
- Verify health
- Objective: Auto-start tsr server on boot
- Files:
rocm-docker/tsr-server.service - Dependencies: Step 5.2
- Implementation:
- systemd unit file
- Depends on docker.service
- Restart on failure
- Install instructions
- Files:
tests/test_db.py - Dependencies: Phase 2
- Implementation:
- Test schema creation, migrations
- Test CRUD operations
- Test CivitAI linking logic
- Use temp database
- Files:
tests/test_server.py - Dependencies: Phase 3
- Implementation:
- Use FastAPI TestClient
- Mock sd-server responses
- Test gallery CRUD
- Test model listing/switching
- Files:
tests/test_client.py - Dependencies: Phase 4
- Implementation:
- Mock HTTP responses with respx
- Test all client methods
- Test error handling