Credential-Free Voice Demo¶
director_ai.voice.demo provides a deterministic dry-run voice pipeline for
local validation, CI, and onboarding. It uses the production async
voice_pipeline() plus DryRunTTSAdapter, so the guard, sentence buffering,
halt callback, recovery path, and adapter lifecycle are exercised without
external services or credentials.
from director_ai.voice import run_voice_demo
result = await run_voice_demo(use_nli=False)
print(result.tts_texts)
print(result.audio_chunks)
print(result.total_audio_bytes)
Run it from the command line:
The dry-run adapter records every text fragment sent to synthesis and emits
deterministic bytes prefixed with audio:. This makes it suitable for
regression tests and for validating that a deployment path closes adapters on
all completion and failure paths before replacing the adapter with a real TTS
backend.
director_ai.voice.demo.DryRunTTSAdapter
dataclass
¶
Bases: TTSAdapter
TTS adapter that records text and yields deterministic audio bytes.
director_ai.voice.demo.VoiceDemoResult
dataclass
¶
VoiceDemoResult(audio_chunks: list[bytes], tts_texts: list[str], halted: bool, halt_reason: str = '', recovery_text: str = '')
Summary returned by :func:run_voice_demo.
total_audio_bytes
property
¶
Total number of dry-run audio bytes emitted by the demo.
director_ai.voice.demo.run_voice_demo
async
¶
run_voice_demo(*, tokens: AsyncIterator[str] | Iterable[str] | None = None, facts: dict[str, str] | None = None, prompt: str = DEFAULT_PROMPT, tts: DryRunTTSAdapter | None = None, threshold: float = 0.3, hard_limit: float = 0.25, score_every: int = 4, soft_halt: bool = True, recovery: str = 'Let me verify that before speaking.', use_nli: bool = False) -> VoiceDemoResult
Run the package voice demo against the production async pipeline.
Parameters mirror :func:voice_pipeline; defaults are credential-free and
deterministic so the demo is suitable for CI and quick local validation.
director_ai.voice.demo.scripted_tokens
async
¶
Yield deterministic token-like fragments from text.
The default keeps whitespace attached to each token so sentence buffering sees realistic fragments while remaining stable across Python versions.