mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-28 21:49:40 +02:00
feat(podcasts): constrain monologue briefs to a single speaker
This commit is contained in:
parent
eb56acc407
commit
f0fc660d70
4 changed files with 55 additions and 14 deletions
|
|
@ -148,6 +148,14 @@ class PodcastSpec(BaseModel):
|
|||
raise ValueError("speaker slots must be unique")
|
||||
return self
|
||||
|
||||
@model_validator(mode="after")
|
||||
def _check_style_speakers(self) -> PodcastSpec:
|
||||
# One voice is what "monologue" means; letting extra speakers through
|
||||
# would force drafting to silently pick a winner.
|
||||
if self.style is PodcastStyle.MONOLOGUE and len(self.speakers) != 1:
|
||||
raise ValueError("a monologue has exactly one speaker")
|
||||
return self
|
||||
|
||||
def speaker_for(self, slot: int) -> SpeakerSpec:
|
||||
"""Return the speaker bound to ``slot`` or raise if none matches."""
|
||||
for speaker in self.speakers:
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ from pydantic import ValidationError
|
|||
from app.podcasts.schemas import (
|
||||
DurationTarget,
|
||||
PodcastSpec,
|
||||
PodcastStyle,
|
||||
SpeakerRole,
|
||||
SpeakerSpec,
|
||||
Transcript,
|
||||
|
|
@ -80,6 +81,27 @@ def test_a_brief_needs_at_least_one_speaker():
|
|||
)
|
||||
|
||||
|
||||
def test_a_monologue_brief_carries_exactly_one_speaker():
|
||||
spec = PodcastSpec(
|
||||
language="en",
|
||||
style=PodcastStyle.MONOLOGUE,
|
||||
speakers=[_speaker(0)],
|
||||
duration=DurationTarget(min_minutes=5, max_minutes=10),
|
||||
)
|
||||
assert spec.style is PodcastStyle.MONOLOGUE
|
||||
|
||||
|
||||
def test_a_monologue_brief_rejects_multiple_speakers():
|
||||
"""One voice is what 'monologue' means; a second speaker is a user error."""
|
||||
with pytest.raises(ValidationError):
|
||||
PodcastSpec(
|
||||
language="en",
|
||||
style=PodcastStyle.MONOLOGUE,
|
||||
speakers=[_speaker(0), _speaker(1, voice_id="kokoro:af_bella")],
|
||||
duration=DurationTarget(min_minutes=5, max_minutes=10),
|
||||
)
|
||||
|
||||
|
||||
def test_duration_rejects_an_inverted_range():
|
||||
"""A max below the min is a user error caught at the brief gate."""
|
||||
with pytest.raises(ValidationError):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue