Add cloud-only sidecar variant (~50MB vs 500MB-2GB)
All checks were successful
Tests / Python Backend Tests (push) Successful in 6s
Tests / Frontend Tests (push) Successful in 7s
Tests / Rust Sidecar Tests (push) Successful in 1m59s

Lightweight Deepgram-only sidecar that excludes PyTorch, faster-whisper,
RealtimeSTT, and CUDA. Only includes audio capture + WebSocket streaming
to Deepgram. Requires a Deepgram API key (BYOK or managed mode).

Changes:
- client/models.py: Extracted TranscriptionResult into standalone module
  so deepgram_transcription.py doesn't transitively import torch
- backend/app_controller.py: Made RealtimeTranscriptionEngine and
  DeviceManager imports lazy (only loaded when remote.mode == "local")
- local-transcription-cloud.spec: PyInstaller spec excluding all ML deps
- SidecarSetup.svelte: Added "Cloud Only (Deepgram)" variant option
- build-sidecar-cloud.yml: CI workflow building cloud sidecar for all 3 OS
- sidecar-release.yml: Dispatches cloud build alongside CPU/CUDA builds

Sidecar download options are now:
- Standard (CPU): ~500 MB - local Whisper on any computer
- GPU Accelerated (CUDA): ~2 GB - local Whisper with NVIDIA GPU
- Cloud Only (Deepgram): ~50 MB - requires API key, no local models

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Developer
2026-04-07 16:57:43 -07:00
parent bb039399fc
commit 3d3d7ec3c5
10 changed files with 469 additions and 42 deletions

View File

@@ -79,7 +79,7 @@ async def test_start_when_not_ready(api_client, controller):
@pytest.mark.asyncio
async def test_clear(api_client, controller):
from client.transcription_engine_realtime import TranscriptionResult
from client.models import TranscriptionResult
from datetime import datetime
controller.transcriptions = [

View File

@@ -72,7 +72,7 @@ def test_double_start_rejected(controller):
def test_clear_transcriptions(controller):
"""clear_transcriptions should empty the list and return the count."""
from client.transcription_engine_realtime import TranscriptionResult
from client.models import TranscriptionResult
controller.transcriptions = [
TranscriptionResult(text="Hello", is_final=True, timestamp=datetime.now(), user_name="Alice"),
@@ -85,7 +85,7 @@ def test_clear_transcriptions(controller):
def test_get_transcriptions_text_with_timestamps(controller):
"""get_transcriptions_text should include [HH:MM:SS] prefixes when requested."""
from client.transcription_engine_realtime import TranscriptionResult
from client.models import TranscriptionResult
ts = datetime(2025, 1, 15, 10, 30, 45)
controller.transcriptions = [
@@ -141,7 +141,7 @@ def test_apply_settings_no_reload_when_same(controller):
def test_on_final_transcription_callback_fires(controller):
"""_on_final_transcription should append and invoke on_transcription callback."""
from client.transcription_engine_realtime import TranscriptionResult
from client.models import TranscriptionResult
received = []
controller.on_transcription = lambda data: received.append(data)
@@ -166,7 +166,7 @@ def test_on_final_transcription_callback_fires(controller):
def test_on_final_transcription_ignored_when_not_transcribing(controller):
"""If the controller is not in transcribing state the callback should be a no-op."""
from client.transcription_engine_realtime import TranscriptionResult
from client.models import TranscriptionResult
controller.is_transcribing = False