feat: media expansion surfaces — edit mask, upscale, background removal, interpolation, diarization, meshgen (ADR-0020)
CI / Tidy (pull_request) Successful in 9m23s
CI / Build & Test (pull_request) Successful in 10m24s
Adversarial Review (Gadfly) / review (pull_request) Successful in 15m37s

- imagegen.EditRequest.Mask -> sd-server img2img inpainting (white=repaint)
- imagegen.Upscaler + BackgroundRemover, videogen.Interpolator,
  audio.DiarizationModel: new optional provider-minted surfaces
- NEW meshgen leaf package (image->3D, glb/stl/obj)
- provider/llamaswap: all five via the /upstream/<model>/<path> passthrough
  (upstreamPath helper, shared one-file multipart builder); binary success
  bodies validated (non-image, non-video, JSON-mesh rejection); diarization
  pins output=json (vtt/srt drop speaker labels)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-12 23:52:34 -04:00
parent 900317af4e
commit e98493bcfb
15 changed files with 1546 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
package imagegen
import "context"
// BackgroundRemovalRequest asks a matting/segmentation backend to cut the
// subject out of an image. Zero values mean "backend default" (ADR-0020).
type BackgroundRemovalRequest struct {
// Image is the image to process. Required.
Image Image
// Net selects the remover's internal network where the backend offers
// several (rembg: "u2net", "birefnet-general", "isnet-general-use", ...);
// "" = backend default. This is NOT the provider model id — that is fixed
// when the BackgroundRemover is minted.
Net string
// OnlyMask returns the black/white segmentation mask instead of the
// cutout — white where the subject is. Useful as an inpainting mask
// (EditRequest.Mask semantics after inversion: the mask marks the
// FOREGROUND, an inpaint mask marks the region to REPAINT).
OnlyMask bool
}
// BackgroundRemovalOption mutates a BackgroundRemovalRequest before it is sent.
type BackgroundRemovalOption func(*BackgroundRemovalRequest)
// WithBackgroundNet selects the remover's internal network.
func WithBackgroundNet(n string) BackgroundRemovalOption {
return func(r *BackgroundRemovalRequest) { r.Net = n }
}
// WithOnlyMask requests the segmentation mask instead of the cutout.
func WithOnlyMask() BackgroundRemovalOption {
return func(r *BackgroundRemovalRequest) { r.OnlyMask = true }
}
// Apply returns a copy of the request with all options applied.
func (r BackgroundRemovalRequest) Apply(opts ...BackgroundRemovalOption) BackgroundRemovalRequest {
for _, opt := range opts {
opt(&r)
}
return r
}
// BackgroundRemover cuts subjects out of images (RGBA PNG with transparent
// background, or the mask alone with OnlyMask).
type BackgroundRemover interface {
// RemoveBackground returns the cutout (or mask) as a one-image Result.
RemoveBackground(ctx context.Context, req BackgroundRemovalRequest, opts ...BackgroundRemovalOption) (*Result, error)
}
// BackgroundRemovalModelOption configures a BackgroundRemover at construction
// time. Reserved for future per-model settings.
type BackgroundRemovalModelOption func(*BackgroundRemovalModelConfig)
// BackgroundRemovalModelConfig carries per-model construction settings.
type BackgroundRemovalModelConfig struct{}
// ApplyBackgroundRemovalModelOptions folds options into a config.
func ApplyBackgroundRemovalModelOptions(opts []BackgroundRemovalModelOption) BackgroundRemovalModelConfig {
var cfg BackgroundRemovalModelConfig
for _, opt := range opts {
opt(&cfg)
}
return cfg
}
// BackgroundRemovalProvider mints BackgroundRemovers bound to one backend.
type BackgroundRemovalProvider interface {
// Name is the registry identifier for the provider.
Name() string
// BackgroundRemovalModel returns a BackgroundRemover bound to the given
// id (passed through to the backend verbatim; no catalog validation).
BackgroundRemovalModel(id string, opts ...BackgroundRemovalModelOption) (BackgroundRemover, error)
}
+9
View File
@@ -12,6 +12,12 @@ type EditRequest struct {
// Init is the initial image the edit starts from. Required.
Init Image
// Mask restricts the edit to a region (inpainting): a single-channel or
// RGB image the same size as Init where WHITE pixels are repainted and
// BLACK pixels are kept. Empty = whole-image edit. Backends without mask
// support must reject a masked request rather than silently ignoring it.
Mask Image
// Strength is the denoising strength in [0,1] — how far the result may
// depart from Init (0 = return the input, 1 = ignore it); nil = backend
// default.
@@ -45,6 +51,9 @@ type EditRequest struct {
// are applied to a copy of the request, so an EditRequest value can be reused.
type EditOption func(*EditRequest)
// WithEditMask restricts the edit to a region (white = repaint, black = keep).
func WithEditMask(m Image) EditOption { return func(r *EditRequest) { r.Mask = m } }
// WithEditStrength sets the denoising strength in [0,1].
func WithEditStrength(s float64) EditOption { return func(r *EditRequest) { r.Strength = &s } }
+62
View File
@@ -0,0 +1,62 @@
package imagegen
import "context"
// UpscaleRequest asks a super-resolution backend to enlarge an image. Zero
// values mean "backend default", mirroring EditRequest (ADR-0020).
type UpscaleRequest struct {
// Image is the image to upscale. Required.
Image Image
// Scale is the enlargement factor (2 or 4 on the reference backend);
// 0 = backend default.
Scale int
}
// UpscaleOption mutates an UpscaleRequest before it is sent.
type UpscaleOption func(*UpscaleRequest)
// WithUpscaleScale sets the enlargement factor.
func WithUpscaleScale(s int) UpscaleOption { return func(r *UpscaleRequest) { r.Scale = s } }
// Apply returns a copy of the request with all options applied.
func (r UpscaleRequest) Apply(opts ...UpscaleOption) UpscaleRequest {
for _, opt := range opts {
opt(&r)
}
return r
}
// Upscaler enlarges images with a super-resolution model. It is its own
// small interface (not a method on Model) because upscalers are not
// diffusion models — they bind to a different backend id entirely.
type Upscaler interface {
// Upscale returns the enlarged image (a one-image Result).
Upscale(ctx context.Context, req UpscaleRequest, opts ...UpscaleOption) (*Result, error)
}
// UpscaleModelOption configures an Upscaler at construction time. Reserved
// for future per-model settings (mirrors ModelOption).
type UpscaleModelOption func(*UpscaleModelConfig)
// UpscaleModelConfig carries per-model construction settings.
type UpscaleModelConfig struct{}
// ApplyUpscaleModelOptions folds options into a config.
func ApplyUpscaleModelOptions(opts []UpscaleModelOption) UpscaleModelConfig {
var cfg UpscaleModelConfig
for _, opt := range opts {
opt(&cfg)
}
return cfg
}
// UpscaleProvider mints Upscalers bound to one backend.
type UpscaleProvider interface {
// Name is the registry identifier for the provider.
Name() string
// UpscaleModel returns an Upscaler bound to the given id (passed through
// to the backend verbatim; no catalog validation).
UpscaleModel(id string, opts ...UpscaleModelOption) (Upscaler, error)
}