Models
src.xil_pipeline.models
Pydantic data models for the podcast production pipeline.
Defines validated, typed structures for script parsing output, cast configuration, and production dialogue entries. These models replace untyped dictionaries with field-level validation and type annotations that render as rich API documentation via mkdocstrings.
TYPE_DEFAULTS
module-attribute
TYPE_DEFAULTS: dict[str, dict] = {'podcast': {'gap_ms': 600, 'stability': None}, 'audiobook': {'gap_ms': 400, 'stability': 0.75}, 'drama': {'gap_ms': 800, 'stability': None}, 'special': {'gap_ms': 600, 'stability': None}}
ProjectConfig
Bases: _DocModel
Typed view of project.json.
All fields are optional with sensible defaults so that a minimal
{"show": "My Show"} project.json validates without change.
Source code in src/xil_pipeline/models.py
show
class-attribute
instance-attribute
Human-readable show title.
type
class-attribute
instance-attribute
Content type — "podcast" (default), "audiobook", "drama", or
"special". Drives section maps, gap defaults, and xil-init sample templates.
season
class-attribute
instance-attribute
Season number, or None.
season_title
class-attribute
instance-attribute
Season arc title (e.g. "The Holiday Shift").
ScriptEntry
Bases: _DocModel
A single parsed entry from a production script.
Each entry represents one line or block from the markdown script, classified into one of four types: dialogue, direction, section_header, or scene_header.
Source code in src/xil_pipeline/models.py
seq
class-attribute
instance-attribute
Sequence number, 1-based and unique within a script.
type
class-attribute
instance-attribute
Entry classification determining how the line is processed.
section
class-attribute
instance-attribute
Current section slug (e.g., "cold-open", "act1").
scene
class-attribute
instance-attribute
Current scene slug (e.g., "scene-1") or None.
speaker
class-attribute
instance-attribute
Normalized speaker key for dialogue entries (e.g., "adam").
direction
class-attribute
instance-attribute
Parenthetical acting direction for dialogue lines.
text
class-attribute
instance-attribute
The spoken text, header text, or stage direction content.
direction_type
class-attribute
instance-attribute
direction_type: Literal['SFX', 'MUSIC', 'AMBIENCE', 'BEAT', 'VINTAGE FILTER'] | None = Field(default=None)
Subtype for direction entries indicating sound category.
sfx_source
class-attribute
instance-attribute
Scriptwriter SFX source hint (e.g. 'SFX/filename.mp3'), stripped from the
'| filename' annotation in the script.
sfx_overrides
class-attribute
instance-attribute
Per-cue :class:SfxEntry overrides from the script's attribute hints, keyed by
config field name — '| play_volume_pct=20%' yields
{"volume_percentage": 20.0}. Applied on top of the generated SFX config entry;
the script wins over any value already in sfx_<TAG>.json.
ScriptStats
Bases: _DocModel
Aggregate statistics for a parsed production script.
Source code in src/xil_pipeline/models.py
total_entries
class-attribute
instance-attribute
Total number of parsed entries.
dialogue_lines
class-attribute
instance-attribute
Count of dialogue-type entries.
direction_lines
class-attribute
instance-attribute
Count of direction-type entries.
characters_for_tts
class-attribute
instance-attribute
Total character count across all dialogue text.
speakers
class-attribute
instance-attribute
Sorted list of unique speaker keys found in the script.
ParsedScript
Bases: _DocModel
Complete output of the script parsing stage.
Produced by parse_script() in XILP001, consumed by
load_production() in XILP002.
Source code in src/xil_pipeline/models.py
season
class-attribute
instance-attribute
Season number, or None if not declared in the script header.
season_title
class-attribute
instance-attribute
Season arc title extracted from Arc: "…" in the script header (e.g.
"The Holiday Shift"). None when the header contains no arc declaration.
source_file
class-attribute
instance-attribute
Basename of the source markdown file.
entries
class-attribute
instance-attribute
Ordered list of parsed script entries.
stats
class-attribute
instance-attribute
Aggregate statistics for the parsed script.
CastMember
Bases: _DocModel
Configuration for a single cast member's voice and audio settings.
Maps a character to their ElevenLabs voice and stereo positioning.
Source code in src/xil_pipeline/models.py
full_name
class-attribute
instance-attribute
Character's display name (e.g., "Adam Santos").
voice_id
class-attribute
instance-attribute
ElevenLabs voice identifier; "TBD" if unassigned, or "" for
non-ElevenLabs backends.
pan
class-attribute
instance-attribute
Stereo pan position from -1.0 (full left) to 1.0 (full right).
filter
class-attribute
instance-attribute
Audio filter chain. False/None = none; True/"phone" = phone
filter; "vintage" = vintage filter; "vintage,phone" = both filters applied
in listed order.
role
class-attribute
instance-attribute
Character role description (e.g., "Host/Narrator").
stability
class-attribute
instance-attribute
Voice stability (0=expressive, 1=monotone); None uses voice default.
similarity_boost
class-attribute
instance-attribute
Adherence to original voice (0=loose, 1=strict); None uses voice default.
style
class-attribute
instance-attribute
Style exaggeration of the original speaker; None uses voice default.
use_speaker_boost
class-attribute
instance-attribute
Boost similarity to original speaker (higher latency); None uses voice default.
language_code
class-attribute
instance-attribute
ISO 639-1 language code for text normalisation (e.g. 'en', 'de'); None = auto.
PreambleSegment
Bases: _DocModel
One text slice of a multi-part preamble or postamble.
Source code in src/xil_pipeline/models.py
text
class-attribute
instance-attribute
Spoken text (may use {season_title}, {episode}, {title} placeholders).
Preamble
Bases: _DocModel
Broadcast introduction prepended to every episode.
Source code in src/xil_pipeline/models.py
text
class-attribute
instance-attribute
Single-string intro text (legacy; may use {season_title}, {episode}, {title}
placeholders). Mutually exclusive with segments.
segments
class-attribute
instance-attribute
Ordered list of cacheable text segments (preferred over text for new
episodes). Stock segments carry a shared_key so they are generated once and
reused; the variable episode-identifier segment has shared_key=None.
speaker
class-attribute
instance-attribute
Cast key for the reader (e.g. "tina").
CastConfiguration
Bases: _DocModel
Complete cast configuration for a production episode.
Loaded from the cast config JSON and used by load_production()
to map speaker keys to voice and audio settings.
Source code in src/xil_pipeline/models.py
season
class-attribute
instance-attribute
Season number, or None if not set in the cast file.
episode
class-attribute
instance-attribute
Episode number.
tag_override
class-attribute
instance-attribute
Raw tag for non-episodic content (e.g. V01C03, D01) — overrides
season/episode derivation.
title
class-attribute
instance-attribute
Episode title (optional, not used during production).
season_title
class-attribute
instance-attribute
Season subtitle/arc title (e.g., "The Letters").
artist
class-attribute
instance-attribute
Artist/creator credit for audio metadata.
preamble
class-attribute
instance-attribute
Broadcast intro configuration, or None if not configured.
postamble
class-attribute
instance-attribute
Broadcast outro configuration, or None if not configured.
cast
class-attribute
instance-attribute
Mapping of speaker keys to their voice configurations.
VoiceConfig
Bases: _DocModel
Simplified voice configuration used during voice generation.
Built from CastMember by load_production(), carrying only
the fields needed for TTS generation and audio assembly.
Source code in src/xil_pipeline/models.py
pan
class-attribute
instance-attribute
Stereo pan position from -1.0 (full left) to 1.0 (full right).
DialogueEntry
Bases: _DocModel
A single dialogue line prepared for voice generation.
Produced by load_production() from parsed script entries,
enriched with the stem filename for audio output.
Source code in src/xil_pipeline/models.py
speaker
class-attribute
instance-attribute
Normalized speaker key (e.g., "adam").
stem_name
class-attribute
instance-attribute
Output filename stem (e.g., "003_cold-open_adam").
seq
class-attribute
instance-attribute
Sequence number from the parsed script.
section
class-attribute
instance-attribute
Script section slug (e.g. 'preamble', 'act1').
SfxEntry
Bases: _DocModel
A single sound effect mapping from script direction to API parameters.
Maps a direction entry's text (e.g., "SFX: PHONE BUZZING") to the
ElevenLabs Sound Effects API parameters needed to generate it, or marks
it as silence (for BEAT entries).
Note: per-effect volume is always volume_percentage, not the prefixed
form (ambience_volume_percentage etc.) — those belong in defaults only.
Source code in src/xil_pipeline/models.py
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 | |
prompt
class-attribute
instance-attribute
Natural-language description for the ElevenLabs SFX API. None for
type="silence" or source-based entries (no generation).
type
class-attribute
instance-attribute
Whether this is an API-generated sound effect ("sfx") or local silence
("silence", e.g. a BEAT stop marker).
duration_seconds
class-attribute
instance-attribute
Audio length in seconds — meaning depends on the entry kind. For
API-generated cues (no source), the requested generation length (must be
0 and ≤ 30). For
source=cues, clips the file to this many seconds at mix time unlessplay_durationis set;0plays the source full-length. Fortype="silence", the silence duration (0.0= stop marker).
prompt_influence
class-attribute
instance-attribute
How closely the ElevenLabs output follows the prompt (0.0–1.0); None
uses the config-level default.
loop
class-attribute
instance-attribute
Whether to generate loopable audio (useful for ambience beds).
source
class-attribute
instance-attribute
Path to a pre-existing audio file. When set, bypasses API generation and the
file is used directly; length is governed by play_duration /
duration_seconds (see those fields).
volume_percentage
class-attribute
instance-attribute
Per-effect playback volume as a percentage (100 = unity gain, 0–200); None
uses the category default. Always the un-prefixed form (the prefixed variants
belong in defaults only).
ramp_in_seconds
class-attribute
instance-attribute
Fade-in duration in seconds (0–30); None uses the category default.
ramp_out_seconds
class-attribute
instance-attribute
Fade-out duration in seconds (0–30); None uses the category default.
play_duration
class-attribute
instance-attribute
Percentage of the clip to play (0–100; 100 = full). Applies to source=
one-shots (SFX/MUSIC/BEAT) and takes precedence over duration_seconds
when set. None plays the full clip, subject to any duration_seconds
clipping.
SfxConfiguration
Bases: _DocModel
Sound effects configuration for a production episode.
Analogous to :class:CastConfiguration for voices. Maps parsed
direction entry text to ElevenLabs Sound Effects API parameters.
Source code in src/xil_pipeline/models.py
season
class-attribute
instance-attribute
Season number, or None if not declared.
episode
class-attribute
instance-attribute
Episode number.
tag_override
class-attribute
instance-attribute
Raw tag for non-episodic content (e.g. V01C03, D01) — overrides
season/episode derivation.
defaults
class-attribute
instance-attribute
Shared default settings (e.g., prompt_influence).
effects
class-attribute
instance-attribute
Mapping of direction text to SFX entry configurations.
vintage_scenes
class-attribute
instance-attribute
Scene labels whose dialogue receives the vintage audio filter
(e.g. ["scene-3", "scene-4"]). Empty list = no vintage treatment.
get_workspace_root
Return the active workspace root.
Resolves in priority order:
1. XIL_PROJECTROOT environment variable (absolute path).
2. Current working directory (existing behaviour).
Source code in src/xil_pipeline/models.py
get_code_root
Return the code root — the directory that holds the optional local-model
virtualenvs (venv-chatterbox, venv-whisper, venv-audioldm2).
Resolves the XIL_CODEROOT environment variable (absolute path, tilde-expanded),
or None when it is unset. This is distinct from :func:get_workspace_root
(XIL_PROJECTROOT): the code root tracks where the software and its heavy
model venvs live, while the workspace root tracks the show content. They differ
when the package is installed once and pointed at a separate content directory.
Source code in src/xil_pipeline/models.py
resolve_venv_python
Resolve the python3 interpreter for an optional local-model venv.
Used to locate venv-chatterbox / venv-whisper / venv-audioldm2, which
carry heavy ML dependencies and are never installed into the main package.
Resolution order:
- explicit — a caller-supplied interpreter path (e.g. the per-command
--chatterbox-python/--whisper-python/--audioldm2-pythonflag). Wins when provided. XIL_CODEROOT— when set,$XIL_CODEROOT/<venv_name>/bin/python3is used exclusively: it overrides auto-detection entirely and there is no fallback (returnsNoneif the interpreter is absent there).- Auto-detect —
<workspace>/<venv_name>/bin/python3, then the repo root next to the running install.
Parameters:
-
venv_name(str) –Directory name of the venv (e.g.
"venv-audioldm2"). -
explicit(str | None, default:None) –An interpreter path that takes precedence over all detection.
Returns:
-
str | None–The interpreter path string, or
Noneif none was found.
Source code in src/xil_pipeline/models.py
get_active_show
Return the slug from .active_show, or None if not set.
set_active_show
show_slug
Convert a show title to a filesystem-safe slug.
Lowercases the string and strips all non-alphanumeric characters.
Parameters:
-
show_name(str) –Human-readable show title (e.g.,
"nightowls").
Returns:
-
str–Compact slug like
"nightowls"or"mypodcast".
Source code in src/xil_pipeline/models.py
derive_paths_legacy
Legacy workspace layout paths (pre-0.1.8) — used by the migration tool.
Parameters:
Returns:
Source code in src/xil_pipeline/models.py
derive_paths
Derive all standard pipeline file paths from a show slug and episode tag.
Auto-detects workspace layout: returns legacy paths when the cast config
exists at the legacy root location (pre-0.1.8 workspaces), and normalized
paths otherwise (new workspaces or post-migration). Run xil migrate-workspace
to move an existing workspace to the normalized layout.
Parameters:
Returns:
Source code in src/xil_pipeline/models.py
load_project_config
Load and validate project.json, returning a :class:ProjectConfig.
Parameters:
-
project_path(str, default:'project.json') –Path to the project config file.
Returns:
-
ProjectConfig–class:
ProjectConfigwith all fields populated (defaults where absent).
Source code in src/xil_pipeline/models.py
resolve_project_type
Return the content type from project.json, defaulting to "podcast".
Parameters:
-
project_path(str, default:'project.json') –Path to the project config file.
Returns:
-
str–One of
"podcast","audiobook","drama", or"special".
Source code in src/xil_pipeline/models.py
resolve_slug
Resolve the show slug from CLI arg, project.json, or the default.
Resolution order:
1. Explicit show_arg (passed through :func:show_slug).
2. project.json "show" field (if the file exists).
3. :data:DEFAULT_SLUG ("sample").
Parameters:
-
show_arg(str | None, default:None) –Value of
--showCLI flag, orNone. -
project_path(str, default:'project.json') –Path to the project config file.
Returns:
-
str–Filesystem-safe show slug.
Source code in src/xil_pipeline/models.py
resolve_season_title
resolve_season_title(season_title_arg: str | None = None, project_path: str = 'project.json') -> str | None
Resolve the season/arc title from an explicit value or project.json.
Resolution order:
1. Explicit season_title_arg (e.g. extracted from the script header Arc: token).
2. project.json "season_title" field (if the file exists and the key is present).
3. None — no season title is available.
Parameters:
-
season_title_arg(str | None, default:None) –Season title already known (e.g. from the script header), or
None. -
project_path(str, default:'project.json') –Path to the project config file.
Returns:
-
str | None–Season title string, or
Nonewhen not available from any source.
Source code in src/xil_pipeline/models.py
resolve_season
Resolve the season number from an explicit value or project.json.
Resolution order:
1. Explicit season_arg (e.g. parsed from the script header Season N: token).
2. project.json "season" field (if the file exists and the key is present).
3. None — no season number is available.
Parameters:
-
season_arg(int | None, default:None) –Season number already known (e.g. from the script header), or
None. -
project_path(str, default:'project.json') –Path to the project config file.
Returns:
-
int | None–Season number as an integer, or
Nonewhen not available from any source.
Source code in src/xil_pipeline/models.py
episode_tag
Format season/episode as a compact tag like S01E01 or E01.
Parameters:
Returns:
-
str–"S01E01"when season is set,"E01"otherwise.