fix: review findings — chain NaN/Inf + id hygiene, percent-escape jobPath, shared singleVideoResult
- SubmitChain rejects NaN/±Inf segment seconds with ErrUnsupported (previously an obscure json.Marshal error; NaN fails every comparison and +Inf passed the >= 0 check). - ChainStatus skips segment entries with no usable id — JSON null (which no-op-unmarshals into a string, previously appending ""), empty strings, and id-less objects; the unfiltered list survives in Raw. ChainJob.SegmentIDs doc now also says ChainSegmentResult takes the segment index, not an id string. - jobPath rejects '%' in job ids — %2F/%2E%2E percent-escapes decode back into path structure server-side, bypassing the literal check on this upstream-echoed value. - singleVideoResult moves to video.go next to videoMIME, and the two remaining hand-rolled copies of the video-result validation (videoModel.Generate, Interpolate) now use it — one validation, one message shape. - videogen.LipSyncer renamed to videogen.Lipsyncer for consistency with the rest of the surface's Lipsync* naming (LipsyncProvider, LipsyncModel, LipsyncRequest); not yet consumed downstream, so the rename is free now and never again. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WWCQcYStWXBYUy5sZWnbLT
This commit is contained in:
+6
-6
@@ -57,16 +57,16 @@ func (r LipsyncRequest) Apply(opts ...LipsyncOption) LipsyncRequest {
|
||||
return r
|
||||
}
|
||||
|
||||
// LipSyncer animates still portraits into talking-head clips. Its own small
|
||||
// Lipsyncer animates still portraits into talking-head clips. Its own small
|
||||
// interface rather than a method on Model: lip-syncers are not text-to-video
|
||||
// generators — they bind to a different backend id entirely.
|
||||
type LipSyncer interface {
|
||||
type Lipsyncer interface {
|
||||
// Lipsync returns the talking-head clip. Generation is slow (minutes);
|
||||
// bound the call with a context deadline.
|
||||
Lipsync(ctx context.Context, req LipsyncRequest, opts ...LipsyncOption) (*Result, error)
|
||||
}
|
||||
|
||||
// LipsyncModelOption configures a LipSyncer at construction time. Reserved
|
||||
// LipsyncModelOption configures a Lipsyncer at construction time. Reserved
|
||||
// for future per-model settings.
|
||||
type LipsyncModelOption func(*LipsyncModelConfig)
|
||||
|
||||
@@ -82,12 +82,12 @@ func ApplyLipsyncModelOptions(opts []LipsyncModelOption) LipsyncModelConfig {
|
||||
return cfg
|
||||
}
|
||||
|
||||
// LipsyncProvider mints LipSyncers bound to one backend.
|
||||
// LipsyncProvider mints Lipsyncers bound to one backend.
|
||||
type LipsyncProvider interface {
|
||||
// Name is the registry identifier for the provider.
|
||||
Name() string
|
||||
|
||||
// LipsyncModel returns a LipSyncer bound to the given id (passed through
|
||||
// LipsyncModel returns a Lipsyncer bound to the given id (passed through
|
||||
// to the backend verbatim; no catalog validation).
|
||||
LipsyncModel(id string, opts ...LipsyncModelOption) (LipSyncer, error)
|
||||
LipsyncModel(id string, opts ...LipsyncModelOption) (Lipsyncer, error)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user