Backend: - tiers.py: real license validation via Heimdall (self-hosted key or cloud user_id), 30-min cache, BYOK exception for translation - session_store.py: create_session() accepts tier/user_id/window_ms/transcribe_lang/ num_speakers; tier-aware _should_reap() (Free: reap on subscriber leave, Paid: activity TTL); auto-snapshot paid sessions with history on reap; voice-ready probe on session start - services/translator.py: DeepL-backed label translation, CF-managed and BYOK key paths, per-session label cache - models/session.py, scene_event.py, service_event.py: new event types and session fields - api/snapshots.py: GET /sessions/history + POST /session/resume (Paid tier only) - api/dev.py: dev-only /dev/voice/stop|start|restart proxy to cf-orch agent - migrations/002_session_snapshots.sql: session_snapshots table Frontend: - ComposeBar.vue: pre-session settings panel (window, language, speakers, Elcor toggle) with slide transition; passes options to startSession() - stores/settings.ts: persistent user preferences (localStorage), survives page reload - stores/session.ts: voiceReady/voiceError/voiceWarning states; SceneEvent/AccentEvent/ ServiceEvent types; TTL timers for environ/queue badges; startSession() accepts opts - composables/useToneStream.ts: handlers for scene-event, accent-event, service-event SSE - NowPanel.vue: diarization speaker identity badge, acoustic scene badge, privacy risk indicator - HistoryStrip.vue: per-speaker colour chips in history strip - components/DevPanel.vue: dev-only cf-voice stop/restart controls + thread view toggle - App.vue: DevPanel in footer (DEV only), threadView flag switches v0.1.x/v0.2.x preview Tests: - tests/test_pinning.py: 20 tests covering tier-aware reaping, snapshot creation, and translator behaviour - tests/test_tiers.py: 17 tests covering key validation, cloud resolution, caching, require_paid() gate, BYOK exception - All 72 tests passing
58 lines
1.8 KiB
Python
58 lines
1.8 KiB
Python
# app/models/scene_event.py — acoustic scene and accent SSE event models
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass
|
|
class SceneEvent:
|
|
"""
|
|
Acoustic scene classification from cf-voice.
|
|
|
|
Broad scene label (e.g. "indoor_quiet", "outdoor_urban") derived from the
|
|
AST model. Primary input to the privacy risk indicator in the frontend.
|
|
Broadcasts via SSE as `event: scene-event`.
|
|
Not stored in session history.
|
|
"""
|
|
session_id: str
|
|
label: str # SCENE_LABELS: indoor_quiet, outdoor_urban, etc.
|
|
confidence: float
|
|
timestamp: float
|
|
privacy_risk: str = "low" # "low" | "moderate" | "high"
|
|
|
|
def to_sse(self) -> str:
|
|
payload = {
|
|
"session_id": self.session_id,
|
|
"label": self.label,
|
|
"confidence": self.confidence,
|
|
"timestamp": self.timestamp,
|
|
"privacy_risk": self.privacy_risk,
|
|
}
|
|
return f"event: scene-event\ndata: {json.dumps(payload)}\n\n"
|
|
|
|
|
|
@dataclass
|
|
class AccentEvent:
|
|
"""
|
|
Regional accent / language identification from cf-voice.
|
|
|
|
Gated by CF_VOICE_ACCENT=1 — only emitted when that flag is set.
|
|
Broadcasts via SSE as `event: accent-event`.
|
|
Not stored in session history or corrections DB.
|
|
"""
|
|
session_id: str
|
|
region: str # ACCENT_LABELS: en_gb, en_us, fr, etc.
|
|
language: str # raw language tag from the model
|
|
confidence: float
|
|
timestamp: float
|
|
|
|
def to_sse(self) -> str:
|
|
payload = {
|
|
"session_id": self.session_id,
|
|
"region": self.region,
|
|
"language": self.language,
|
|
"confidence": self.confidence,
|
|
"timestamp": self.timestamp,
|
|
}
|
|
return f"event: accent-event\ndata: {json.dumps(payload)}\n\n"
|