434d721b99
- New leaf package `audio` (ADR-0017): SpeechModel/SpeechProvider and TranscriptionModel/TranscriptionProvider with imagegen conventions (zero value = backend default, functional options + Apply, bytes in/out, never URLs). Root re-exports added. - imagegen.Editor (ADR-0018): optional image-to-image interface — EditRequest carries the generation knobs plus Init image and denoising Strength; separate interface so existing Models keep compiling. - provider/llamaswap implements all of it: POST /v1/audio/speech (JSON, raw-audio response, MIME from Content-Type with format fallback), POST /v1/audio/transcriptions (multipart, response_format=json), ListVoices (GET /v1/audio/voices?model=, tolerant of string-list and object-list shapes), POST /sdapi/v1/img2img (txt2img wire + init_images/denoising_strength, shared image decode), and Health(ctx) (GET /health) — a cheap liveness probe for often-offline hosts. - Hermetic httptest coverage for every new wire shape and validation path; README sections + support-matrix footnote updated in the same commit (also corrects the stale /v1/images/generations claim — the image path has been SDAPI since the seed fix). First consumer: mort's llamaswap media tool cluster (status / image / TTS / STT agent tools against the netherstorm host). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AXQxVhXBw8PwFAtsVrXSmj
1.7 KiB
1.7 KiB
ADR-0018: imagegen.Editor — image-to-image as a separate optional interface
Status: Accepted — 2026-07-11
Context
ADR-0016 shipped text-to-image and explicitly deferred img2img. mort's new
llama-swap media tools need "edit this image under this prompt"
(image-to-image with a denoising strength). Two shape questions: does Edit
belong on imagegen.Model, and which llama-swap endpoint carries it —
OpenAI-style /v1/images/edits (multipart) or A1111-style /sdapi/v1/img2img
(JSON)?
Decision
Editoris a separate, optional interface (Edit(ctx, EditRequest, ...EditOption) (*Result, error)), not a new method onModel. ExistingModelimplementations keep compiling; callers type-assert (m.(imagegen.Editor)) or require the capability explicitly.EditRequest= the generation knobs (prompt, N, size, steps, cfg, negative prompt, sampler, seed) plusInit Image(required) andStrength *float64(denoising strength in [0,1]; nil = backend default). Same option/Apply conventions; result type is the sharedResult.- llama-swap implements it via
/sdapi/v1/img2img, not/v1/images/edits: the same sd-server build that ignoresseedon the OpenAI images route (the reason txt2img went SDAPI in ADR-0016's implementation) applies; the JSON shape is txt2img's plusinit_images: ["<b64>"]+denoising_strength, so it reusesdoJSONverbatim, where the OpenAI route is multipart.
Consequences
- Backends that can't edit simply don't implement
Editor; no stub methods. - The init image travels base64-inline in JSON (~33% overhead) — acceptable at chat-image sizes; a future backend needing multipart can still satisfy the same interface.