Add Seriatim configuration contract
This commit is contained in:
12
README.md
12
README.md
@@ -16,6 +16,18 @@ WhisperX config contract in `pipeline.yml`:
|
|||||||
- required: `whisperx.transcribe_url`
|
- required: `whisperx.transcribe_url`
|
||||||
- defaulted when omitted: `whisperx.language` (`en`), `whisperx.timeout` (`30m`), `whisperx.retries` (`3`), `whisperx.retry_delay` (`2s`), `whisperx.concurrency` (`2`)
|
- defaulted when omitted: `whisperx.language` (`en`), `whisperx.timeout` (`30m`), `whisperx.retries` (`3`), `whisperx.retry_delay` (`2s`), `whisperx.concurrency` (`2`)
|
||||||
|
|
||||||
|
Seriatim config contract in `pipeline.yml`:
|
||||||
|
|
||||||
|
- required: `seriatim.binary` (name or path; existence is checked at execution time, not config validation time)
|
||||||
|
- defaulted when omitted: `seriatim.timeout` (`10m`), `seriatim.output_schema` (`seriatim-intermediate`), `seriatim.coalesce_gap` (`3.0`), `seriatim.report` (`true`)
|
||||||
|
- allowed `seriatim.output_schema` values: `seriatim-minimal`, `seriatim-intermediate`, `seriatim-full`
|
||||||
|
- optional tuning: `seriatim.env.*` (`overlap_word_run_gap`, `overlap_word_run_reorder_window`, `backchannel_max_duration`, `filler_max_duration`) must be `> 0` when provided
|
||||||
|
|
||||||
|
`speakers.yml` note:
|
||||||
|
|
||||||
|
- use Seriatim’s documented `match:` format (not the legacy direct mapping style used by older scripts/scaffolds)
|
||||||
|
- TODO: add a concrete `speakers.yml` example once the Seriatim README/spec is vendored or linked in-repo.
|
||||||
|
|
||||||
Decoding is strict (`KnownFields(true)`), so unknown YAML fields fail fast.
|
Decoding is strict (`KnownFields(true)`), so unknown YAML fields fail fast.
|
||||||
|
|
||||||
Example minimal files are available under `examples/`:
|
Example minimal files are available under `examples/`:
|
||||||
|
|||||||
@@ -115,6 +115,15 @@ WhisperX config keys:
|
|||||||
- `pipeline.whisperx.retry_delay` (default: `2s`)
|
- `pipeline.whisperx.retry_delay` (default: `2s`)
|
||||||
- `pipeline.whisperx.concurrency` (default: `2`)
|
- `pipeline.whisperx.concurrency` (default: `2`)
|
||||||
|
|
||||||
|
Seriatim config keys:
|
||||||
|
|
||||||
|
- `pipeline.seriatim.binary` (required)
|
||||||
|
- `pipeline.seriatim.timeout` (default: `10m`)
|
||||||
|
- `pipeline.seriatim.output_schema` (default: `seriatim-intermediate`; allowed: `seriatim-minimal|seriatim-intermediate|seriatim-full`)
|
||||||
|
- `pipeline.seriatim.coalesce_gap` (default: `3.0`, must be `>= 0`)
|
||||||
|
- `pipeline.seriatim.report` (default: `true`)
|
||||||
|
- optional tuning under `pipeline.seriatim.env.*` (must be `> 0` when provided)
|
||||||
|
|
||||||
Validation currently enforces:
|
Validation currently enforces:
|
||||||
|
|
||||||
- `pipeline.workspace.root` is required.
|
- `pipeline.workspace.root` is required.
|
||||||
@@ -122,6 +131,11 @@ Validation currently enforces:
|
|||||||
- `pipeline.whisperx.timeout` and `pipeline.whisperx.retry_delay` must parse as Go durations.
|
- `pipeline.whisperx.timeout` and `pipeline.whisperx.retry_delay` must parse as Go durations.
|
||||||
- `pipeline.whisperx.retries` must be `>= 0`.
|
- `pipeline.whisperx.retries` must be `>= 0`.
|
||||||
- `pipeline.whisperx.concurrency` must be `> 0`.
|
- `pipeline.whisperx.concurrency` must be `> 0`.
|
||||||
|
- `pipeline.seriatim.binary` is required.
|
||||||
|
- `pipeline.seriatim.timeout` must parse as Go duration.
|
||||||
|
- `pipeline.seriatim.output_schema` must be one of `seriatim-minimal|seriatim-intermediate|seriatim-full`.
|
||||||
|
- `pipeline.seriatim.coalesce_gap` must be `>= 0`.
|
||||||
|
- optional `pipeline.seriatim.env.*` values must be `> 0` when provided.
|
||||||
- `session.session_id` is required.
|
- `session.session_id` is required.
|
||||||
- `session.inputs.speakers_file`, `autocorrect_file`, `glossary_file` are required.
|
- `session.inputs.speakers_file`, `autocorrect_file`, `glossary_file` are required.
|
||||||
- At least one audio source: `session.inputs.audio_dir` or non-empty `session.inputs.audio_files`.
|
- At least one audio source: `session.inputs.audio_dir` or non-empty `session.inputs.audio_files`.
|
||||||
|
|||||||
@@ -13,7 +13,16 @@ whisperx:
|
|||||||
concurrency: 2
|
concurrency: 2
|
||||||
|
|
||||||
seriatim:
|
seriatim:
|
||||||
timeout: 30s
|
binary: "seriatim"
|
||||||
|
timeout: "10m"
|
||||||
|
output_schema: "seriatim-intermediate"
|
||||||
|
coalesce_gap: 3.0
|
||||||
|
report: true
|
||||||
|
env:
|
||||||
|
overlap_word_run_gap: 1.0
|
||||||
|
overlap_word_run_reorder_window: 1.0
|
||||||
|
backchannel_max_duration: 2.0
|
||||||
|
filler_max_duration: 1.25
|
||||||
|
|
||||||
audita:
|
audita:
|
||||||
timeout: 1h
|
timeout: 1h
|
||||||
|
|||||||
@@ -207,7 +207,11 @@ whisperx:
|
|||||||
retry_delay: 1ms
|
retry_delay: 1ms
|
||||||
concurrency: 1
|
concurrency: 1
|
||||||
seriatim:
|
seriatim:
|
||||||
timeout: 30s
|
binary: seriatim
|
||||||
|
timeout: 10m
|
||||||
|
output_schema: seriatim-intermediate
|
||||||
|
coalesce_gap: 3.0
|
||||||
|
report: true
|
||||||
audita:
|
audita:
|
||||||
timeout: 1h
|
timeout: 1h
|
||||||
analyzer:
|
analyzer:
|
||||||
|
|||||||
@@ -52,9 +52,20 @@ type WhisperXConfig struct {
|
|||||||
|
|
||||||
// SeriatimConfig configures seriatim adapter settings.
|
// SeriatimConfig configures seriatim adapter settings.
|
||||||
type SeriatimConfig struct {
|
type SeriatimConfig struct {
|
||||||
BinaryPath string `yaml:"binary_path"`
|
Binary string `yaml:"binary"`
|
||||||
Timeout string `yaml:"timeout"`
|
Timeout string `yaml:"timeout"`
|
||||||
Args []string `yaml:"args"`
|
OutputSchema string `yaml:"output_schema"`
|
||||||
|
CoalesceGap *float64 `yaml:"coalesce_gap"`
|
||||||
|
Report *bool `yaml:"report"`
|
||||||
|
Env SeriatimEnvConfig `yaml:"env"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeriatimEnvConfig configures optional advanced seriatim environment tuning.
|
||||||
|
type SeriatimEnvConfig struct {
|
||||||
|
OverlapWordRunGap *float64 `yaml:"overlap_word_run_gap"`
|
||||||
|
OverlapWordRunReorderWindow *float64 `yaml:"overlap_word_run_reorder_window"`
|
||||||
|
BackchannelMaxDuration *float64 `yaml:"backchannel_max_duration"`
|
||||||
|
FillerMaxDuration *float64 `yaml:"filler_max_duration"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuditaConfig configures audita adapter settings.
|
// AuditaConfig configures audita adapter settings.
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ func applyPipelineDefaults(cfg *PipelineConfig) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
applyWhisperXDefaults(&cfg.WhisperX)
|
applyWhisperXDefaults(&cfg.WhisperX)
|
||||||
|
applySeriatimDefaults(&cfg.Seriatim)
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyWhisperXDefaults(cfg *WhisperXConfig) {
|
func applyWhisperXDefaults(cfg *WhisperXConfig) {
|
||||||
@@ -109,3 +110,31 @@ func intPtr(v int) *int {
|
|||||||
p := v
|
p := v
|
||||||
return &p
|
return &p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func applySeriatimDefaults(cfg *SeriatimConfig) {
|
||||||
|
if cfg == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if cfg.Timeout == "" {
|
||||||
|
cfg.Timeout = "10m"
|
||||||
|
}
|
||||||
|
if cfg.OutputSchema == "" {
|
||||||
|
cfg.OutputSchema = "seriatim-intermediate"
|
||||||
|
}
|
||||||
|
if cfg.CoalesceGap == nil {
|
||||||
|
cfg.CoalesceGap = float64Ptr(3.0)
|
||||||
|
}
|
||||||
|
if cfg.Report == nil {
|
||||||
|
cfg.Report = boolPtr(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func float64Ptr(v float64) *float64 {
|
||||||
|
p := v
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
|
||||||
|
func boolPtr(v bool) *bool {
|
||||||
|
p := v
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ func TestLoadAndValidate(t *testing.T) {
|
|||||||
whisperx:
|
whisperx:
|
||||||
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
||||||
seriatim:
|
seriatim:
|
||||||
timeout: 30s
|
binary: seriatim
|
||||||
audita:
|
audita:
|
||||||
timeout: 1h
|
timeout: 1h
|
||||||
analyzer:
|
analyzer:
|
||||||
@@ -93,6 +93,8 @@ unknown_field: true
|
|||||||
root: /tmp/narratio
|
root: /tmp/narratio
|
||||||
whisperx:
|
whisperx:
|
||||||
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
||||||
|
seriatim:
|
||||||
|
binary: seriatim
|
||||||
`,
|
`,
|
||||||
sessionYAML: `session_id: ""
|
sessionYAML: `session_id: ""
|
||||||
inputs:
|
inputs:
|
||||||
@@ -108,6 +110,8 @@ inputs:
|
|||||||
pipelineYAML: `workspace:
|
pipelineYAML: `workspace:
|
||||||
root: /tmp/narratio
|
root: /tmp/narratio
|
||||||
whisperx:
|
whisperx:
|
||||||
|
seriatim:
|
||||||
|
binary: seriatim
|
||||||
`,
|
`,
|
||||||
sessionYAML: `session_id: 2026-05-03
|
sessionYAML: `session_id: 2026-05-03
|
||||||
inputs:
|
inputs:
|
||||||
@@ -124,6 +128,8 @@ inputs:
|
|||||||
root: /tmp/narratio
|
root: /tmp/narratio
|
||||||
whisperx:
|
whisperx:
|
||||||
transcribe_url: ://
|
transcribe_url: ://
|
||||||
|
seriatim:
|
||||||
|
binary: seriatim
|
||||||
`,
|
`,
|
||||||
sessionYAML: `session_id: 2026-05-03
|
sessionYAML: `session_id: 2026-05-03
|
||||||
inputs:
|
inputs:
|
||||||
@@ -141,6 +147,8 @@ inputs:
|
|||||||
whisperx:
|
whisperx:
|
||||||
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
||||||
timeout: definitely-not-a-duration
|
timeout: definitely-not-a-duration
|
||||||
|
seriatim:
|
||||||
|
binary: seriatim
|
||||||
`,
|
`,
|
||||||
sessionYAML: `session_id: 2026-05-03
|
sessionYAML: `session_id: 2026-05-03
|
||||||
inputs:
|
inputs:
|
||||||
@@ -158,6 +166,8 @@ inputs:
|
|||||||
whisperx:
|
whisperx:
|
||||||
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
||||||
retry_delay: not-a-duration
|
retry_delay: not-a-duration
|
||||||
|
seriatim:
|
||||||
|
binary: seriatim
|
||||||
`,
|
`,
|
||||||
sessionYAML: `session_id: 2026-05-03
|
sessionYAML: `session_id: 2026-05-03
|
||||||
inputs:
|
inputs:
|
||||||
@@ -175,6 +185,8 @@ inputs:
|
|||||||
whisperx:
|
whisperx:
|
||||||
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
||||||
retries: -1
|
retries: -1
|
||||||
|
seriatim:
|
||||||
|
binary: seriatim
|
||||||
`,
|
`,
|
||||||
sessionYAML: `session_id: 2026-05-03
|
sessionYAML: `session_id: 2026-05-03
|
||||||
inputs:
|
inputs:
|
||||||
@@ -192,6 +204,8 @@ inputs:
|
|||||||
whisperx:
|
whisperx:
|
||||||
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
||||||
concurrency: 0
|
concurrency: 0
|
||||||
|
seriatim:
|
||||||
|
binary: seriatim
|
||||||
`,
|
`,
|
||||||
sessionYAML: `session_id: 2026-05-03
|
sessionYAML: `session_id: 2026-05-03
|
||||||
inputs:
|
inputs:
|
||||||
@@ -202,6 +216,140 @@ inputs:
|
|||||||
`,
|
`,
|
||||||
wantValidate: "pipeline config \"pipeline.yml\" invalid: pipeline.whisperx.concurrency must be > 0",
|
wantValidate: "pipeline config \"pipeline.yml\" invalid: pipeline.whisperx.concurrency must be > 0",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "unknown seriatim field fails",
|
||||||
|
pipelineYAML: `workspace:
|
||||||
|
root: /tmp/narratio
|
||||||
|
whisperx:
|
||||||
|
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
||||||
|
seriatim:
|
||||||
|
binary: seriatim
|
||||||
|
bogus: true
|
||||||
|
`,
|
||||||
|
sessionYAML: `session_id: 2026-05-03
|
||||||
|
inputs:
|
||||||
|
audio_dir: ./audio
|
||||||
|
speakers_file: ./speakers.yml
|
||||||
|
autocorrect_file: ./autocorrect.yml
|
||||||
|
glossary_file: ./glossary.yml
|
||||||
|
`,
|
||||||
|
wantLoadErr: "strict decode failed",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unknown seriatim env field fails",
|
||||||
|
pipelineYAML: `workspace:
|
||||||
|
root: /tmp/narratio
|
||||||
|
whisperx:
|
||||||
|
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
||||||
|
seriatim:
|
||||||
|
binary: seriatim
|
||||||
|
env:
|
||||||
|
unknown_knob: 1.0
|
||||||
|
`,
|
||||||
|
sessionYAML: `session_id: 2026-05-03
|
||||||
|
inputs:
|
||||||
|
audio_dir: ./audio
|
||||||
|
speakers_file: ./speakers.yml
|
||||||
|
autocorrect_file: ./autocorrect.yml
|
||||||
|
glossary_file: ./glossary.yml
|
||||||
|
`,
|
||||||
|
wantLoadErr: "strict decode failed",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "missing seriatim binary fails",
|
||||||
|
pipelineYAML: `workspace:
|
||||||
|
root: /tmp/narratio
|
||||||
|
whisperx:
|
||||||
|
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
||||||
|
seriatim:
|
||||||
|
timeout: 10m
|
||||||
|
`,
|
||||||
|
sessionYAML: `session_id: 2026-05-03
|
||||||
|
inputs:
|
||||||
|
audio_dir: ./audio
|
||||||
|
speakers_file: ./speakers.yml
|
||||||
|
autocorrect_file: ./autocorrect.yml
|
||||||
|
glossary_file: ./glossary.yml
|
||||||
|
`,
|
||||||
|
wantValidate: "pipeline config \"pipeline.yml\" invalid: pipeline.seriatim.binary is required",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid seriatim timeout fails",
|
||||||
|
pipelineYAML: `workspace:
|
||||||
|
root: /tmp/narratio
|
||||||
|
whisperx:
|
||||||
|
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
||||||
|
seriatim:
|
||||||
|
binary: seriatim
|
||||||
|
timeout: not-a-duration
|
||||||
|
`,
|
||||||
|
sessionYAML: `session_id: 2026-05-03
|
||||||
|
inputs:
|
||||||
|
audio_dir: ./audio
|
||||||
|
speakers_file: ./speakers.yml
|
||||||
|
autocorrect_file: ./autocorrect.yml
|
||||||
|
glossary_file: ./glossary.yml
|
||||||
|
`,
|
||||||
|
wantValidate: "pipeline config \"pipeline.yml\" invalid: pipeline.seriatim.timeout must be a valid duration",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid seriatim output schema fails",
|
||||||
|
pipelineYAML: `workspace:
|
||||||
|
root: /tmp/narratio
|
||||||
|
whisperx:
|
||||||
|
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
||||||
|
seriatim:
|
||||||
|
binary: seriatim
|
||||||
|
output_schema: invalid-schema
|
||||||
|
`,
|
||||||
|
sessionYAML: `session_id: 2026-05-03
|
||||||
|
inputs:
|
||||||
|
audio_dir: ./audio
|
||||||
|
speakers_file: ./speakers.yml
|
||||||
|
autocorrect_file: ./autocorrect.yml
|
||||||
|
glossary_file: ./glossary.yml
|
||||||
|
`,
|
||||||
|
wantValidate: "pipeline config \"pipeline.yml\" invalid: pipeline.seriatim.output_schema must be one of: seriatim-minimal, seriatim-intermediate, seriatim-full",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "negative seriatim coalesce gap fails",
|
||||||
|
pipelineYAML: `workspace:
|
||||||
|
root: /tmp/narratio
|
||||||
|
whisperx:
|
||||||
|
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
||||||
|
seriatim:
|
||||||
|
binary: seriatim
|
||||||
|
coalesce_gap: -0.1
|
||||||
|
`,
|
||||||
|
sessionYAML: `session_id: 2026-05-03
|
||||||
|
inputs:
|
||||||
|
audio_dir: ./audio
|
||||||
|
speakers_file: ./speakers.yml
|
||||||
|
autocorrect_file: ./autocorrect.yml
|
||||||
|
glossary_file: ./glossary.yml
|
||||||
|
`,
|
||||||
|
wantValidate: "pipeline config \"pipeline.yml\" invalid: pipeline.seriatim.coalesce_gap must be >= 0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid seriatim env float fails",
|
||||||
|
pipelineYAML: `workspace:
|
||||||
|
root: /tmp/narratio
|
||||||
|
whisperx:
|
||||||
|
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
|
||||||
|
seriatim:
|
||||||
|
binary: seriatim
|
||||||
|
env:
|
||||||
|
overlap_word_run_gap: 0
|
||||||
|
`,
|
||||||
|
sessionYAML: `session_id: 2026-05-03
|
||||||
|
inputs:
|
||||||
|
audio_dir: ./audio
|
||||||
|
speakers_file: ./speakers.yml
|
||||||
|
autocorrect_file: ./autocorrect.yml
|
||||||
|
glossary_file: ./glossary.yml
|
||||||
|
`,
|
||||||
|
wantValidate: "pipeline config \"pipeline.yml\" invalid: pipeline.seriatim.env.overlap_word_run_gap must be > 0 when provided",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@@ -247,6 +395,18 @@ inputs:
|
|||||||
if cfg.Pipeline.WhisperX.Concurrency == nil || *cfg.Pipeline.WhisperX.Concurrency != 2 {
|
if cfg.Pipeline.WhisperX.Concurrency == nil || *cfg.Pipeline.WhisperX.Concurrency != 2 {
|
||||||
t.Fatalf("whisperx.concurrency = %v, want 2", cfg.Pipeline.WhisperX.Concurrency)
|
t.Fatalf("whisperx.concurrency = %v, want 2", cfg.Pipeline.WhisperX.Concurrency)
|
||||||
}
|
}
|
||||||
|
if cfg.Pipeline.Seriatim.Timeout != "10m" {
|
||||||
|
t.Fatalf("seriatim.timeout = %q, want %q", cfg.Pipeline.Seriatim.Timeout, "10m")
|
||||||
|
}
|
||||||
|
if cfg.Pipeline.Seriatim.OutputSchema != "seriatim-intermediate" {
|
||||||
|
t.Fatalf("seriatim.output_schema = %q, want %q", cfg.Pipeline.Seriatim.OutputSchema, "seriatim-intermediate")
|
||||||
|
}
|
||||||
|
if cfg.Pipeline.Seriatim.CoalesceGap == nil || *cfg.Pipeline.Seriatim.CoalesceGap != 3.0 {
|
||||||
|
t.Fatalf("seriatim.coalesce_gap = %v, want 3.0", cfg.Pipeline.Seriatim.CoalesceGap)
|
||||||
|
}
|
||||||
|
if cfg.Pipeline.Seriatim.Report == nil || *cfg.Pipeline.Seriatim.Report != true {
|
||||||
|
t.Fatalf("seriatim.report = %v, want true", cfg.Pipeline.Seriatim.Report)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = Validate(cfg)
|
err = Validate(cfg)
|
||||||
@@ -280,6 +440,13 @@ func TestValidateMissingAudioSource(t *testing.T) {
|
|||||||
RetryDelay: "2s",
|
RetryDelay: "2s",
|
||||||
Concurrency: &concurrency,
|
Concurrency: &concurrency,
|
||||||
},
|
},
|
||||||
|
Seriatim: SeriatimConfig{
|
||||||
|
Binary: "seriatim",
|
||||||
|
Timeout: "10m",
|
||||||
|
OutputSchema: "seriatim-intermediate",
|
||||||
|
CoalesceGap: float64Ptr(3.0),
|
||||||
|
Report: boolPtr(true),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Session: &SessionConfig{
|
Session: &SessionConfig{
|
||||||
SessionID: "2026-05-03",
|
SessionID: "2026-05-03",
|
||||||
|
|||||||
@@ -36,8 +36,7 @@ func validatePipeline(cfg *PipelineConfig) error {
|
|||||||
if err := validateWhisperX(cfg.WhisperX); err != nil {
|
if err := validateWhisperX(cfg.WhisperX); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := validateSeriatim(cfg.Seriatim); err != nil {
|
||||||
if err := validateDuration("pipeline.seriatim.timeout", cfg.Seriatim.Timeout); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := validateDuration("pipeline.audita.timeout", cfg.Audita.Timeout); err != nil {
|
if err := validateDuration("pipeline.audita.timeout", cfg.Audita.Timeout); err != nil {
|
||||||
@@ -85,6 +84,44 @@ func validateWhisperX(cfg WhisperXConfig) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateSeriatim(cfg SeriatimConfig) error {
|
||||||
|
if strings.TrimSpace(cfg.Binary) == "" {
|
||||||
|
return fmt.Errorf("pipeline.seriatim.binary is required")
|
||||||
|
}
|
||||||
|
if err := validateDuration("pipeline.seriatim.timeout", cfg.Timeout); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch cfg.OutputSchema {
|
||||||
|
case "seriatim-minimal", "seriatim-intermediate", "seriatim-full":
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("pipeline.seriatim.output_schema must be one of: seriatim-minimal, seriatim-intermediate, seriatim-full")
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.CoalesceGap == nil {
|
||||||
|
return fmt.Errorf("pipeline.seriatim.coalesce_gap must be set (defaults should populate this)")
|
||||||
|
}
|
||||||
|
if *cfg.CoalesceGap < 0 {
|
||||||
|
return fmt.Errorf("pipeline.seriatim.coalesce_gap must be >= 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range []struct {
|
||||||
|
name string
|
||||||
|
value *float64
|
||||||
|
}{
|
||||||
|
{name: "pipeline.seriatim.env.overlap_word_run_gap", value: cfg.Env.OverlapWordRunGap},
|
||||||
|
{name: "pipeline.seriatim.env.overlap_word_run_reorder_window", value: cfg.Env.OverlapWordRunReorderWindow},
|
||||||
|
{name: "pipeline.seriatim.env.backchannel_max_duration", value: cfg.Env.BackchannelMaxDuration},
|
||||||
|
{name: "pipeline.seriatim.env.filler_max_duration", value: cfg.Env.FillerMaxDuration},
|
||||||
|
} {
|
||||||
|
if item.value != nil && *item.value <= 0 {
|
||||||
|
return fmt.Errorf("%s must be > 0 when provided", item.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func validateSession(cfg *SessionConfig) error {
|
func validateSession(cfg *SessionConfig) error {
|
||||||
if strings.TrimSpace(cfg.SessionID) == "" {
|
if strings.TrimSpace(cfg.SessionID) == "" {
|
||||||
return fmt.Errorf("session.session_id is required")
|
return fmt.Errorf("session.session_id is required")
|
||||||
|
|||||||
Reference in New Issue
Block a user