--- id: "0084" title: "imagegen_studio — app Go binario producto (Fase 3 plan stack)" status: pendiente type: feature domain: - imagegen scope: app-scoped priority: media depends: [] blocks: [] related: [] created: 2026-05-13 updated: 2026-05-17 tags: [] --- ## Objetivo App Go autocontenida `imagegen_studio` que orquesta `sd-cli` para generar imagenes sin Python en runtime. Encarna la Fase 3 del documento del stack: binario distribuible, `GenerationConfig` Go nativo, subprocess streaming con progreso. ## Contexto - Toda la capa Go del contrato esta lista: tipos `GenerationConfig_go_ml`, `ModelRef_go_ml`, `LoraRef_go_ml`, `ImageGenResult_go_ml`, interface `ImageGenerator_go_ml`. - Funciones Go ya construidas: `sdcli_resolve_binary_go_ml`, `sdcli_generate_go_ml`, `subprocess_stream_go_core`, `genconfig_to_sdcli_args_go_ml`, `genconfig_json_marshal_go_ml`, `sdcli_parse_progress_go_ml`, `get_gpu_info_go_infra`. - Plan del documento: producto Go con subprocess gestionando `sd-cli`, binario embebido via `go:embed` o descarga al primer arranque. ## Arquitectura Path: `projects/imagegen/apps/imagegen_studio/` ``` imagegen_studio/ main.go # CLI args / TUI entry / HTTP API studio.go # ImageGenerator wrapper sobre sdcli_generate app.md # frontmatter del registry CMakeLists.txt # NO (es Go, usa go.mod) go.mod README.md embed/ # opcional: sd binary embebido ``` **Pure core / impure shell:** - `pkg/`: validacion `GenerationConfig`, serializacion JSON, formato outputs (paths derivados). - `shell/` o `studio.go`: invocacion `SdcliGenerate`, IO disco, manejo subproceso. Tres modos de uso: 1. **CLI**: `imagegen_studio generate --prompt "..." --seed 42 --out out.png` 2. **HTTP API**: `imagegen_studio serve --port 8088` → POST /generate {GenerationConfig JSON} 3. **TUI (opcional, Bubble Tea)**: forma interactiva, preview, queue Empezar por CLI; HTTP API y TUI iterativos. ## Tareas 1. Scaffolding 1.1. `fn run init_go_app --project imagegen imagegen_studio` (si existe pipeline) o crear estructura manual. 1.2. `app.md` con `framework: cli`, `tags: [ml, imagegen, service?]`, `uses_functions:` lista de las 7 funciones Go citadas. 1.3. `go.mod` con dependencias minimas (registry imports + cobra opcional). 2. CLI minima (Fase A) 2.1. Subcomando `generate`: flags --prompt/--negative/--seed/--steps/--cfg/--sampler/ --width/--height/--model/--out 2.2. Construir `GenerationConfig`, llamar `SdcliResolveBinary("")`, `SdcliGenerate(...)`. 2.3. Stream progreso a stderr (callback `SdcliProgressCallback`). 2.4. Salida final: imprime path de la imagen + duration_ms + JSON meta. 3. JSON I/O (Fase B) 3.1. Subcomando `generate-from-json --config path/cfg.json --out out.png`. 3.2. Permite pegar configs validados de la fase 2 (notebook cross-validation). 4. HTTP server (Fase C, feature flag) 4.1. `imagegen_studio serve --port 8088`. 4.2. POST `/generate` body = GenerationConfig JSON → respuesta multipart PNG + meta. 4.3. GET `/health` → 200 + version + GpuInfo. 4.4. Feature flag `imagegen-studio-server` para esconder cuando no compila/no testeado. 5. e2e_checks 5.1. Anadir bloque `e2e_checks` en `app.md`: - `build`: go build con CGO_ENABLED=0 - `cli_help`: ./imagegen_studio --help, contiene "generate" - `smoke`: si `sd` binario en $PATH + SD Turbo en vault, generar 1 imagen a /tmp/, verificar PNG valido. Si no: SKIP (warning). 6. Tests 6.1. Tests unitarios sobre helpers puros (path derivation, JSON marshaling). 6.2. Test integracion en e2e_checks (smoke). ## Ejemplo de uso ```bash # CLI directo imagegen_studio generate \ --model /home/lucas/vaults/imagegen_models/diffusers/sd-turbo/sd_turbo.safetensors \ --prompt "a red apple on a wooden table" \ --seed 42 --steps 1 --cfg-scale 0.0 --sampler euler_a \ --width 512 --height 512 \ --out /tmp/apple.png # Desde config JSON validado en spike notebook 02 imagegen_studio generate-from-json \ --config ~/vaults/imagegen_models/configs/spike01_seed42_*.json \ --out /tmp/seed42.png # HTTP API (feature flag activado) imagegen_studio serve --port 8088 & curl -X POST -H "Content-Type: application/json" \ -d @config.json http://localhost:8088/generate -o out.png ``` ## Decisiones - **Subprocess via SdcliGenerate** — no cgo ni bindings. Mas robusto, mas lento al arrancar (~200ms cold start), pero overhead irrelevante frente a 1-30s generacion. - **NO `go:embed` del binario `sd` en Fase A** — el binario depende de la GPU del usuario (CUDA/CPU/Vulkan). Documentar requisito: tener `sd` en $PATH (issue 0082). - **Feature flag para HTTP API** — Fase A es CLI, no romper master con server a medias. ## Prerequisitos - Issue 0082 (binario `sd` compilado en $PATH) — sin esto el smoke falla pero la app compila. Se puede arrancar el scaffolding antes. - Funciones Go de Ola 3.C (hechas). ## Riesgos - `sd-cli` no soporta SD Turbo cleanly con 1-step euler_a → puede requerir 4-step como minimo. Validar en issue 0082. - Distribucion sin binario `sd` empotrado obliga al usuario a instalarlo. Aceptable para Fase A; reevaluar `go:embed` con build-per-backend en Fase C+. - Si Fase 0 (spike) del documento revela calidad insuficiente: replantear stack y pausar este issue.