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
+82
View File
@@ -0,0 +1,82 @@
package videogen
import "context"
// InterpolateRequest asks a frame-interpolation backend (RIFE-style) to
// synthesize intermediate frames in an existing clip. Zero values mean
// "backend default" (ADR-0020).
type InterpolateRequest struct {
// Video is the clip to interpolate. Required.
Video Video
// Multi is the frame multiplier (2 or 4 on the reference backend);
// 0 = backend default (2).
Multi int
// SlowMo plays the synthesized frames at the SOURCE frame rate instead of
// multiplying it: Multi-times slow motion. The backend strips audio in
// this mode (time-stretched audio is noise).
SlowMo bool
// TargetFPS resamples the smoothed clip to a specific frame rate
// (e.g. 60); 0 = Multi times the source rate. Ignored in SlowMo mode.
TargetFPS int
}
// InterpolateOption mutates an InterpolateRequest before it is sent.
type InterpolateOption func(*InterpolateRequest)
// WithInterpolateMulti sets the frame multiplier.
func WithInterpolateMulti(m int) InterpolateOption {
return func(r *InterpolateRequest) { r.Multi = m }
}
// WithSlowMo switches to slow-motion output.
func WithSlowMo() InterpolateOption { return func(r *InterpolateRequest) { r.SlowMo = true } }
// WithTargetFPS resamples the smoothed clip to a specific frame rate.
func WithTargetFPS(fps int) InterpolateOption {
return func(r *InterpolateRequest) { r.TargetFPS = fps }
}
// Apply returns a copy of the request with all options applied.
func (r InterpolateRequest) Apply(opts ...InterpolateOption) InterpolateRequest {
for _, opt := range opts {
opt(&r)
}
return r
}
// Interpolator synthesizes intermediate frames (fps boost or slow-mo). Its
// own small interface rather than a method on Model: interpolators are not
// generators — they bind to a different backend id entirely.
type Interpolator interface {
// Interpolate returns the smoothed (or slowed) clip.
Interpolate(ctx context.Context, req InterpolateRequest, opts ...InterpolateOption) (*Result, error)
}
// InterpolatorModelOption configures an Interpolator at construction time.
// Reserved for future per-model settings.
type InterpolatorModelOption func(*InterpolatorModelConfig)
// InterpolatorModelConfig carries per-model construction settings.
type InterpolatorModelConfig struct{}
// ApplyInterpolatorModelOptions folds options into a config.
func ApplyInterpolatorModelOptions(opts []InterpolatorModelOption) InterpolatorModelConfig {
var cfg InterpolatorModelConfig
for _, opt := range opts {
opt(&cfg)
}
return cfg
}
// InterpolationProvider mints Interpolators bound to one backend.
type InterpolationProvider interface {
// Name is the registry identifier for the provider.
Name() string
// InterpolatorModel returns an Interpolator bound to the given id (passed
// through to the backend verbatim; no catalog validation).
InterpolatorModel(id string, opts ...InterpolatorModelOption) (Interpolator, error)
}