- VoiceFrame dataclass: label, confidence, speaker_id, shift_magnitude, timestamp - MockVoiceIO: async generator of synthetic frames on a timer (CF_VOICE_MOCK=1) - ContextClassifier: passthrough stub wrapping VoiceIO; _enrich() hook for real classifiers - make_io() factory: mock mode auto-detected from env, raises NotImplementedError for real audio - cf-voice-demo CLI entry point for quick smoke-testing - 12 tests passing; editable install via pip install -e ../cf-voice
43 lines
1.6 KiB
Python
43 lines
1.6 KiB
Python
# cf_voice/models.py — VoiceFrame API contract
|
||
#
|
||
# This module is MIT licensed. All consumers (Linnet, Osprey, etc.)
|
||
# import VoiceFrame from here so the shape is consistent across the stack.
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass, field
|
||
|
||
|
||
@dataclass
|
||
class VoiceFrame:
|
||
"""
|
||
A single annotated moment in a voice stream.
|
||
|
||
Produced by cf_voice.io (audio capture) and enriched by cf_voice.context
|
||
(tone classification, speaker diarization).
|
||
|
||
Fields
|
||
------
|
||
label Tone annotation, e.g. "Warmly impatient" or "Deflecting".
|
||
Generic by default; Elcor-style prefix format is an
|
||
easter egg surfaced by the product UI, not set here.
|
||
confidence 0.0–1.0. Below ~0.5 the annotation is speculative.
|
||
speaker_id Ephemeral local label ("speaker_a", "speaker_b").
|
||
Not tied to identity — resets each session.
|
||
shift_magnitude Delta from the previous frame's tone, 0.0–1.0.
|
||
High values indicate a meaningful register shift.
|
||
timestamp Session-relative seconds since capture started.
|
||
"""
|
||
|
||
label: str
|
||
confidence: float
|
||
speaker_id: str
|
||
shift_magnitude: float
|
||
timestamp: float
|
||
|
||
def is_reliable(self, threshold: float = 0.6) -> bool:
|
||
"""Return True when confidence meets the given threshold."""
|
||
return self.confidence >= threshold
|
||
|
||
def is_shift(self, threshold: float = 0.3) -> bool:
|
||
"""Return True when shift_magnitude indicates a meaningful register change."""
|
||
return self.shift_magnitude >= threshold
|