Files
noteflow/spikes/spike_03_asr_latency/dto.py
Travis Vasceannie af1285b181 Add initial project structure and files
- Introduced .python-version for Python version management.
- Added AGENTS.md for documentation on agent usage and best practices.
- Created alembic.ini for database migration configurations.
- Implemented main.py as the entry point for the application.
- Established pyproject.toml for project dependencies and configurations.
- Initialized README.md for project overview.
- Generated uv.lock for dependency locking.
- Documented milestones and specifications in docs/milestones.md and docs/spec.md.
- Created logs/status_line.json for logging status information.
- Added initial spike implementations for UI tray hotkeys, audio capture, ASR latency, and encryption validation.
- Set up NoteFlow core structure in src/noteflow with necessary modules and services.
- Developed test suite in tests directory for application, domain, infrastructure, and integration testing.
- Included initial migration scripts in infrastructure/persistence/migrations for database setup.
- Established security protocols in infrastructure/security for key management and encryption.
- Implemented audio infrastructure for capturing and processing audio data.
- Created converters for ASR and ORM in infrastructure/converters.
- Added export functionality for different formats in infrastructure/export.
- Ensured all new files are included in the repository for future development.
2025-12-17 18:28:59 +00:00

89 lines
2.4 KiB
Python

"""Data Transfer Objects for ASR.
These DTOs define the data structures used by ASR components.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import NewType
SegmentID = NewType("SegmentID", str)
@dataclass(frozen=True)
class WordTiming:
"""Word-level timing information."""
word: str
start: float # Start time in seconds
end: float # End time in seconds
probability: float # Confidence (0.0-1.0)
def __post_init__(self) -> None:
"""Validate timing data."""
if self.end < self.start:
raise ValueError(f"Word end ({self.end}) < start ({self.start})")
if not 0.0 <= self.probability <= 1.0:
raise ValueError(f"Probability must be 0.0-1.0, got {self.probability}")
@dataclass(frozen=True)
class AsrResult:
"""ASR transcription result for a segment."""
text: str
start: float # Start time in seconds
end: float # End time in seconds
words: tuple[WordTiming, ...] = field(default_factory=tuple)
language: str = "en"
language_probability: float = 1.0
avg_logprob: float = 0.0
no_speech_prob: float = 0.0
def __post_init__(self) -> None:
"""Validate result data."""
if self.end < self.start:
raise ValueError(f"Segment end ({self.end}) < start ({self.start})")
@property
def duration(self) -> float:
"""Duration of the segment in seconds."""
return self.end - self.start
@dataclass
class PartialUpdate:
"""Unstable partial transcript (may be replaced)."""
text: str
start: float
end: float
def __post_init__(self) -> None:
"""Validate partial data."""
if self.end < self.start:
raise ValueError(f"Partial end ({self.end}) < start ({self.start})")
@dataclass
class FinalSegment:
"""Committed transcript segment (immutable after creation)."""
segment_id: SegmentID
text: str
start: float
end: float
words: tuple[WordTiming, ...] = field(default_factory=tuple)
speaker_label: str = "Unknown"
def __post_init__(self) -> None:
"""Validate segment data."""
if self.end < self.start:
raise ValueError(f"Segment end ({self.end}) < start ({self.start})")
@property
def duration(self) -> float:
"""Duration of the segment in seconds."""
return self.end - self.start