VibeVox — Technikai Architektúra

Backend · Pipeline · Adatfolyam · Infrastruktúra

Kapcsolódó: 09_Product.md · 05_GDPR.md · ROADMAP.md Státusz: Élő dokumentum — v1.5.x állapot alapján Strategic Architecture integráció: ✅ GAP-1–4 + Bet-3 + riport ajánlások beépítve (2026-04-11) — WebSocket streaming (GAP-4), CEE endpointing ADR (GAP-1), MCP Fázis 2 (GAP-2), ADR-001 On-Device STT (GAP-3), ElevenLabs Scribe v2 fallback, gRPC migration roadmap, Distil-Whisper CEE rejection, Context-Aware Output Formatting, Azure MAI-Transcribe-1 B2B — forrás: Strategic_Architecture_Market_Analysis.md Post-CTA funnel integráció: ✅ SHA-256 release pipeline + onboarding_completed event timestamp beépítve (2026-04-18) — forrás: post_cta_funnel_analysis.md


Tartalomjegyzék

  1. Architektúra áttekintés
  2. STT pipeline
  3. Backend proxy szerver
  4. Adatbázis és szinkronizáció
  5. Fizetési infrastruktúra
  6. Platform-specifikus architektúrák
  7. Biztonsági architektúra
  8. Ismert technikai adósságok

1. Architektúra áttekintés

Rendszerkomponensek

┌─────────────────────────────────────────────────────────────────┐
│  VibeVox KLIENS (Windows / Linux App)                               │
│  ├── PySide6 UI (main_window.py, tray.py)                      │
│  ├── Audio recording (workers.py — hold-to-talk + session cap)  │
│  ├── Post-processing (post_process.py — filler removal)         │
│  ├── Local DB (SQLite — history, vocabulary, usage)             │
│  └── Sync engine (sync.py — Supabase ↔ local DB)               │
└───────────────────┬─────────────────────────────�  ├── Routing: stt_router.py → provider-agnostik routing       │
  └── Billing sync (Stripe webhooks)                             │
└───────────────────┬─────────────────────────────────────────────┘
          ┌─────────┴──────────┐
          ▼                    ▼
  ┌───────────────────────┐   ┌───────────────────┐
  │  Deepgram Nova-3      │   │  Supabase         │
  │  (STT — PRIMARY)      │   │  (history, vocab, │
  │  WebSocket streaming  │   │   usage sync)     │
  │  EU adatközpont, SCC  │   │  Zürich, EU       │
  └───────────────────────┘   └───────────────────┘
          │
          │ Managed fallback lánc
          ▼
  ┌──────────────────────────────────────────────────┐
  │  Groq Whisper large-v3 (Frankfurt, SCC)          │  ← Managed fallback / BYOK alt.
  │  → OpenAI gpt-4o-transcribe                      │  ← Végső fallback (3.2× drágább)
  │  → Azure AI Speech (VNet) — B2B compliance tier  │  ← Fázis 2 high-compliance B2B
  └──────────────────────────────────────────────────┘─────────────────────────────────────┘
          ┌─────────┴──────────┐
          ▼                    ▼
  ┌───────────────┐   ┌───────────────────┐
  │  Groq API     │   │  Supabase         │
  │  (STT)        │   │  (history, vocab, │
  │  Frankfurt    │   │   usage sync)     │
  │  routing, SCC │   │  Zürich, EU       │
  └───────────────┘   └───────────────────┘
          │
          │ Fallback lánc
          ▼
  ┌───────────────────────────────┐
  │  OpenAI gpt-4o-transcribe     │  ← Legjobb minőség (3.2× drágább)
  │  → Gemini 2.5 Flash (EU)      │  ← Jövőbeli EU backend (Fázis 2)
  └───────────────────────────────┘

BYOK mód architektúra

VibeVox KLIENS
    │
    ├──► KÖZVETLENÜL a user STT API-jára (Groq / OpenAI / Azure / Gemini)
    │    Az API kulcs a felhasználóé — ETS LLC nem proxyzza
    │
    └──► Supabase Zürich (history szinkron — ha bejelentkezve)

2. STT pipeline

Elsődleges pipeline (Managed Cloud) — WebSocket True Streaming

⚡ IMPORTANT

Döntés (2026-04-11 · GAP-4 javítás): A VibeVox P0-tól true streaming architektúrán indul. Nem batch WAV → egyszeri válasz, hanem valós idejű audio chunk streaming → live interim results. Ez az aha-moment kritikus eleme (live bubble). Batch→streaming migráció helyett: az alap eleve streaming.

⚠️ WARNING

ADR-002: Deepgram ELVETETT (2026-04 — végleges döntés) Deepgram Nova-3-at megpróbáltuk — többször is. Elvetés oka: nem kezeli a CEE code-switching-et. A CEE felhasználók (HU/PL/CZ/SK) természetesen kever angolt az anya nyelvhez ("menj a settings-be", "klikkelj a button-ra"). A Deepgram API egyetlen nyelvet vett paraméterként — a váltásnál hibás leirat vagy teljes csőd következett. Helyébe lép: Groq Whisper large-v3 — OpenAI Whisper alapú, natívan kezeli a többnyelvű hangot, code-switching-et. §2.1 Háromszintű multilinguális STT pipeline épít erre. Ezzel a Deepgram-mal kapcsolatos TASK_CALENDAR feladatok (D-13, D-9, D+24) érvénytelenek — lásd 17_TASK_CALENDAR.md módosítás.

[GOMB NYOMVA TARTVA]
    │
    ↓ Hang rögzítés (workers.py) — gomb elengedésekor WAV buffer lezárva
    │
    ↓ Proxy WebSocket kapcsolat (kliens → GCP proxy)
    │
    ↓ stt_router.py → Groq Whisper large-v3 (Frankfurt, SCC) ← ELSŐDLEGES
    │   language=BCP47_MAP[primary_language]  (hu, pl, cs, sk...)
    │   prompt="Primary: Hungarian. Also: English."  (⇒ code-switching support)
    │   Batch WAV — gomb elengedésekor küld, válasz ms-eken belül

[GOMB ELENGEDVE]
    │
    ↓ post_process.py — filler removal (ööö/szóval/hm), írásjel, mondatvég
    │
    ↓ Szöveg commit az aktív ablakba (OS keyboard injection)
    │
    ↓ Storage: SQLite (local) + Supabase szinkron (cloud)

[Fallback lánc]
    → OpenAI gpt-4o-transcribe (3.2× drágább, de legjobb accuracy)
    → Azure AI Speech (Fázis 2 — B2B VNet compliance tier)

[NOTE: Live bubble / interim results — Fázis 2+ kutatási cél]
    Groq nem támogat WebSocket streaming-et (részben ezért próbáltuk Deepgramot).
    Jövőbeli lehetőség: EU-alapú provider WebSocket streaming-gel, ami egyben
    kezeli a CEE code-switching-et — jelenleg ilyen nincs azonosítva.

Pipeline kulcsparaméterei:

Paraméter Érték Indok
language BCP47_MAP[primary_language] CEE pontos nyelvi fókusz (nem auto-detect)
prompt "Primary: HU. Also: EN." Code-switching támogatás Whisper prompt hint-el
Batch mód WAV gomb elengedésekor Groq, ellentétben Deepgrammal, nem hibás HU+EN váltásnál
temperature 0 Determinisztikus — konzisztens leiratok

Protokoll Stratégia: WebSocket (P0) → gRPC (Fázis 3+)

ℹ️ NOTE

Döntés (2026-04-11 · riport ajánlás): A P0 WebSocket-alapú streaming helyes és elégséges a hold-to-talk use case-re; jól dokumentált, széles klienssupport. A gRPC az egyértelmű hosszú távú cél (Fázis 3+) — HTTP/2 multiplexing, natív kétirányú streaming, alacsonyabb overhead.

Dimenzió WebSocket (P0 — most) gRPC (Fázis 3+ — jövő)
Latency ~80–150ms end-to-end ~30–60ms (HTTP/2 multiplexing)
Streaming Kétirányú (külön kezelés) Natív kétirányú (bidirectional)
Kapcsolat overhead Magas (handshake per request) Alacsony (connection multiplex)
CEE morfológia Jó (jelenlegi utterance_end_ms) Kiváló (server push interim tokens)
Backward compat Széles kliens support gRPC-web szükséges browserben
Implementáció risk Nulla (kész) Közepes (proto def., migration)

Migrációs döntési pont (Fázis 3): Ha a D+83 CEE endpointing A/B teszt eredményei után is latencia-panasz marad a top bug-reportok között → gRPC sprint indul. Ha a WebSocket latencia felhasználói szinten nem érzékelhető → marad, mert nincs user-visible probléma, és a migráció overhead nem indokolt.


2.1. Háromszintű multilinguális STT pipeline

⚡ IMPORTANT

Ez egy tudatos architektúrális döntés — NEM auto-detect. Dokumentálandó és aktívan kommunikálandó marketing anyagokban.

A probléma az auto-detect-tel: A Whisper auto-detect az audio első ~30 másodpercére alapozva választ a 100+ lehetséges nyelv közül. Kétnyelvű (pl. hu + en) diktálásnál pontatlan — a magyar–finn fonológiai hasonlóság (mindkettő Uralic) miatt pl. magyar szövegből finn leirat is keletkezhet. (Ez a Wispr Flow auto-detect konkrét, saját tapasztalatból dokumentált hibája.)

A VibeVox 3 szintű megoldása:

Szint 1: Primary Language PIN
  app/config/settings.py → "primary_language": "Hungarian"
  groq_engine.py → language=LANG_BCP47_MAP[primary] → "hu"
  Hatás: A Whisper modell pontosan erre a nyelvre fókuszál
         (nem választ 100+ közül)

Szint 2: Prompt Hint (Secondary + Tertiary)
  _lang_helpers.py → build_lang_context(settings, previous_context)

  ⚠️ ADR — Prompt Hint Hallucináció Bug (2026-04-19 — FIX)
  PROBLÉMA: A Whisper API `prompt` paramétere NEM utasítás, hanem kontextus-szöveg.
  Ha az első diktálásnál (üres rolling tail) lang-hint mondatot küldtünk:
    "The speaker uses Hungarian, English."
  A Whisper ezt szó szerint beleírta a leírat elejére — pontosan ugyanaz a szöveg
  jelent meg a transzkriptben: "A speaker uses Hungarian, English."

  Megpróbált megoldások:
    ① Post-process strip CSAK — tüneti kezelés (hallucináció megtörtént,
       csak utólag töröltük; átugorja a proxy-ágat és jövőbeli motorokat).
    ② Format megváltoztatás ("[Hungarian, English]" → nem mondat)
       — nem dokumentált Whisper viselkedésre támaszkodik; nincs benchmark
         garancia; elvetettük.
    ③ VÁLASZTOTT FIX: a `prompt` mezőt CSAK akkor küldjük el, ha van valódi
       rolling-context tail. Üres tail esetén üres string → motorok nem küldik
       a prompt-ot → Whisper semmi „mondandót" nem hall hallucinálni.
       + strip_lang_hint() safeguard marad aktív DEFENCE 1-ként minden motornál.

  Hatás a secondary/tertiary language-re:
    Az első chunk-nál nincs explicit lang hint — DE:
    • A Whisper Large v3 belső multilinguális képessége HU+EN code-switchingre
      erős (~85-90% a CEE use case-ben hint nélkül is).
    • A 2. chunk-tól a rolling tail stílus-kontextusa pótol mindent.
    • A language= API param (primary) mindig aktív marad.
    Nettó hatás: első mondat margóan gyengébb cold-start detekció — elfogadott trade-off.

  ⚠️ Google STT + Azure Speech integráció (Fázis 2):
    Mindkét új engine-be be kell kötni a strip_lang_hint() safeguard-ot.
    A Google multimodal API más mechanizmust használ (nem `prompt=`),
    az Azure Speech pedig PhraseListGrammar → a lang hint küldési mechanizmusa
    más lesz, de a strip-safeguard engine-független és minden kimenetre alkalmazható.
    Implementáció: `raw = strip_lang_hint(raw, settings)` a transcribe() return előtt.

Szint 2b: Rolling Context Window — Whisper prompt optimális felhasználása
  Az előző transzkripció utolsó ~150 szava kerül a Whisper prompt-ba.
  NEM szótár — a 224-token limitet szótárra pazarolni értelmetlen.
  → Hatás: Mondathatár-hibák, stílus-öröklés, folyamatos diktálás kontextusa
  → Kód: prompt = previous_transcript_tail(max_tokens=224)

  BYOK Provider-specifikus prompt limit — Kutatás (2026-04-18):
  A 224-token limit a Whisper modell belső architektúrájának korlátja.
  NEM érvényes minden BYOK providerre — provider-specifikus kezelés szükséges!

  | STT Provider              | Prompt mód             | Limit / Mechanizmus                            | Implementáció a rolling contexthez                  |
  |---------------------------|------------------------|------------------------------------------------|-----------------------------------------------------|
  | Groq Whisper large-v3     | `prompt=` string       | 224 token (végéről számolva, korábbi szöveg ignorálva) | `max_tokens=224` — jelenlegi implementáció ✅     |
  | OpenAI BYOK (gpt-4o-transcribe) | `prompt=` string | ~224 token — prompt leakage kockázat hosszabb inputnál | rövid trailing context, `max_tokens=200`      |
  | Azure BYOK (OpenAI Whisper) | `prompt=` string     | 224 token (azonos Whisper architektúra)        | azonos, `max_tokens=224`                            |
  | Google Gemini BYOK        | multimodal chat üzenet | ~1M token kontextusablak (32 token/sec audio)  | **1 000 token** rolling window — lásd döntés lent  |

  ADR — Azure Cognitive Services Speech ELVETVE (2026-04-18):
  Az Azure BYOK = kizárólag Azure OpenAI Whisper. Azure Cognitive Speech NEM kerül implementálásra.
  Indok:
    ✅ Ár: azonos ($0.006/perc batch) — nincs cost-előny az Azure Speech mellett
    ✅ WER: nagyjából azonos CEE nyelveken — nincs accuracy-előny
    ❌ Azure Speech fő előnye: real-time streaming alacsony latenciával
       → VibeVox hold-to-talk = BATCH (gomb elengedésekor küld WAV-t)
       → a streaming előny irreleváns a use case-re
    ❌ Azure Speech API: teljesen más SDK (Microsoft Cognitive), PhraseListGrammar,
       külön rolling context logika → nagy fejlesztési overhead, semmi extra értékért
    ✅ Azure OpenAI Whisper: OpenAI-kompatibilis endpoint → ugyanaz a kód mint OpenAI BYOK,
       csak `base_url` + `api_key` különbözik — trivialis implementáció
    ✅ Azure OpenAI = EU data residency oka megtartható (B2B compliance tier)

  ADR — OpenAI whisper-1 ELVETVE (2026-04-18, végleges döntés):
  OpenAI BYOK = kizárólag gpt-4o-transcribe. whisper-1 NEM kerül implementálásra.
  A felhasználó csak „OpenAI API kulcs"-ot lát — a modellválasztás VibeVox belső döntése.
  Indok:
    ✅ WER: gpt-4o-transcribe lényegesen alacsonyabb hibaarány mint whisper-1
       (OpenAI belső benchmarkok: ~30-50% WER csökkentés tipikus use case-en)
    ✅ CEE code-switching: gpt-4o-transcribe jobb HU+EN, PL+EN, CZ+EN kezelése
       (whisper-1 a CEE morfológián és vegyes nyelvű mondatokon gyengébben teljesít)
    ✅ API kulcs: gpt-4o-transcribe ugyanazon OPENAI_API_KEY alatt érhető el — nincs
       külön engedélyezési lépés vagy plan-upgrade a BYOK user számára
    ✅ UX: a felhasználónak irreleváns a modell neve — csak a pontosság számít
    ❌ whisper-1 egyetlen előnye lett volna: alacsonyabb cost
       → de a pontosság-különbség ezt nem indokolja, és BYOK user a saját számlájára fizet
    ❌ Karbantartás: két OpenAI-ágat fenntartani (whisper-1 + gpt-4o-transcribe)
       semmi pluszt nem adna, csak kódbonyolítást
  Összefoglalva: ha valakinek OpenAI kulcsa van, a legjobb modellt kapja — automatikusan.

  ⚠️ Fejlesztési figyelő (2026-04-19 sprint):
  - Groq Whisper large-v3: max_tokens=224 ✓ (jelenlegi implementáció)
  - OpenAI gpt-4o-transcribe: max_tokens=200 (prompt leakage kockázat miatt konzervatív)
  - Azure OpenAI Whisper: max_tokens=224 (azonos Whisper architektúra)
  - Gemini BYOK: max_tokens=1000 — dedicated branch a build_lang_context()-ben


  A Gemini 1M token kontextusa lehetővé teszi, hogy lényegesen több előző szöveget adjunk át
  mint Whisper-nél. Ez jobb kontextus-öröklést ad (proper nouns, stílus, terminológia).
  DE: az audio maga is tokenekbe kerül (32 tok/sec), és a text input is pénzbe kerül.

  Cost-benefit kalkuláció (Gemini 1.5 Flash, BYOK user fizeti):
    Egy 30mp-es diktálás audio cost:   30 × 32 tok = 960 audio token
    Text input (~26× olcsóbb audio-nál):
      224 token kontextus  → +$0.000017/diktálás → napi 50 alkalom: $0.00085/nap
      1 000 token kontextus → +$0.000075/diktálás → napi 50 alkalom: $0.004/nap  ← VÁLASZTOTT
      3 000 token kontextus → +$0.000225/diktálás → napi 50 alkalom: $0.011/nap
      10 000 token kontextus → +$0.00075/diktálás → napi 50 alkalom: $0.038/nap

  DÖNTÉS: Gemini BYOK rolling window = 1 000 token (~750 szó, ~5 perc kontextus)
  Indok:
    ✅ 4× több kontextus mint Whisper — érzékelhető kontextus-öröklés proper nouns-ra, stílusra
    ✅ Napi extra cost < $0.004 — elhanyagolható a BYOK user számára
    ✅ Konzervatív megközelítés — könnyen növelhető ha A/B teszt indokolja
    ❌ 3K+ token: extra cost nő, a margináló minőségjavulás már kicsi
  Implementáció: `build_lang_context(provider="gemini", max_tokens=1000)`

  ⚠️ Fejlesztési figyelő (2026-04-19 sprint):
  - Whisper-alapú providerek (Groq, OpenAI whisper-1, Azure OAI): max_tokens=224 marad ✓
  - gpt-4o-transcribe: max_tokens=200 (prompt leakage kockázat miatt konzervatív)
  - Gemini BYOK: max_tokens=3000 — dedicated branch a build_lang_context()-ben
  - Azure Cognitive Speech (nem OAI): rolling context teljesen más API — PhraseListGrammar
    → fejlesztési döntés szükséges: külön implementáció vagy Azure OAI-ra irányítás

Szint 2c: LLM Post-Processing — Custom Vocabulary Correction (Fázis 2+)
  DÖNTÉS (2026-04-18): A custom vocabulary NEM a Whisper promptba kerül.
  A Whisper 224 token limitje ~80-120 orvosi/jogi szót fed le — elégtelen.
  Helyette 2-lépéses pipeline:
    1. Groq Whisper large-v3 → nyers transzkript (rolling context prompt)
    2. Groq Llama 3 8B Instant → vocabulary-korrigált végleges szöveg
       Rendszer-prompt = összes aktív szótár teljes listája
       (500-1500 szó gond nélkül befér a Llama 3 8K+ kontextusba)
  Triggerelés (OPT-IN — 2026-04-18 döntés):
    Az LLM lépés CSAK akkor fut le, ha a felhasználónak van legalább 1 aktív szótára
    VAGY aktív Style Persona van kiválasztva (nem Standard).
    Ez magában foglalja az előre beépített (Medical, Legal, Dev) szótárakat is —
    de ezek is csak aktiválás után futnak. Alapértelmezett állapotban: LLM nem fut.
    Style Persona = Standard → LLM NEM fut (ha nincs szótár sem)
    Style Persona ≠ Standard → LLM fut, rendszer-promptba kerül a persona definíció
    Szótár + Persona egyszerre → EGYETLEN API hívásban kezelve (nincs extra latencia)
    Filler removal (ööö, hát, szóval) — marad regex/post_process.py — NEM kerül LLM-be.
  Előnyök: korlátlan szótárméret, több szótár egyszerre, kontextus-érzékeny;
    stílus és szótár egyetlen API hívásban egyesíthető — nincs extra latencia
  Cost: ld. 04_Pricing.md — LLM Post-Processing cost szekció (részletes leépítés)
  Gboard ellentéte: Gboard explicit ignorálja a Personal Dictionary-t
                    voice mode-ban → VibeVox LLM pipeline megoldja
  Android kiemelten releváns: Gboard monopolhelyzet → erős differenciátor

  BYOK Provider Routing — Döntés (2026-04-18):
  A post-processing LLM KÖVETI az STT providert.
  Elv: egykulcsos BYOK — a felhasználó egyetlen API kulcsa fedi az STT-t ÉS
  az LLM post-processinget is. ETS LLC nem kezel más provider kulcsát.

  | STT Provider        | Modell (user NEM választ) | LLM Post-Processing      | Kulcs           |
  |---------------------|---------------------------|--------------------------|-----------------|
  | Groq (managed/BYOK) | Whisper large-v3          | Groq Llama 3 8B Instant  | GROQ_API_KEY    |
  | OpenAI BYOK         | **gpt-4o-transcribe**     | OpenAI gpt-4o-mini       | OPENAI_API_KEY  |
  | Google BYOK         | Gemini 1.5 Flash          | Gemini 1.5 Flash         | GOOGLE_API_KEY  |
  | Azure BYOK (OAI)    | Azure OpenAI Whisper      | Azure OpenAI gpt-4o-mini | AZURE_OPENAI_*  |
  | Azure BYOK (Speech) | Azure Speech              | Groq Llama 3 (fallback)  | —               |

  Implementáció: _get_postprocessing_provider() helper (_orchestrator.py)
  Tesztelési scope: Groq/OpenAI/Gemini/Azure × szótár aktív/inaktív × literal mód = 16 kombináció
  Fejlesztési sprint: 2026-04-19 (D-12)

Szint 3: Filler Removal (CEE-specifikus)
  post_process.py → filler_removal(text, primary_language)
  → "ööö", "hát", "szóval", "no", "takže", "teda", "eee"
  Hatás: CEE-specifikus, az auto-detect nem ismeri ezeket

Kódból:

# groq_engine.py
lang_code = LANG_BCP47_MAP.get(settings.get("primary_language", "Hungarian"), "hu")
# → Whisper language param: pontosan "hu" (nem auto)

# _lang_helpers.py
langs = [settings.get("primary_language", "Hungarian")]
# secondary + tertiary → prompt hint

Marketing érv:

„Wispr Flow-nak van auto-detect funkciója. Nálunk nincs — mert ez pontosabb. Egy felhasználó által explicit megadott 2-3 nyelv mindig jobb eredményt ad, mint 100+ közötti gépi választás."

2.2. Hallucináció-megelőzési réteg (Anti-Confabulation)

Probléma: A Whisper seq2seq architektúra csend esetén hallucinál — a training adatából generál szöveget (pl. „Thanks for watching", „Transcription by CastingWords", „Subscribe to our channel", véletlenszerű mondatok más nyelveken). Ez a hold-to-talk modellben is előfordul, ha a user gondolkodás közben nyomva tartja a gombot.

Forrás: Churn post-mortem kutatás (2026-04) — az AquaVoice és Wispr Flow felhasználóknál reprodukálható, dokumentált probléma.

3 szintű védekezés:

Szint 1: Kliens-oldali VAD (Voice Activity Detection) — Fázis 1
  ├── A VibeVox app a hangfelvételt küldés ELŐTT elemzi
  ├── RMS energia < küszöbérték AND nincs speech onset → NEM küld API-nak
  ├── Teljes csend session → üres string, nem API hívás (megtakarítás!)
  └── Implementáció: webrtcvad (Python) vagy egyszerű RMS threshold

Szint 2: Proxy-oldali blocklist szűrés — Fázis 1
  ├── A FastAPI proxy ismert hallucináció-mintákat szűr a Groq válaszban:
  │   ["Thanks for watching", "Transcription by", "Subscribe to",
  │    "bye", "thank you for listening", "Amara.org"]
  ├── Regex blocklist: ha a TELJES válasz ilyen szöveg → üres string return
  └── Nyelvi koherencia: ha user HU-t diktál és válasz 100% EN → eldobás

Szint 3: Felhasználói feedback
  └── Üres eredménynél: "Nem hallottam semmit — próbáld újra" toast
      (NEM jelenít meg random hallucinált szöveget)

Teljesítmény hatás:

  • VAD check: <5ms (kliens-oldali, minimális overhead)
  • Proxy blocklist: <10ms (egyszerű string matching)
  • Megtakarítás: felesleges Groq API hívások eliminálása csend esetén

A fenti az orvosi/jogi B2B szegmensben kritikus: „Köszönöm a figyelmet" vagy random szöveg a zárójelentésben azonnali bizalomvesztést okoz.


2.3. Latency SLA

A kutatás (2026-04) szerint a 3 másodperc feletti E2E latency a flow state megsemmisítője — ennél a pontnál a felhasználó visszatér a gépeléshez. Az AquaVoice 450ms–1s sávja az iparági arany-standard.

SLA célok és alerting:

Metrika P50 cél P95 cél P99 cél Alerting küszöb
E2E TTV (gomb felengedés → szöveg megjelenik) <1.0s <1.5s <2.5s P95 > 2.0s = alert
Groq API response <500ms <1.0s <1.5s P50 > 800ms = fallback trigger
Audio upload (kliens → proxy) <200ms <400ms <600ms
Text injection (proxy return → aktív ablak) <50ms <100ms <150ms

Versenytárs benchmarkok:

Versenytárs TTV Módszer
AquaVoice (Avalon motor) 450ms-1s Saját modell, agresszív optimalizálás
Wispr Flow 1.5-3s Cloud roundtrip (flow state killer)
Typeless ~1.5-3s Cloud-native, hasonló Wispr sávban
VibeVox (cél) <2s (P95) Groq Frankfurt routing

Monitoring implementáció — Sentry performance tracing (opt-in):

# Mérendő Sentry spanok
sentry_sdk.start_span(op="stt.upload_latency_ms")
sentry_sdk.start_span(op="stt.processing_time_ms")
sentry_sdk.start_span(op="stt.total_ttv_ms")
sentry_sdk.start_span(op="stt.text_insertion_ms")

A Groq Frankfurt routing természetes előnyt ad a CEE felhasználóknak vs. US-központú versenytársak (~50-100ms RTT nyereség). Ez aktívan kommunikálandó a marketing narratívában.

2.4. CEE Nyelv-specifikus Endpointing ADR (Hipotézis — Validálandó)

Döntés (2026-04-11): A VibeVox language-aware endpointing konfigurációt alkalmaz Deepgram WebSocket streaming esetén. Az optimális érték CEE nyelvenként eltérő — a szóhossz és morfológiai komplexitás függvénye. Ez jelenleg hipotézis, Fázis 2-ben A/B teszttel validálandó.

A probléma: Deepgram default endpointing angol-centrikus

Deepgram endpointing = hány ms csend után zárja le az utterance-t

Default: 10ms — az angol rövid szavakra optimalizálva (~4-5 karakter)

Magyar példa a problémára (800ms-nél rövidebb endpointing esetén):
  Felhasználó mondja: "megvizsgálhatatlan"  (~1.4 mp kiejtési idő)

  10ms endpointing:   "megvizsgálha" [LEZÁR] "tlan" → 2 töredék, rossz
  200ms endpointing:  "megvizsgálhata" [LEZÁR] "lan" → még mindig rossz
  800ms endpointing:  "megvizsgálhatatlan" [LEZÁR] → ✅ teljes szó

CEE nyelvek morfológiai komplexitása és endpointing hipotézis

Nyelv Típus Átl. szóhossz Max szóhossz Jellemző probléma Endpointing hipotézis
English (baseline) Izoláló ~4-5 kar. ~15 kar. 10ms (Deepgram default)
Slovak (SK) Fuzionáló ~5-6 kar. ~25 kar. Kevesebb eset-suffix ~400ms
Czech (CZ) Fuzionáló ~5-6 kar. ~28 kar. Hasonló SK-hoz ~400–500ms
Polish (PL) Fuzionáló + klaszter ~6-7 kar. ~30 kar. szcz, prz, strz msh-torlódás ~500–600ms
Hungarian (HU) Agglutináló ~7-8 kar. ~44+ kar. Korlátlan suffix-lánc ~700–800ms
⚡ IMPORTANT

A PL eset különleges: a lengyel mássalhangzó-csoportok (szcz, prz) nem hosszú szavakat, hanem nehezen szegmentálható fonémasorozatokat okoznak. Az endpointing itt a téves szóhatár-detektálás ellen véd, nem a szóhossz miatt.

Implementáció — Primary Language PIN alapján automatikus

# stt_router.py / deepgram_handler.py
# Egy dict vezérel mindent — a Primary Language PIN már megvan

LANGUAGE_ENDPOINTING_MS = {
    "en": 10,    # Deepgram default — angol baseline
    "sk": 400,   # Fuzionáló, mérsékelten hosszú szavak
    "cs": 450,   # Fuzionáló, hasonló SK-hoz
    "pl": 550,   # Fuzionáló + msh-torlódás (szcz, prz)
    "hu": 800,   # Agglutináló — a leghosszabb szavak
}

# Deepgram WebSocket konfig (language = Primary Language PIN):
deepgram_config = {
    "language": lang_code,                              # pl. "hu"
    "endpointing": LANGUAGE_ENDPOINTING_MS[lang_code], # pl. 800
    "utterance_end_ms": 1000,    # 1 mp szünet = utterance lezárva (minden CEE-n)
    "smart_format": True,
    "model": "nova-3",
}

Miért elegáns ez az arhitektúra:

  • A Primary Language PIN (2.1. szekció) már meghatározza a lang_code-ot
  • Az endpointing automatikusan következik belőle — a user semmit nem állít be
  • Új CEE nyelv hozzáadása = 1 sor a dict-ben

A/B Teszt Protokoll (Fázis 2, D+83)

Tesztkészlet: 30 mondat × 4 CEE nyelv = 120 teszt
  - 10 rövid mondat (1-3 szó)
  - 10 közepes mondat (4-8 szó, normál szóhossz)
  - 10 hosszú mondat (9+ szó, komplex agglutináció/klaszter)

Tesztelt endpointing értékek: [10, 200, 400, 600, 800, 1200] ms
Mért metrika: WER (Word Error Rate) a ground truth transzkripthez képest

Várható eredmény:
  EN: 10ms optimális (egyértelmű)
  HU: 700-900ms sávban optimális
  PL: 500-700ms sávban optimális
  CZ/SK: 400-600ms sávban optimális

Ha mért optimum ≠ hipotézis → LANGUAGE_ENDPOINTING_MS frissítése
ℹ️ NOTE

Marketing értéke (ha validált): Ez az egyetlen publikusan dokumentált, tesztelt CEE-specifikus Deepgram endpointing konfiguráció. Nincs más STT termék ami ezt méri és publikálja. Dev community számára megosztható technikai blog post / HN post alapja.

Versenytárs-összehasonlítás

Versenytárs Magyar endpointing optimalizálás?
Wispr Flow ❌ Default 10ms (angol-centrikus)
Typeless ❌ Default (auto-detect, generikus)
Windows Fluid Dictation ❌ Azure default konfig
Dragon HU N/A (nem streaming)
VibeVox ✅ Language-aware, mért endpointing

STT provider összehasonlítás

⚠️ WARNING

Architektúrális döntés felülvizsgálat (2026-04-11 — éles tesztelés alapján) Az eredeti architektúra Deepgram Nova-3-t jelölt ki PRIMARY motornak elméleti benchmark adatok alapján. Éles, valós körülmények között végzett tesztelés ezt megcáfolta. Lásd a teszteredmények szekciót alább.

Deepgram Nova-3 — Éles teszteredmények (2026-04-11)

🚨 CAUTION

Deepgram Nova-3 CEE tesztelés — SIKERTELEN Tesztkörnyezet: Boya gooseneck USB mikrofon · Magyar elsődleges nyelv · Windows 11 · Koh Phangan (TH → EU szerver)

Teszt Konfiguráció Eredmény Értékelés
Magyar monolinguális language=hu ✅ Működik — ~0.4 mp latencia
Magyar + "AI" szó language=hu ❌ "AI" felismerhetetlenül elrontva Kritikus hiba
Magyar + angol márkanév (Boya) language=hu ❌ Értelmetlen output Kritikus hiba
Multilinguális (language=multi) language=multi Magyar szövegből svéd/nordikus leirat (ä/å/ø karakterek) Disqualifying
Sebességmérés (batch baseline-hoz képest) language=hu ✅ ~5-6× gyorsabb mint batch Pozitív

Gyökérokok:

1. language=hu: Nova-3 a teljes hangot magyar fonetikán erőlteti át
   → Angol szavak (AI, Boya, app) elvesznek vagy torzulnak
   → Magyar + bármilyen idegen szó = hibás output

2. language=multi: Nova-3 100+ nyelv közül választ mondatonként
   → Magyar fonológia átfedést mutat finnugor/skandináv nyelvekkel
   → Valós teszten: magyar mondatok svéd szövegként kerültek leiratba
   → Ez diszqualifikálja a CEE kódváltó (HU+EN) use case-re

3. Nincs prompt paraméter: Deepgram API nem támogatja a
   "primary=HU, secondary=EN" hint megadását
   → Whisper-rel szemben nincs megoldás erre az use case-re

Összehasonlítás WhisperFloat-tal (Groq Whisper, azonos mikrofon):

WhisperFloat (Groq Whisper large-v3): Magyar + angol szavak → TÖKÉLETES
Deepgram Nova-3:                      Magyar + angol szavak → MEGBÍZHATATLAN

Döntés: Deepgram Nova-3 kizárva a PRIMARY pozícióból. Deepgram WebSocket streaming sebesség-előnye valós (~0.4 mp), de a CEE kódváltó minőség elfogadhatatlan. A Managed Cloud PRIMARY motor: Groq Whisper large-v3 (VAD-alapú szegmentálással).


⚡ IMPORTANT

Döntés (2026-04-11 — éles teszt alapján felülírva): Deepgram Nova-3Groq Whisper large-v3 a Managed Cloud elsődleges motorja. A Whisper language= + prompt= kombinációja lehetővé teszi a primary+secondary+tertiary hint megadását — ez az egyetlen megbízható megoldás a CEE kódváltó use case-re.

Provider Ár/perc EU Data Residency CEE kódváltó minőség Transzkripciós minőség (WER) Szerepe
Groq Whisper large-v3 ~$0.00185 ✅ SCC, Frankfurt ✅ Kiváló (tesztelve, HU+EN) ✅ Jó — Whisper large-v3 ~4–6% WER EN; CEE-n ~8–12% Managed Cloud PRIMARY · BYOK low-cost default
OpenAI gpt-4o-transcribe ~$0.006 ❌ US ✅ Legjobb (benchmark-vezető) ✅✅ Legjobb — ~2–4% WER EN; ~30–50% WER jobb mint whisper-1 Managed végső fallback · BYOK opció
Azure AI Speech / OAI Whisper ~$0.006 ✅ EU Data Zones ✅ Kiváló (Whisper arch.) ✅ Jó — azonos Whisper large-v3 szint BYOK B2B compliance tier (Fázis 2)
Gemini 2.5 Flash (Vertex) ~$0.001–0.002 ✅ EU (europe-west4) 🟡 Tesztelendő 🟡 Tesztelendő — Google erős multilingvális, CEE benchmark nincs Jövőbeli managed kandidált
OpenAI GPT-4o (full, chat API) $5–15/1M token ❌ US 🟡 Tesztelendő ✅ Magas — de NEM dedikált STT API KIZÁRVA — ld. ADR lent
Gemini 2.5 Pro $1.25–2.50/1M token ✅ EU (Vertex) 🟡 Tesztelendő ✅ Magas — de NEM dedikált STT API KIZÁRVA — ld. ADR lent
Deepgram Nova-3 $0.0043 ✅ SCC, EU ❌ CEE kódváltásnál megbízhatatlan ✅ Jó — ~5.26% WER EN monolinguális PRIMARYKIZÁRVA (2026-04-11 éles teszt)
Groq Whisper Turbo ❌ Gyenge CEE WER ❌ Gyengébb mint large-v3 KIZÁRVA
Google Chirp 2 ❌ Auto-detect megbízhatatlan ❌ CEE-n gyenge KIZÁRVA
ℹ️ NOTE

ADR — Miért nem GPT-4o (full) és miért nem Gemini 2.5 Pro STT-re? GPT-4o (full, chat API) kizárás: A GPT-4o chat API nem dedikált STT — audio bemenetből szöveget tud generálni, de ez multimodal chat completion, nem transzkripció. Problémák:

  • Ár: $5–15/1M input token vs. gpt-4o-transcribe ~$0.006/perc = 10–50× drágább azonos feladatra
  • Kontroll hiánya: A chat completion modell hozzáadhat, parafrazeálhat, „javíthat" — nem garancia az exact transcript outputra
  • Nincs timestamp/confidence: gpt-4o-transcribe ad strukturált transzkripció-outputot; a chat API-nál ezt kézzel kellene parseolni
  • Konklúzió: Ha OpenAI-t akarunk, a gpt-4o-transcribe API a helyes eszköz — az jobb transzkripciós minőséget ad, olcsóbban, strukturáltan.
Gemini 2.5 Pro kizárás: A Gemini 2.5 Pro szintén multimodal chat modell, nem dedikált STT motor. Problémák:
  • Ár: $1.25–2.50/1M input token vs. Gemini 2.5 Flash ~$0.001–0.002/perc = 100–1000× drágább azonos STT feladatra
  • Latencia: A Pro méretű modell inferencia-ideje 2–5× lassabb mint Flash — hold-to-talk < 2s SLA-nk nem tartható
  • Over-engineering: A vocab-correction task (ahol esetleg indokolt lenne a Pro) inherensen egyszerű — kisebb modell kevesebbet „okoskodik", pontosabb output
  • Konklúzió: Gemini 2.5 Flash (STT) + Gemini 1.5 Flash (LLM post-proc.) pontosan elég. A Pro méret semmit nem ad a use case-hez — csak drágább és lassabb.
Deepgram Nova-3 kizárás — kontextus (cross-reference: STT UX Architecture riport, 2026-04-11) A kizárás CEE kódváltó éles teszt alapján történt, NEM általános WER benchmark alapján. A 2026-os iparági kutatás a Nova-3-at „high accuracy" CEE motorként értékeli (monolinguális HU WER ~5.26%) — ez az adat önmagában helyes. A VibeVox use case azonban CEE kódváltó (HU+EN, PL+EN ugyanazon utterance-ban), amihez Deepgram API nem biztosít primary=HU, secondary=EN hint megadási lehetőséget. Éles teszten (language=multi): magyar mondatok svéd szövegként leiratba kerültek (finnugor–skandináv fonológiai átfedés) — ez diszqualifikáló. Monolinguális, EN-only BYOK use case-re a Nova-3 alternatívaként megtartható (ld. BYOK provider routing szekció). Forrás: stt_ux_architecture_analysis.md §6 · 17_TASK_CALENDAR.md ADR-002 · Érintett kutatás: Strategic UX and Architecture for Real-Time Professional Dictation Systems (2026-04-11)

BYOK Provider Routing — Átláthatóság-alapú modell

Alapelv: A BYOK tier provider-agnostik. A felhasználó maga dönt — a VibeVox tájékoztatja a trade-off-okról, de nem korlátozza a választást.

BYOK onboarding wizard — provider választás:

  ★ AJÁNLOTT: Groq Whisper large-v3
    Legjobb CEE WER + HU/EN kódváltás prompt-alapon + EU Frankfurt
    Ár: ~$0.00185/perc | Streaming: VAD-alapú szegmentálás
    → Ideális: minden CEE user, napi diktálók, jogi/orvosi B2B userek

  ○ Alternatíva: Deepgram Nova-3 (csak EN-domináns diktáláshoz)
    WebSocket streaming sebessége valós (~0.4 mp), de CEE kódváltásnál megbízhatatlan
    Ár: ~$0.0043/perc | Trade-off: drágább + CEE minőség nem megfelelő
    → Kizárólag akkor ajánlott, ha a user CSAK angol nyelven diktál

  ○ Haladó: OpenAI gpt-4o-transcribe
    Legjobb EN minőség, de US-adatközpont
    → Ideális: EN-only power userek, akiknek fontos az OpenAI ökoszisztéma

  ○ Vállalati: Azure AI Speech (Fázis 2)
    100% EU Data Residency, VNet integráció
    → Ideális: healthcare/legal B2B (GDPR hard requirement)

  ✗ NEM ELÉRHETŐ: Groq Whisper Turbo — gyenge CEE WER
  ✗ NEM ELÉRHETŐ: Google Chirp 2 — megbízhatatlan multi-language

Margin megjegyzés: A BYOK felhasználó saját API kulcsával fizet közvetlenül a providernek — a VibeVox €3,50/hó licence fix bevétel, független a provider választástól. A VibeVox margin 100% a BYOK tiernél.

BYOK STT Provider — API Capability Matrix

Forrás: GAP-C6 kutatás + Azure ADR (2026-04-19 — éles API referencia alapján) Cél: Meghatározni, melyik providernél mit tudunk lefejleszteni (feature feasibility per provider). Ez az egyetlen hiteles referencia a provider-specifikus API korlátokhoz és fejlesztési lehetőségekhez.

STT (Transcription) Képességek

Képesség Groq Whisper large-v3 OpenAI gpt-4o-transcribe Google Gemini 1.5 Flash Azure OpenAI Whisper
Protokoll REST (batch) REST (batch) REST (batch / multimodal) REST (batch)
WebSocket streaming ❌ Nem elérhető ❌ Nem elérhető ❌ Nem elérhető¹ ❌ Nem elérhető²
Prompt paraméter prompt= string prompt= string ✅ System instruction (chat) prompt= string
Prompt token limit 224 token (Whisper arch.) ~200 token (prompt leakage kockázat) ~1M token (text), 32 tok/s audio 224 token (azonos Whisper arch.)
Rolling context max 224 token ✅ 200 token (konzervatív) 1 000 token (DÖNTÉS: 4× jobb, elhanyagolható cost) 224 token
Language hint language= BCP-47 language= BCP-47 System prompt szöveg language= BCP-47
Confidence score ⚠️ avg_logprob (szegmens szint, verbose_json) ❌ Nem elérhető ❌ Nem elérhető³ ❌ Nem elérhető
Word-level timestamps verbose_json + timestamp_granularities=["word"] ❌ — ❌ — ❌ —
CEE code-switching ✅ Kiváló (tesztelve, HU+EN) ✅ Legjobb EN (tesztelendő HU) 🟡 Tesztelendő ✅ Kiváló (Whisper arch.)
Max fájlméret 25 MB 25 MB ~20 MB⁴ 25 MB
Rate limit (free tier) 2 000 req/nap · 7 200 audio-s/h Fizetős (nincs ingyenes tier) Gemini API: 1 500 req/nap (free) Fizetős (Azure Portal)
Ár/perc (referencia) ~$0.00185 ~$0.006 ~$0.001–0.002 ~$0.006
EU Data Residency ✅ Frankfurt (SCC) ❌ US europe-west4 (Vertex) / ❌ AI Studio ✅ EU Data Zones

¹ Gemini Live API létezik WebSocket-tel, de audio→text streaming B2B production use-ra még nem érett (2026-04 állapot). A VibeVox Fázis 3+ roadmapján szerepel. ² Azure Cognitive Services Speech (NEM Azure OpenAI Whisper) támogatja a WebSocket streaming-et — de ezt ADR-002 kizárta (ld. §2.1 ADR szekció): a hold-to-talk batch modellhez irreleváns, és SDK-overhead nem indokolt. ³ Gemini candidates[0].safetyRatings ad content-filter jelet, de audio transzkripció accuracy score-t nem. ⁴ Gemini multimodal inline data limitje modell-függő; base64-ban küldött WAV esetén ~$0.002/mb overhead.

LLM Post-Processing Modellek — Részletes Összehasonlítás (Step 2c — Vocabulary Correction)

Kontextus: A vocab-correction pipeline (_orchestrator.py → _run_vocab_correction()) mind a 4 providernél más LLM-et hív az egykulcsos BYOK elv miatt. Ezek a modellek nem egyenértékűek — az alábbi tábla az fejlesztési döntéseket alátámasztó hiteles referencia.

A legkritikusabb tulajdonság: instruction-following minősége — a modell pontosan az utasítás szerint dolgozik-e? A vocab-correction taskban: „Csak a félrehallott technikia szavakat javítsd. Ne változtass mondatszerkezeten, ne adj hozzá, ne vegyél el semmit." Ha a modell ennél többet tesz, a user elveszíti a bizalmat.

Modell specs (jelenlegi VibeVox választás + benchmark összehasonlítás):

A szürke oszlopok (gpt-4o, Gemini 2.5 Pro) nem kerülnek implementálásra — referenciaként szerepelnek, hogy lássuk mit nyernénk/veszítenénk a váltással.

Groq — Llama 3.1 8B (aktív) OpenAI — gpt-4o-mini (aktív) Google — Gemini 1.5 Flash (aktív) Azure — gpt-4o-mini (aktív) OpenAI — gpt-4o (referencia) Google — Gemini 2.5 Pro (referencia)
Modell méret 8B ~8–9B (zárt) MoE ~unknown = gpt-4o-mini ~200B (becsült) ~unknown (MoE, nagy)
Kontextus ablak 128K 128K 1M 128K 128K 1M
Max output token 8 192 16 384 8 192 16 384 16 384 65 536
Sebesség ⚡ ~500–800 tok/s ~80–120 tok/s ~150–250 tok/s ~80–120 tok/s ~40–80 tok/s ~60–100 tok/s
E2E latencia hatás +50–100ms +150–300ms +100–200ms +150–300ms +300–600ms +200–400ms
Cost/1M input token $0.05 $0.15 $0.075 $0.165 $2.50 $1.25
Cost/1M output token $0.08 $0.60 $0.30 $0.66 $10.00 $10.00
Becsült cost/diktálás ~$0.00005 ~$0.0002 ~$0.0001 ~$0.0002 ~$0.003 ~$0.002
Cost szorzó vs mini 1× (Groq) 0.5× ~15–17× ~10–13×
temperature=0 generationConfig
EU Data Residency ❌ US ❌ US ✅ Vertex EU ✅ Azure EU ❌ US ✅ Vertex EU

Minőségi dimenziók (vocab-correction feladatra, 1–10 skálán):

Módszertan: Iparági benchmarkok (LMSYS, Chatbot Arena, OpenAI/Google belső) + vocab-correction specifikus szempontok (instruction-following, CEE language, over-correction hajlam). A számok relatív rangsorolást tükröznek, nem abszolút mértéket.

Llama 3.1 8B gpt-4o-mini Gemini 1.5 Flash Azure gpt-4o-mini gpt-4o Gemini 2.5 Pro
🎯 Instruction-following 🟡 6/10 ✅ 8/10 ✅ 8/10 ✅ 8/10 ✅✅ 9.5/10 ✅✅ 9.5/10
⚠️ Over-correction kockázat 🟠 Magas ✅ Alacsony ✅ Alacsony ✅ Alacsony ✅ Minimális ✅ Minimális
🌍 CEE szófelismerés (HU/PL/CZ) 🟡 6/10 ✅ 8/10 🟡 7/10* ✅ 8/10 ✅✅ 9/10 ✅✅ 9/10
📚 Szótárméret-skálázás 🟡 ~150 szó max ✅ 1 000+ ✅✅ 10 000+ ✅ 1 000+ ✅ 1 000+ ✅✅ 10 000+
🚫 Hallucináció / hozzáadás 🟠 Ritkán előfordul ✅ Alacsony ✅ Alacsony ✅ Alacsony ✅ Nagyon alacsony ✅ Nagyon alacsony
🔤 Multilingual output stabilitás ✅ Stabil ✅ Erős 🟡 Tesztelendő ✅ Erős ✅✅ Kiváló ✅✅ Kiváló
⚡ Sebesség (pipeline impact) ✅✅ Legjobb ✅ Jó ✅ Jó ✅ Jó 🟡 Lassabb 🟡 Közepes
💰 Cost-efficiency ✅✅ Legjobb ✅ Jó ✅✅ Nagyon jó ✅ Jó ❌ 15–17× drágább ❌ 10–13× drágább
📊 Összesített érték-arány 🟡 6.5/10 8.5/10 8/10 8.5/10 🟡 7/10 🟡 7.5/10

*Gemini 1.5 Flash CEE coverage: Google belső training adatok HU/PL/CZ jelenlétét nem publikálják; a Flash modell multilingual erős, de a CEE specifikus ragozás-invariáns javítás mélysége tesztelendő.

ADR — Miért nem gpt-4o (full) és miért nem Gemini 2.5 Pro? (2026-04-19, végleges)

⚡ IMPORTANT

Döntés: A vocab-correction task szándékosan mini/flash modelleket használ. Ez NEM kompromisszum — ez a feladathoz optimális választás. Az alábbi okok egymást erősítik.

Szempont Mini/Flash (jelenlegi) Full/Pro (elvetett) Verdict
Instruction-following delta 8/10 9.5/10 +1.5 pont — a vocab-correction prompt egyszerű elég, hogy 8/10 is elég legyen
Cost delta/diktálás ~$0.0001–0.0002 ~$0.002–0.003 15–17× drágább — BYOK user saját számlájára megy
Latencia delta +100–300ms +300–600ms +200–300ms extra — felhasználó érzi (3s flow-state limit)
Over-correction kockázat Alacsony Minimális A különbség marginális — a full modell „okosabb" átírás kísértésével ellensúlyozza
Task komplexitás Egyszerű szócsere — nem igényel reasoning-t Reasoning kapacitás kihasználatlan marad Pazarlás 10× áron
Szótárméret limit 1 000+ szó (Mini/Flash) — elegendő Nincs előny Nincs win a full modellnél

Mikor érdemes mégis full modellre váltani (trigger feltételek):

gpt-4o full → bekapcsol, ha:
  ✓ OpenAI BYOK user aktív szótára > 500 orvosi/jogi terminus
  ✓ AND user explicit "Maximum Quality" módot vált (opt-in Fázis 2+)
  ✓ AND user elfogadja a ~15× cost overhead-et (előre közölt)
  → Implementáció: quality_tier=["standard", "max"] setting + orchestrator branch

Gemini 2.5 Pro → bekapcsol, ha:
  ✓ Gemini BYOK user + aktív szótár > 1 000 szó (Flash 1M = bőséges, szóméret nem trigger)
  ✓ AND mért CEE WER romlás > 5% a Flash teszten (cédulaváltó)
  → Egyelőre nem indokolt — Fázis 2 A/B teszttől függ
ℹ️ NOTE

Összefoglalva: A gpt-4o összesített érték-aránya 7/10 vs. gpt-4o-mini 8.5/10 — azaz a mini nem egyszerűen „olcsóbb alternatíva", hanem a vocab-correction taskhoz objektíven jobb választás, főleg ha figyelembe vesszük, hogy a full modell erős reasoning képessége itt kihasználatlan marad és olykor éppen az over-correction irányába tolja a modellt.

Fejlesztési konzekvenciák és watchlistek:

Kérdés Döntés / Figyelő
Mikor kell Llama 3.1 8B-t lecserélni? Ha a Groq BYOK vocab-correction user-panasz top-3-ba kerül (over-correction, kihagyott szavak) → upgrade Llama 3.3 70B-re (drágább, de 8× pontosabb instruction-following)
Gemini CEE minőség validálás Fázis 1.5 smoke test: 50 HU+EN mondat × 20 szótárszó → mért WER a javítás előtt/után. Ha rontja a CEE szavakat → fallback Groq Llama 3-ra Gemini STT esetén is
Llama 3.1 8B szótárméret limit Ha aktív szótár > 100 szó + persona prompt → tokenszám > 4K → 8K kontextus szorul. Monitor: prompt_tokens logolása _orchestrator.py-ban. Küszöb: 6 000 token → warning
Azure gpt-4o-mini vs OpenAI gpt-4o-mini Azonos modell, de Azure EU data residency-t ad → B2B healthcare/legal tier számára Azure BYOK kötelező ajánlás, nem opció
Gemini 1M kontextus kihasználás Gemini BYOK vocab-correction esetén opcionálisan az egész session history beküldhető system-promptba → Gemini egyértelmű winner long-form B2B diktálásnál (orvosi lelet, jogi szerződés folytatása)
⚠️ WARNING

Llama 3.1 8B Instant — ismert korlát: A modell 8B paramétermérete miatt a „ne változtass semmit a javításon kívül" boundary case-eknél nem 100% megbízható. A jelenlegi prompt a _lang_helpers.py-ban tartalmaz explicit záróutasítást: „Output ONLY the corrected transcript. Do not add explanations." — ez csökkenti, de nem eliminálja a kockázatot. Fázis 2-ben A/B teszt Llama 3.3 70B ellen.

ℹ️ NOTE

Miért nem gpt-4o (full) és nem Gemini 2.5 Pro? A vocab-correction task szándékosan konzervatív modelleket használ: az egyszerű, gyors, olcsó modell (8B–mini méret) pontosan elég a szótárjavításhoz, és a veszélye kisebb mint egy erős modellé (kevesebb esély az „okos átírásra"). A jobb modell = jobb instruction-following, de nem = jobb output, ha a task inherentemente egyszerű.

Fejlesztési Feasibility Összefoglaló (mi fejleszthető melyik providernél)

Feature Groq OpenAI Gemini Azure
Rolling context (Whisper prompt) ✅ 224 tok ✅ 200 tok ✅ 1 000 tok ✅ 224 tok
Vocabulary correction (LLM) ✅ Llama 3 ✅ gpt-4o-mini ✅ 1.5 Flash ✅ gpt-4o-mini
Low-confidence toast (GAP-C3) avg_logprob ❌ N/A ❌ N/A ❌ N/A
Word-level timestamps
WebSocket live streaming 🟡 Fázis 3+ ❌ (Speech-only, ADR kizárta)
EU GDPR compliance ✅ (Vertex)
B2B VNet integráció 🟡 Vertex Private
CEE code-switch minőség ✅ Tesztelve 🟡 Tesztelendő 🟡 Tesztelendő ✅ Whisper arch.
ℹ️ NOTE

Legfontosabb fejlesztési korlát (2026-04-19): A low-confidence toast (GAP-C3) csak Groq-nál működik natívan — az egyetlen provider, amelyik avg_logprob szegmens-szintű pontossági jelzést ad vissza. Az összes többi provider esetén a felhasználónak saját megfigyelésre kell hagyatkoznia.

💡 TIP

Gemini rolling context stratégiai előnye: A Gemini 1.5 Flash 1M tokenes kontextusa lehetővé teszi, hogy az STT rolling context az egész diktálási session előzményét magában foglalja — nem csak az utolsó ~150 szót (224 token). Ez B2B long-form diktálóknál (orvosi lelet, jogi beadvány) lényegesen jobb kontextus-öröklést ad. A Gemini BYOK tier így valódi differenciáló érv hosszú dokumentumokhoz.

Session hard cap

# workers.py — session limitek
MAX_SESSION_DURATION = 360  # 6 perc másodpercben
WARNING_THRESHOLD = 300      # 5 percnél figyelmeztetés

Célja: Margin védelem (heavy usereknél veszteség megelőzése) + UX (fókuszált munkamód).

A Typeless szintén 6 perces session limitet alkalmaz — de az ő felhasználóik ezt negatívumként élik meg (flow state megszakítás). A VibeVox-ben ez tudatos UX döntés:

  1. Hold-to-talk modell = természetes szünet a gombengedéskor
  2. Session Summary Toast = „127 szó, ~3 perc megtakarítva" → pozitív megerősítés
  3. Margin védelem = heavy userek sem generálnak veszteséget

A VibeVox UX-ben a 6 perc NEM limit, hanem „mikro-fókusz session" framing.

Post-processing (post_process.py)

Filler word eltávolítás (opt-in, default be):
  HU: ööö, hát, szóval, ugye, tehát, mondjuk
  EN: um, uh, like, you know, basically

Automatic punctuation:
  Mondatvég detektálás (hosszú szünet → pont)
  Magyar kérdő mondat felismerés
  Nagybetű mondatkezdetek

Fázis 2 tervezve:
  Tone control (casual → formal)
  Template alkalmazás (jogi emlékeztető, orvosi lelet)
  Style Personas → ld. §2.3b Style Personas architektúra (alább)

2.3b. Style Personas — Stílus-személyiség rendszer (Fázis 1.5)

⚡ IMPORTANT

Döntés (2026-04-18): A Style Personas a VibeVox LLM post-processing pipeline kiterjesztése. Tier: FREE — teljes funkcionalitás beleértve a Custom Persona-t. Indok: a stílus-horgony a legerősebb retention driver; ha valaki kialakít egy saját stílust, a 20 000 szavas free kvóta lesz az egyetlen konverziós trigger — nem a feature hiánya.

Architektúra

STT output (nyers transzkript)
    │
    ↓ LLM Post-Processing (Groq Llama 3 8B Instant / provider-matching)
    │   system_prompt = style_persona_prompt + aktív szótárak (ha van)
    │   EGYETLEN API hívás — nincs extra cost, nincs extra latencia
    │
    ↓ Stílusban átírt végleges szöveg → aktív ablakba

Kulcsarchitektúrális döntés: A Style Persona prompt és a vocabulary lista ugyanabba a system promptba kerül — nincs második LLM hívás. A cost-overhead minimális: ~50–200 extra token a persona definíciójától függően.

Beépített Style Personas (FREE — teljes hozzáférés)

Alapstílusok:

ID Név Leírás Prompt stratégia
standard Standard Nincs átírás — pure transcription (alapértelmezett) LLM nem fut
concise Tömör Max. 30%-os tömörítés, lényegre törő „Keep core meaning, remove filler and padding"
professional Professzionális Formális, magázódó, strukturált „Rewrite formally, use proper grammar"
friendly Barátságos Közvetlen, tegeződő, meleg hangvétel „Casual, warm, use 2nd person singular"
executive Vezetői összefoglaló Bullet points, kulcspontok kiemelve „Extract key points as bullet list"

Formality Conversion — multi-language (implementálva: 2026-04-18):

UI: app/ui/tabs/style_tab.py_FORMALITY_LANG_MAP dict + language-aware toggle A Style tab Formality szekciója az elsődleges nyelv (primary_language setting) alapján automatikusan a megfelelő szabályokat alkalmazza.

ID Trigger nyelv Preferred forms Tiltott formák Gender-aware?
hu_onozo Hungarian Ön • Önnek • Önt • Önnel maga • magának (TILTOTT) Nem
de_siezen German Sie • Ihnen • Ihr • Ihre Nem
fr_vouvoyer French vous • votre • vos Nem
es_ustedeo Spanish usted • su • sus Nem
it_lei Italian Lei • La • Le Nem
pl_panpani Polish Pan / Pani Igen
cs_vikani Czech Vy • Vám • Vás Nem
sk_vikanie Slovak Vy • Vám • Vás Nem
ru_vy Russian Вы • Вас • Вам Nem
nl_u Dutch u • uw Nem
ro_dvs Romanian Dumneavoastră Nem
pt_senhor Portuguese o senhor / a senhora Igen
⚡ IMPORTANT

Magyar „maga" tilalom (2026-04-18 döntés): Az LLM prompt KIZÁRÓLAG „Ön" alakokat produkálhat. A „maga" forma régies, lekezelő — explicit tiltani kell a promptban. Minden HU formality prompt záróutasítása: „SOHA ne használd a 'maga' alakot." A tegeződő/magázódó konverzió egyedülálló CEE piacon — marketing kulcsmondat: „Diktáld úgy, ahogy kényelmes — kapod úgy, ahogy illik."

Fun / Viral stílusok (FREE — megosztást generál):

ID Név Leírás Viral potenciál
yoda 🧙 Yoda Megfordított mondatrend, archaikus szóhasználat 🔴 Maximális — TikTok/Twitter demo
victorian 👑 Viktoriánus úr Angol arisztokrata stílus, „I daresay" fordulatok 🟠 Magas — EN-domináns
pirate 🏴‍☠️ Kalóz Ahoy!, Arr!, tengerész szleng 🟠 Magas — HU+EN vicces
news_anchor 📺 Hírolvasó Formális, tárgyilagos tónus 🟡 Közepes
hal9000 🤖 HAL 9000 Hideg, precíz, kissé fenyegető AI tónus 🟠 Magas — tech/geek közösség

Yoda kompatibilitás CEE nyelveken: Angolból vicces, mert az SVO normát töri meg (SOV). Magyar és szláv nyelveken az erőltetett szórendfordítás + archaikus szókincs kombinációja más mechanizmussal de hasonló hatást ér el. HU — várhatóan működik. PL/CZ/SK — A/B teszttel validálandó Fázis 1.5-ben.

Custom Style Persona (FREE — saját prompt)

Felhasználói szerkesztő:
  „Írj úgy, mint egy 18. századi levélíró..."
  „Minden mondatot kezdj igével..."
  „Maradj max. 2 mondatos, tűhegyes legyél"
  „Speak as an English aristocrat would..."

Korlátok:
  Max. prompt hossz: 500 karakter (UI display) / ~1000 token (feldolgozás)
  Sandbox: a user prompt rendszer-promptba kerül, NEM user-üzenetbe
           → prompt injection ellen védett

Tárolás: settings.db (lokális) + Supabase szinkron (ha bejelentkezve)
         → Multi-device: a saját stílus mindenhol elérhető
⚡ IMPORTANT

Custom Persona = FREE tier (2026-04-18 döntés): Ha valaki kialakítja a saját digitális hangját, ez a legerősebb pszichológiai lock-in — a 20 000 szavas kvóta lesz a konverziós trigger, nem a feature hiánya.

Brand Safety Tiltólista (2026-04-18 — kutatás alapján formalizálva)

Forrás: viral_style_personas_cee_analysis.md §3 — The "Red Flag" Spectrum

Custom Persona UI — blokkolt tartalmak (regex + proxy content filter):

❌ Aktív politikai vezető neve (Orbán, Babiš, Fico, Kaczyński…)
   → B2B reputációs kockázat: jogi/orvosi partner elveszítése
❌ Explicit profanitás vagy szexuális tartalom
   → B2B brand kizáró, enterprise deal-breaker
❌ Etnikai csoportokat negatívan caricaturizáló instrukció
   → GDPR reputációs kockázat + CEE community backlash

Implementáció: proxy-oldali regex blocklist + LLM moderation
Effort: ~0,5 nap (blocklist regex + proxy endpoint kiegészítés)

Beépített tiltólista — SOHA nem kerülnek official built-in personaként:

❌ Aktív CEE politikusok paródiája (Orbán, Babiš, Fico)
   → Partnerség-romboló, CEE B2B jogi szegmens számára disqualifying
❌ Borat / "Eastern European Mockery" archetype
   → Anti-CEE brand — ellentmond az alap positioning-nek
❌ Gen Z Brainrot / TikTok slang
   → Gyors avulás (temporális decay) = folyamatos prompt-maintenance cost
   → Custom Persona-ként lefedhető, built-in felesleges

✅ Typowy Janusz (PL): ENGEDÉLYEZETT — in-group, kulturálisan beágyazott
✅ Tabloid Vendég / Mónika (HU): ENGEDÉLYEZETT — energia paródiája, profanitás nélkül
✅ Rytmus (SK): DÖNTÉS FÜGGŐBEN — valós személy → jogi kockázat vizsgálandó

Prompt Engineering Robustossági Szabályok (2026-04-18)

Forrás: viral_style_personas_cee_analysis.md §1 — LLM Feasibility

1. Szemantikai integritás — kötelező záró utasítás MINDEN beépített promptban:

Minden persona system prompt KELL tartalmazzon:
"Keep ALL factual content, numbers, names, and dates exactly as stated.
 Do NOT add, remove, or alter any factual information."

Indok: a szemantikai inverzió (AI átírja/rövidíti a tartalmat) az AI diktáló
appok #1 churn triggerének bizonyult. ← Már implementálva a fenti BUILT_IN_PERSONAS dict-ben.

2. CEE personák — few-shot záradék kötelező (Fázis 1.5):

A Typowy Janusz prompt tartalmazzon 1 példapárt, mert Groq Llama 3
generic approximation-re esik vissza few-shot nélkül:

Példa input:  "A szoftver frissítése 2 napot vett igénybe."
Példa output: "Kiedyś to było — két nap egy frissítésre?! Grażyna, hallod ezt?
               Régen ez öt perc alatt ment, mert az emberek DOLGOZTAK."

3. Yoda CoT (Chain-of-Thought) szintaxis inverziónál:

A Yoda prompt már tartalmazza a lépéseket:
  Step 1: Identify the main verb.
  Step 2: Move the object to sentence start.
  Step 3: Place subject and verb at end.
← Ez 60-70%-kal javítja az OSV-konzisztenciát komplex mondatokon (kutatás alapján).

Technikai implementáció

# style_personas.py — örököl az LLM post-processing pipeline-tól (_orchestrator.py)

BUILT_IN_PERSONAS = {
    "standard":      None,  # LLM NEM fut
    "concise":       "Rewrite the following transcription concisely. Keep all meaning, remove filler and padding. Output only the rewritten text. Keep ALL factual content, numbers, names, and dates exactly as stated.",
    "professional":  "Rewrite the following transcription in formal, professional language. Use önöző (formal) form for Hungarian. Keep all content. Keep ALL factual content, numbers, names, and dates exactly as stated.",
    "friendly":      "Rewrite the following transcription in a warm, casual, tegeződő style. Keep all content. Keep ALL factual content, numbers, names, and dates exactly as stated.",
    "executive":     "Extract the key points from the following transcription as a concise bullet list. Keep ALL factual content, numbers, names, and dates exactly as stated.",
    # ── Formality Conversion — language-aware (Style tab toggle) ─────────────
    "hu_onozo":      "Alakítsd át az alábbi szöveget magázódó stílusra. Kizárólag 'Ön' alakokat használj (Önnek, Önt, Önnel, Önhöz). SOHA ne használd a 'maga' szót. Minden tartalmat őrizz meg.",
    "de_siezen":     "Wandle den folgenden Text in eine formelle Anrede um. Verwende 'Sie', 'Ihnen', 'Ihr', 'Ihre'. Behalte alle Inhalte bei.",
    "fr_vouvoyer":   "Transforme le texte suivant en vouvoiement. Utilise 'vous', 'votre', 'vos'. Conserve tout le contenu.",
    "es_ustedeo":    "Transforma el siguiente texto al tratamiento formal. Usa 'usted', 'su', 'sus'. Conserva todo el contenido.",
    "it_lei":        "Trasforma il seguente testo in forma formale. Usa 'Lei', 'La', 'Le', 'Suo'. Mantieni tutto il contenuto.",
    "pl_panpani":    "Przekształć poniższy tekst na formę grzecznościową. Użyj formy 'Pan' lub 'Pani' (odpowiednio do kontekstu). Zachowaj całą treść.",
    "cs_vikani":     "Převeď následující text do vykání. Používej 'Vy', 'Vám', 'Vás'. Zachovej veškerý obsah.",
    "sk_vikanie":    "Preveď nasledujúci text do vykania. Použi 'Vy', 'Vám', 'Vás'. Zachovaj celý obsah.",
    # ── Fun / Viral stílusok ─────────────────────────────────────────────────
    "yoda":          ("Rewrite the following text in the style of Yoda from Star Wars. "
                      "Step 1: Identify the main verb. Step 2: Move the object to sentence start. "
                      "Step 3: Place subject and verb at end. Use archaic phrasing. "
                      "Keep ALL factual content, numbers, names, and dates exactly as stated."),
    "victorian":     "Rewrite the following text as a Victorian English gentleman would write. Use formal, elaborate language with period-appropriate phrases. Keep ALL factual content exactly as stated.",
    "pirate":        "Rewrite the following text in pirate speak. Add nautical metaphors. Keep ALL factual content, numbers, names, and dates exactly as stated.",
    "news_anchor":   "Rewrite the following text as a professional news anchor would deliver it. Neutral, formal, declarative. Keep ALL factual content exactly as stated.",
    "hal9000":       "Rewrite the following text in the style of HAL 9000. Cold, precise, slightly ominous. Keep ALL factual content exactly as stated.",
    # ── CEE personák (Fázis 1.5 — 2026-04-18) ───────────────────────────────
    "linkedin_lunatic": (
        "You are a viral LinkedIn influencer. Rewrite the user's input as a sensationalized, "
        "self-congratulatory corporate post. Use single-sentence paragraphs. Inject words like "
        "'leverage', 'synergy', 'deep dive', 'bandwidth', 'pivot'. Add rocket (🚀) and "
        "fire (🔥) emojis. Conclude with a leadership lesson and 3 hashtags. "
        "Keep ALL factual content, numbers, names, and dates exactly as stated."
    ),
    "newsreel_1950": (
        "Rewrite the text to sound like a dramatic 1950s radio news anchor. Use rapid-fire, "
        "highly formal sentence structures. Include mid-century colloquialisms: 'say, buddy', "
        "'swell', 'gee whiz'. Frame the information as a sensational, breaking news bulletin. "
        "Keep ALL factual content exactly as stated."
    ),
    "typowy_janusz": (
        "Rewrite the text in Polish as a 'Typowy Janusz' — a complaining, provincial middle-aged "
        "Polish man. Use phrases like 'Kiedyś to było...'. Complain about costs and taxes. "
        "Reference your wife Grażyna or son Pjoter occasionally. Misspell common foreign loanwords "
        "phonetically (e.g. 'olinkluziw' for all-inclusive). "
        "Keep ALL factual content exactly as stated."
    ),
    "moravian_slang": (
        "Translate the text into highly colloquial Moravian Czech. Use 'su' instead of 'jsem'. "
        "Maximize regional street slang and morphological reductions. Maintain the underlying meaning."
    ),
    "prague_slang": (
        "Translate the text into highly colloquial Prague Czech (Pražák dialect). Use 'seš' instead "
        "of 'jsi'. Maximize colloquial reduction. Maintain the underlying meaning."
    ),
    "hu_monika": (
        "Rewrite the text in Hungarian in the energetic, dramatic style of a daytime tabloid TV "
        "guest. Use CAPITALIZATION for emphasis, multiple exclamation marks, rhetorical questions. "
        "Convey escalating emotional intensity. Do NOT use profanity. "
        "Keep ALL factual content exactly as stated."
    ),
}

def get_llm_system_prompt(persona_id: str, vocab_list: list, user_custom_prompt: str = None) -> str | None:
    """Returns None if no LLM processing needed (standard persona + no vocab)"""
    persona_prompt = user_custom_prompt or BUILT_IN_PERSONAS.get(persona_id)

    if not persona_prompt and not vocab_list:
        return None  # LLM nem fut — regex pipeline marad

    parts = []
    if persona_prompt:
        parts.append(persona_prompt)
    if vocab_list:
        parts.append(f"Additionally, correct these domain-specific terms: {', '.join(vocab_list)}")

    return "\n\n".join(parts)
Trigger kombináció LLM fut? System prompt tartalma
Standard + nincs szótár — (regex pipeline csak)
Standard + aktív szótár vocabulary correction only
Yoda + nincs szótár persona prompt only
Professional + aktív szótár persona + vocabulary combined
Custom persona + szótár user prompt + vocabulary combined

Tesztelési scope: 18 persona × managed/BYOK × szótár aktív/inaktív = 36 kombináció alap

  • 6 CEE persona × 4 CEE nyelv = 24 CEE-specifikus kombináció → **Összesen: 60 teszt Fejlesztési sprint: Fázis 1.5 (D+30–D+45)

Context-Aware Output Formatting — „Bet 3" (Fázis 2)

⚡ IMPORTANT

Döntés (2026-04-11 · riport: „Bet 3"): A Context-Aware Output Formatting a VibeVox mélység-moatjának következő rétege — az aktív ablak alapján adaptált szövegformázás olyan OS-szintű integráció, amelyet cloud SaaS versenytársak (Wispr, Typeless) technikailag nem tudnak replicate-elni.

Hogyan működik:

Aktív ablak detektálás (Win32 API / Linux wnck → process class)
    │
    ↓ Alkalmazás osztályozás
    │
    ├─ VS Code / JetBrains IDE   → „Vibe Coding Mode": camelCase/PascalCase/snake_case
    │                              (pl. „user profile component" → `UserProfileComponent`)
    │
    ├─ Terminal / Shell          → bash szintaxis: „sudo install nginx" → `sudo apt install nginx`
    │
    ├─ Slack / Discord / Teams   → casual tone, filler preservation, emoji-toleráns
    │
    ├─ Word / LibreOffice Writer → Document mode: auto paragraph, formal tone, heading detektálás
    │
    └─ Default (böngésző, egyéb)  → Standard Smart Mode (filler removal + írásjel)
Alkalmazás osztály Process Formázási hatás
VS Code / JetBrains code, idea, pycharm camelCase / PascalCase / snake_case azonosítás
Terminal emulators cmd, powershell, bash, fish shell szintaxis, sudo, git parancsok
Slack / Discord Slack.exe, Discord.exe casual tone, nincs auto-formális írásjel
MS Word / LibreOffice WINWORD.EXE, swriter document formázás, heading detektálás

Implementáció (Fázis 2, D+90–D+105):

  • app_context_detector.py — OS-specifikus aktív ablak lekérés
  • context_formatter.py — alkalmazás osztály → formázási szabályok dispatcher
  • Felhasználói override: minden alkalmazásnál kézzel felülírható (Settings → App Contexts)

2.5. Offline STT motor — faster-whisper + INT8 (Fázis 2)

Döntés (2026-04-11): A VibeVox offline módja a faster-whisper könyvtárra épül, CTranslate2 motorral, INT8 kvantálással. Ez a konfiguráció a legjobb ár/minőség/memória arányt nyújtja fogyasztói hardveren.

Miért faster-whisper, nem az OpenAI whisper csomag?

Metrika OpenAI whisper (FP16) faster-whisper (INT8)
Számítási motor PyTorch CTranslate2 (C++ alapú)
RAM igény (large-v3-turbo) ~6.4 GB ~3.0 GB
Sebesség Alap 4×+ gyorsabb
INT8 kvantálás Kézi, körülményes compute_type="int8" — 1 sor
Telepítési méret ~2.5 GB (PyTorch) ~400 MB (CTranslate2)

Miért nem Distil-Whisper?

🚨 CAUTION

Distil-Whisper CEE-n: fundamentálisan alkalmatlan. A riport elemzése szerint a Distil-Whisper 60–80%-kal kevesebb paraméterrel dolgozik, mint a large-v3-turbo — a CEE agglutináló morfológia (HU) és a klaszter-gazdag fonológia (PL) kezelésére ez elégtelen.

Metrika Distil-Whisper large-v2 faster-whisper large-v3-turbo (INT8)
Paraméterek ~756M (50%-kal kevesebb) ~809M (turbo-optimalizált)
Magyar WER (riport benchmark) ~18–25% ~3–5%
Lengyel WER ~14–20% ~4–6%
CEE morfológia kezelés ❌ Gyenge (distillation eltávolítja a ritka token reprezentációkat) ✅ Kiváló
Sebesség CEE-n ~2.5× gyorsabb mint large-v2 ~4× gyorsabb (INT8 kvantálás hatása)

Következtetés: A Distil-Whisper sebességelőnye a faster-whisper INT8 kvantálással minőségromlás nélkül elérhető. Distil-Whisper a VibeVox egyetlen pipeline szintjén sem szerepel — sem offline motorként, sem fallback-ként.

INT8 kvantálás — hogyan működik?

A Whisper neurális hálózat súlyait (weights) számokként tárolja. A precizitás meghatározza a memóriaigényt:

FP32 (32 bit/szám):  ~6.4 GB RAM  — feleslegesen pontos CPU-n
FP16 (16 bit/szám):  ~3.2 GB RAM  — standard, de még sok
INT8  (8 bit/szám):  ~1.6 GB RAM  ← modell fájl mérete

Futtatási RAM dekompozíció (large-v3-turbo, INT8, CPU):

Modell súlyok (INT8):           ~1.6 GB
Aktivációs memória (FP16):      ~0.8 GB  ← számítás közbeni ideiglenes tenzor
Audio buffer + tokenizer:       ~0.4 GB
Python / OS overhead:           ~0.2 GB
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Összesen:                       ~3.0 GB RAM

Minőség hatás (WER delta, CEE nyelveken):

  • FP16 → INT8 kvantálás: ~0.3–0.5% WER romlás — emberi fülnek érzékelhetetlen
  • Üzleti következmény: nincs, a minőségi fogadalmak tarthatók

Implementáció (1 sor konfiguráció)

from faster_whisper import WhisperModel

model = WhisperModel(
    "large-v3-turbo",   # ~1.6 GB letöltés (egyszer, cache-elve)
    device="cpu",        # GPU nélkül is fut — fogyasztói laptopokon
    compute_type="int8"  # INT8 kvantálás: 3× kisebb RAM, 4× gyorsabb
)

segments, info = model.transcribe(
    audio_file,
    language="hu",       # Szint 1: Primary Language PIN (nem auto-detect)
    beam_size=5
)

Offline pipeline (Fázis 2)

Hang rögzítés (workers.py)
    │ WAV, max 6 perc session
    ↓
RAM detekció (psutil) — induláskor EGYSZER, cachelve
    │
    ├─ RAM ≥ 8 GB  → Offline pipeline (lentebb)
    └─ RAM < 8 GB  → Cloud fallback (Deepgram/Groq) + Toast figyelmeztetés
    │
    ↓ [Offline ág]
faster-whisper model (large-v3-turbo, INT8, CPU)
    │ Lokális inferencia — hang nem hagyja el a gépet
    │ Várható sebesség: ~RTF 0.3–0.6 (reáltime 1.6–3.3× sebességgel)
    │
    ↓
post_process.py (filler removal, írásjel) — azonos a cloud pipeline-nal
    │
    ↓
Szöveg beillesztése az aktív ablakba
    │
    ↓
Storage: SQLite (local) — felhő szinkron opcionális (history feature)

Hardver threshold táblázat

RAM GPU (VRAM) Ajánlott modell Mód
< 8 GB ❌ Cloud fallback (automatikus)
8–15 GB large-v3-turbo (INT8, CPU) ✅ Offline Turbo
16–31 GB large-v3-turbo (INT8, CPU) ✅ Offline Turbo (ajánlott sáv)
32 GB+ CPU only large-v3-turbo (INT8) ✅ Offline Turbo, max kényelem
32 GB+ ≥ 10 GB VRAM large-v3 (FP16, CUDA/ROCm) ✅ Offline Prémium (opt-in, ~10 GB VRAM)
ℹ️ NOTE

BYOK LTD tartalmazza az offline módot — nem addon. A per-device beállítás Supabase-ben tárolódik: az erős laptop offline Turbo-n fut, a gyenge eszköz/telefon automatikusan cloud-ra vált. Egy account, minden eszközön a megfelelő mód.

Modell letöltő UX specifikáció (Fázis 2)

In-app letöltő wizard (első offline aktiváláskor):

  ┌─────────────────────────────────────────────────┐
  │  Offline mód beállítása                         │
  │                                                 │
  │  Rendszer: 16 GB RAM ✅  (Elegendő)             │
  │                                                 │
  │  ★ AJÁNLOTT: Whisper large-v3-turbo             │
  │    Méret: 1.6 GB  |  RAM igény: ~3 GB           │
  │    Minőség: CEE nyelveken kiváló                │
  │    [████████████████░░░░] 73%  ~2 perc          │
  │                                                 │
  │  ○ Prémium: Whisper large-v3 (csak 32 GB+ RAM)  │
  │    Méret: 3.1 GB  |  VRAM: ≥10 GB szükséges    │
  │    [Letöltés]                                   │
  └─────────────────────────────────────────────────┘

Jövőbeli gyorsítási útvonalak (Fázis 3+)

Miért nem most? A faster-whisper INT8 CPU-n Fázis 2-re elegendő (hold-to-talk use case: nem real-time streaming). A GPU gyorsítás Fázis 3-ban kerül napirendre, ha a CEE user feedback latencia-panaszt jelez.

A három gyorsítási opció összehasonlítása:

Technológia Eszköz RTF* 60 mp átírása Elérhetőség Komplexitás
faster-whisper INT8 CPU ~0.4 ~24 mp ✅ Minden laptop ✅ Alacsony
faster-whisper CUDA NVIDIA dGPU ~0.05 ~3 mp ⚠️ NVIDIA laptopok ✅ Alacsony (auto-detect)
whisper.cpp Vulkan iGPU (Intel/AMD) ~0.1–0.15 ~6–9 mp 🟡 Minden modern laptop 🔴 Magas

RTF = Real-Time Factor (0.1 = 10× valós idő felett)


faster-whisper CUDA — Fázis 2 opcionális (alacsony effort)

Ha NVIDIA dGPU detektálva → device="cuda" automatikusan. Csak 1 sor változás:

import torch

device = "cuda" if torch.cuda.is_available() else "cpu"
model = WhisperModel("large-v3-turbo", device=device, compute_type="int8")
# Ha NVIDIA GPU van: CUDA, ha nincs: CPU — ugyanaz a kód

Implementációs cost: ~1 nap. Fázis 2-ben bekapcsolható ha a torch + cudatoolkit dependency vállalható.


whisper.cpp + Vulkan — mi ez és miért Fázis 3?

whisper.cpp = a Whisper modell C++-ban újraírva
  - Nincs Python, nincs PyTorch
  - Natív bináris → minimális méret, maximális sebesség

Vulkan = alacsony szintű GPU API (Khronos, nyílt szabvány)
  Összehasonlítás:
  ┌──────────┬────────────┬───────────────────────────┐
  │  API     │  Gyártó    │  Fut ezen                 │
  ├──────────┼────────────┼───────────────────────────┤
  │  CUDA    │  NVIDIA    │  Csak NVIDIA dGPU         │
  │  ROCm    │  AMD       │  Csak AMD dGPU (korl.)    │
  │  Metal   │  Apple     │  Csak Mac                 │
  │  Vulkan  │  Khronos   │  NVIDIA + AMD + Intel iGPU│
  └──────────┴────────────┴───────────────────────────┘

iGPU (Integrált GPU) = CPU-ba épített grafikus processzor
  - MINDEN modern Intel/AMD laptopban van
  - Nincs saját VRAM — a rendszer RAM-ból merít
  - Intel Iris Xe (2020+) / AMD Radeon Vega (Ryzen 4000+)

Miért vonzó: 3-4× gyorsabb a CPU-nál, és minden laptopban van

Miért nem Fázis 2?

Blokkoló Részletek
Driver stabilitás Intel Xe + Vulkan 2025-ben: kiszámíthatatlan crashek egyes disztribúciókon
Python integráció C++ könyvtár → pywhispercpp wrapper szükséges (külső, nem hivatalos)
CEE WER ismeretlen Nincs publikus benchmark iGPU + Vulkan kombináción CEE nyelveken
Build komplexitás Custom CMake build + Vulkan SDK szükséges a disztribúcióhoz
faster-whisper elég Hold-to-talk use case-re a CPU sebesség elfogadható

ADR-001: On-Device STT Integration Decision (GAP-3)

⚡ IMPORTANT

Státusz: HALASZTVA — 12 hónapos deferred döntés, formalizálva 2026-04-11 Ez az ADR rögzíti, hogy a VibeVox mikor és milyen feltételekkel vezeti be a whisper.cpp + NPU/Vulkan hardware-gyorsított offline motort. A faster-whisper INT8 CPU-motor (2.5. szekció) ettől független, már eldöntött Fázis 2 funkció.

Kontextus

A VibeVox jelenleg két offline STT track-et tart nyilván:

Track Technológia Fázis Döntés
A — Szoftver-alapú faster-whisper INT8, CPU/CUDA Fázis 2 (D+77) ELDÖNTVE — implementálás folyamatban
B — Hardware-gyorsított whisper.cpp + Vulkan/NPU Fázis 3+ ⏸️ HALASZTVA — jelen ADR határozza meg

Ez az ADR kizárólag a Track B döntési keretét rögzíti.

Döntés

A whisper.cpp + Vulkan/NPU integrációja halasztva. A Track A (faster-whisper) elegendő a Fázis 2 use case-re. A Track B-re való áttérés csak akkor indul, ha az alábbi triggerek MIND teljesülnek.

Triggerek — minden feltétel szükséges

1. Hardware Trigger — NPU driver stabilitás

AMD Ryzen AI (XDNA architektúra) / Intel Lunar Lake NPU
  Target Q: Q3 2027 (gyártói roadmap alapján)
  Mérés: 3+ egymást követő negyedévben nulla driver crash report
           CEE célplatformokon (Fedora 41+, Ubuntu 26.04 LTS)
  Forrás: kernel.org AMD/Intel driver changelog, LWN.net GPU hírek

2. Minőségi Trigger — CEE WER benchmark

whisper.cpp Vulkan + Large-v3-Turbo INT8
  Küszöb: CEE WER ≤ 5% delta a faster-whisper CPU INT8-hoz képest
           (HU + PL tesztkészleten — azonos tesztprotokollt mint D+83 A/B teszt)
  Publikus: Minimum 1 reprodukálható nyilvános benchmark szükséges
  Ha delta > 5%: Track B elutasítva, addig Track A marad

3. UX/Disztribúció Trigger — Flatpak kompatibilitás

  Feltételek:
    - Flatpak bundle méret ≤ 3 GB (modell + runtime együtt)
    - Auto-update megoldható (delta package vagy külső model store)
    - Flatpak sandbox: Vulkan hozzáférés konszisztensen működik
                       (jelenleg: --device=all szükséges, sandbox escape)
  Mérés: Flathub submission teszt Fedora + Ubuntu clean install-on

4. Felhasználói Visszajelzés Trigger

  Threshold: Latencia-panasz > 5% support ticketek
             (kizárólag Managed Cloud + offline mode kombináltan)
  Mérés: Plain.com ticket kategorizáció negyedévenként

Következmények (ha MINDEN trigger teljesül)

Aktiválás:
  1. Kutatási sprint: 2 hét
     → whisper.cpp build pipeline (CMake + Vulkan SDK + Flatpak)
     → CEE WER benchmark saját tesztkészleten
     → pywhispercpp wrapper stabilitás vizsgálat
  
  2. Fázis 3 feature:
     → Track B opcionális, opt-in UI a Track A mellé
     → "Kísérleti — NPU gyorsítás" jelölés első 2 kiadáson
  
  3. Track A nem szűnik meg:
     → Fallback: ha NPU driver crash → automatikus Track A

Negyedéves Review Ütemezés

Dátum Review feladat
2026-10-01 (Q3) NPU driver + minőség + UX trigger státusz — első check
2027-01-01 (Q4) Lunar Lake / Ryzen AI driver release notes review
2027-04-01 (Q1) Döntési pont: triggerek teljesülnek? → Fázis 3 sprint indítás?
2027-07-01 (Q2) Ha 2027 Q1-es sprint eredményes: Fázis 3 éles implementáció
ℹ️ NOTE

Review kötelező elvégezni akkor is, ha nincs látható változás. A negyedéves check biztosítja, hogy nem születnek ad-hoc döntések 12 hónappal later.


2.6. Mid-Dictation Abort — ESC Hotkey Specifikáció (GAP-C5)

⚡ IMPORTANT

Döntés (2026-04-18 · GAP-C5 elfogadva): Az ESC key mid-dictation abort a keyboard-native, legkisebb súrlódású megoldás a "Scratch that" voice command-alapú Dragon-megközelítéssel szemben. Fázis 1-ben implementálandó — a becsült effort ~3 óra. Forrás: strategic_ux_architecture_analysis.md — GAP-C5

Két fázisú abort modell

ESC = Mid-Dictation Abort

── FÁZIS A: Aktív diktálás közben (hotkey tartva) ─────────────────────
  Esemény: User ESC-t nyom miközben a diktálás gombot tartja
  
  1. workers.py → audio buffer drop (rögzített hang eldobva)
  2. ui.py / live_bubble.py → Live Bubble clear (UI azonnali törlés)
  3. workers.py → WebSocket kapcsolat bontva (stream severed)
  4. KRITIKUS: hotkey release NEM injektál szöveget
     → inject_text() hívás blokkolt, ha abort_flag = True
  
  abort_flag életciklus:
    ESC_keydown → abort_flag = True
    hotkey_release → inject_text() FeltételVizsgálat: if abort_flag → skip
    hotkey_release → abort_flag = False (reset következő sessionra)

── FÁZIS B: Post-injection (szöveg már a target appban van) ──────────
  Esemény: szöveg már beillesztve → user rossz volt a diktálás
  
  Megoldás: Ctrl+Z (natív OS undo)
    → a host app undo history kezeli (Word, VS Code, stb.)
    → VibeVox NEM tart külön undo stacket
    → NEM implementálunk saját voice-based correction engine-t

UI feedback

ESC abort esetén:
  → Toast megjelenítés (1 másodperc auto-dismiss):
    \"❌ Diktálás megszakítva\"
  → Sentry breadcrumb loggolás (ha opt-in): 
    sentry_sdk.add_breadcrumb(category=\"dictation\", message=\"dictation_aborted\", level=\"info\")

Sugallt UX pozicionálás: ESC = \"vészkijárat\" — nem hibaállapot, hanem tudatos felhasználói kontroll.

Implementációs spec (workers.py)

# Az abort_flag session-szintű állapot — a WorkerThread példányhoz kötött
class DictationWorker(QThread):
    def __init__(self):
        self.abort_flag = False  # ← ESC lenyomáskor True

    def on_esc_pressed(self):
        \"\"\"Global ESC hotkey handler — csak aktív session közben aktív.\"\"\"
        if self.is_recording:
            self.abort_flag = True
            self.stop_recording()        # audio buffer drop
            self.clear_live_bubble()     # UI törlés
            self.sever_connection()      # WebSocket bontás
            self.show_toast(\"❌ Diktálás megszakítva\", duration_ms=1000)

    def on_hotkey_released(self):
        if self.abort_flag:
            self.abort_flag = False      # reset jövő sessionra
            return                       # ← inject skip
        self.inject_text(self.transcript)
ℹ️ NOTE

ESC vs. Toggle Mode: Toggle Mode-ban (ahol a gomb egyszeri nyomás indít/megállít) az ESC szemantikája azonos: a folyamatban lévő session leállítása szöveginjektálás nélkül. A hotkey_mode enum-tól független az abort logika.


2.7. Select & Capture Vocabulary Building — Globális Hotkey (GAP-C4)

⚡ IMPORTANT

Döntés (2026-04-18 · GAP-C4 elfogadva): A Select & Capture UX pattern a custom vocabulary feature Fázis 2 implementációjának kritikus belépési pontja. A Settings-alapú szótárfelvétel high-friction — ez az organikus, in-context capture módszer a power user retenciójának kulcsa. Forrás: strategic_ux_architecture_analysis.md — GAP-C4

Hotkey specifikáció

Billentyűkombináció: Ctrl+Shift+V
  Globális: működik minden alkalmazásban, miközben a VibeVox a tálcán fut
  Ütközés-ellenőrzés:
    ✅ Windows: nem ütközik rendszer shortcut-tal
    ✅ Linux (X11 + Wayland): nem ütközik xdg/Gnome/KDE alapszabályokkal
    ⚠️ VS Code: Ctrl+Shift+V = Markdown Preview megnyitása
               → Settings → VS Code-ban override lehetséges
               → Toast figyelmeztetés: ha VS Code ablak aktív, egyedi konfig ajánlott

Teljes add-flow

1. User diktál → STT \"Supabase\"-t \"super base\"-ként hozza vissza
2. User billentyűzettel javítja: [super base] → [Supabase]
3. User kijelöli a javított szót: [Supabase] (OS clipboard tartalom)
4. User megnyomja: Ctrl+Shift+V
5. VibeVox globális hotkey listener → clipboard olvas → term = \"Supabase\"
6. Toast jelenik meg (2 másodperc):
   \"✅ 'Supabase' hozzáadva az Egyéni Szótárhoz\"
7. Háttérben:
   a. SQLite INSERT INTO vocabulary (term, ...) VALUES (...)
   b. Supabase cloud sync (ha sync_mode = \"cloud\")
   c. Groq API rolling context: következő diktálásnál az LLM post-processing
      prompt tartalmazza az új szót (ha szótár aktív → LLM pipeline futtatódik)

Alternatív belépési pontok (B2B szótárcsomag import)

Tier 1 — Egyéni word-by-word (Fázis 2, alapfunkció):
  Select & Capture (Ctrl+Shift+V) ← jelen szekció

Tier 2 — Bulk import (Fázis 2, B2B):
  Settings → Vocabulary → Import
  Formátum: .csv (term, replacement)
  Newton .dic / .xml kompatibilis import wizard (Newton migration path)

Tier 3 — Iparági szótárcsomag (Fázis 2+):
  Admin-telepített szótárak (jogi, orvosi, tech) — B2B admin konzol
  Supabase-szinkronizált: admin egyszer veszi fel, minden user appjában megjelenik

Implementációs scope (vocabulary_manager.py + hotkey listener)

# vocabulary_manager.py — Select & Capture handler
def capture_selected_text_as_vocab_term(clipboard_text: str) -> bool:
    \"\"\"
    Global Ctrl+Shift+V handler.
    Beolvassa a kijelölt (clipboard) szöveget, és hozzáadja a szótárhoz.
    Returns True ha sikeres, False ha üres clipboard / duplikátum.
    \"\"\"
    term = clipboard_text.strip()
    
    if not term or len(term) > 100:  # limit: ne legyen egész mondat
        show_toast(\"⚠️ Érvénytelen kijelölés — egyetlen szót vagy kifejezést jelölj ki.\")
        return False
    
    if vocabulary_db.exists(term):
        show_toast(f\"ℹ️ '{term}' már szerepel a szótárban.\")
        return True
    
    vocabulary_db.insert(term)
    supabase_sync.push_vocab_update(term)  # aszinkron, nem blokkoló
    show_toast(f\"✅ '{term}' hozzáadva az Egyéni Szótárhoz\", duration_ms=2000)
    return True

# hotkey_controller.py / controller.py — globális listener regisztráció
keyboard.add_hotkey(\"ctrl+shift+v\", 
    lambda: capture_selected_text_as_vocab_term(pyperclip.paste()),
    suppress=False)
ℹ️ NOTE

B2B vonzat: Ez a feature a domain jargon failure (#2 churn trigger, riport szerint) közvetlen megoldása. A Select & Capture + cloud sync kombináció teszi lehetővé az irodai admin szótárkezelést: 10_Sales_B2B.md §B2B többletértékek. Az LLM post-processing pipeline (§2.1 Szint 2c) automatikusan felveszi a new term-eket a következő diktálásban.


Technológia stack

Komponens Technológia Verzió
Web framework FastAPI 0.110+
Runtime Python 3.11+
Infrastruktúra Google Cloud VPS US régió (transit only)
Auth JWT / Supabase token
Szervice manager systemd VibeVox-proxy.service

Package struktúra (v1.5.x után refaktorált)

vtj_proxy/
├── __init__.py
├── config.py          ← Env vars, Stripe keys, Supabase URL
├── db.py              ← SQLite operations, quota tracking
├── auth.py            ← JWT validation, Supabase auth
├── routes/
│   ├── transcribe.py  ← /transcribe endpoint (STT routing)
│   ├── billing.py     ← /webhook (Stripe events)
│   └── health.py      ← /health check
└── handlers/
    ├── stt_router.py           ← Provider-agnostik STT routing (plugin-style, sorrend cserélhető)
    ├── deepgram_handler.py     ← Deepgram Nova-3 WebSocket (PRIMARY — live streaming, managed cloud)
    ├── elevenlabs_handler.py   ← ElevenLabs Scribe v2 (másodlagos managed fallback — speaker diarization)
    ├── groq_handler.py         ← Groq Whisper large-v3 (BYOK alt. / batch fallback — nincs WebSocket)
    ├── openai_handler.py       ← OpenAI gpt-4o-transcribe (végső fallback)
    └── quota_handler.py        ← Free tier enforcement

STT Provider Chain — managed cloud prioritási sorrend

ℹ️ NOTE

A stt_router.py plugin-architektúrájú — új provider beillesztése egyetlen új handler fájlt igényel, a routing logika érintése nélkül. Ez a provider lock-in elleni stratégiai döntés.

Prioritás Provider Protokoll Trigger
1. PRIMARY Deepgram Nova-3 WebSocket streaming Default — minden managed cloud session
2. FALLBACK-A ElevenLabs Scribe v2 REST batch Deepgram 502/503 error vagy speaker diarization request
3. FALLBACK-B Groq Whisper large-v3 REST batch ElevenLabs hiba
4. LAST RESORT OpenAI gpt-4o-transcribe REST batch Groq hiba
B2B PREMIUM Azure MAI-Transcribe-1 REST / streaming BYOK konfigurációban — jogi/orvosi B2B szegmens
ℹ️ NOTE

Azure MAI-Transcribe-1 (B2B Premium — Fázis 2): Azure AI Foundry dedikált EU geo-fenced instance — 100% EU data residency törvényi elváráshoz (nem csak SCC-alapú megállapodás), jogi/orvosi B2B ügyfeleknek. ~2.8–3.2× drágább a Groq-nál, de BYOK-on a felhasználó viseli. Bekerül a BYOK provider listába Fázis 2-ben.

ℹ️ NOTE

ElevenLabs Scribe v2: A Deepgram elsődleges managed fallbackje — kiváló speaker diarization képességei miatt különösen értékes a B2B interjú/meeting transzkripció use case-ekben (Fázis 2+ feature). REST-alapú (nem WebSocket), ezért fallback esetén az UX UI jelzi: „Backup mode — slight delay expected".

API endpoints

Endpoint Metódus Leírás Auth
/transcribe POST STT requests routing JWT
/webhook POST Stripe webhook events Stripe signature
/health GET Service health check
/usage GET User quota status JWT

Quota enforcement logika

FREE_TIER_MONTHLY_MINUTES = 180
SESSION_MAX_MINUTES = 6

# Ellenőrzési pontok:
# 1. Session indításakor: van-e kvóta?
# 2. Session alatt: 6 perces cap betartása
# 3. Hónap váltásakor: kvóta reset

VPS architektúra megjegyzések

ℹ️ NOTE

A jelenlegi VPS US régióban van, de ez GDPR-szempontból nem probléma — a proxy nem tárol hangfelvételt, csak továbbít (transit). B2B marketing erősítés érdekében EU-ba helyezés mérlegelendő (Fázis 2).


4. Adatbázis és szinkronizáció

Helyi adatbázis (SQLite)

-- Főbb táblák:
transcription_history(
    id, user_id, text, word_count, duration_sec,
    created_at, synced_at, app_context
)

vocabulary(
    id, user_id, term, replacement, language,
    created_at, synced_at
)

usage_stats(
    id, user_id, month, minutes_used, words_total,
    sessions_count, last_updated
)

Supabase cloud szinkronizáció

Adatközpont: Supabase Zürich (eu-central-2) — szöveges adatok EU-ban maradnak
Technológia: PostgreSQL (Supabase managed)
Auth: Supabase Auth (JWT + Row Level Security)
Ár szintek: Free ($0) → Pro ($25/hó) — ~100K user-ig free tier elegendő
# sync.py — szinkronizáció logika (v1.5.x)
# Ismert bug: db_insert() egyenként triggereli a pruning logikát
# Megoldás: bulk insert pruning nélkül (Fázis 1 blokkolt)
async def sync_history_to_cloud():
    local_records = get_unsynced_records()
    # TODO: bulk insert helyett jelenleg egyenkénti insert
    for record in local_records:
        await supabase.insert(record)  # ← pruning trigger bug
⚠️ WARNING

Ismert architektúra-hiba: A Supabase sync db_insert()-tel illeszti be a remote rekordokat — ez egyenként triggereli a helyi pruning logikát. Megoldás: bulk insert pruning nélkül (sync.py refactor, Fázis 1 blokkolt).

ℹ️ NOTE

Free tier ping: A Supabase free tier 1 hét inaktivitás után szünetel. Cron ping (pl. Uptime Robot) szükséges amíg Pro-szintű bevétel nincs.

Szinkronizáció stratégia

Konfliktus kezelés: "Last write wins" — szerver elsőbbsége
Offline mód: teljes funkcionalitás SQLite-ból
Szinkron trigger: app elindításkor + minden 15 percben

4.1. Supabase Realtime Platform Limitek

🚨 CAUTION

Runaway reconnection loop (pl. Android Doze Mode felébredés exponential backoff nélkül) a teljes real-time projektet felfüggesztheti — ez az ÖSSZES felhasználó szinkronizációját leállítja (RealtimeDisabledForTenant)!

Tier Concurrent Connections Messages/sec Channel Joins/sec
Free 200 100 100
Pro ($25/hó) 500 500 500
Enterprise 10 000+ 2 500+ 2 500+
Android-specifikus implikációk:
  NEM használunk persistent WebSocket-et Android kliensen
  FCM push-to-wake → WorkManager → ephemeral fetch → close
  Kötelező exponential backoff MINDEN reconnection kísérletben
  Default: min 5mp → max 5 perc backoff (jitter-rel)
  Monitoring: Supabase dashboard „Realtime Connections" metrika

4.2. Doze Mode hatása a szinkronizációra

Doze Mode aktiválási feltétel:
  Eszköz áramforrás nélkül + mozdulatlan + képernyő kikapcsolva

Desktop kliens (Windows/Linux):
  Nincs Doze Mode → persistent WebSocket stabil
  Sleep/hibernate → reconnect ébredéskor (exponential backoff!)

Android kliens:
  Doze Mode aktív → hálózati hozzáférés felfüggesztve
  WS heartbeat pinger OS által szüneteltetve → heartbeat kimarad
  Szerver timeout → kapcsolat csendben bontva (nincs explicit error!)
  Agresszív retry loop (backoff nélkül) → Supabase Realtime limit

  EZÉRT: NEM használunk persistent WS-t Androidon
  FCM high-priority data messages ÁT tudnak jutni Doze-on
  → push-to-wake → WorkManager → ephemeral fetch → close

5. Fizetési infrastruktúra

Payment stack (döntött)

Stripe (payment gateway) + Taxually (EU ÁFA compliance)

Stripe — Fázis 1 (launch blockerek):
  • Kártya (Visa/Mastercard) — Fázis 1
  • Natív BLIK (Lengyelország) — Fázis 1
      └─ ⚠️ KÖTELEZŐ VALIDÁCIÓ: BLIK Model A (recurring billing)
         A Model A lehetővé teszi az automatikus havi ismétlődő
         terhelést az első engedélyezés után — manual re-auth nélkül.
         Ha a Stripe BLIK NEM támogatja a Model A recurring-et,
         alternatív MoR szükséges (PayU vagy Przelewy24).
         Manual re-auth minden hónapban = elfogadhatatlan UX = magas
         involuntary churn a lengyel piacon.
  • GoPay (Csehország) — Fázis 1 (CZ launch blocker)
      └─ Indoklás: 14,6M debit vs. 1,2M credit kártya CZ-ben.
         GoPay nélkül a checkout „idegen és megbízhatatlan" — közvetlen
         versenyhátrányt okoz a natív cseh Beey-vel szemben.

Stripe — Fázis 2:
  • Barion / SimplePay (Magyarország)
  • TatraPay (Szlovákia)
  • qvik (Magyarország — figyelendő)
      └─ MNB által 2024 őszén indított azonnali QR/deep-link fizetés.
         1M+ tranzakció az első hónapokban; ingyenes felhasználóknak.
         Integráció akkor, ha a Stripe vagy a választott MoR támogatja.

Taxually:
  • €340/hó fix — automatikus EU ÁFA bevallás minden CEE piacra
  • Már szerződött

Stripe integráció architektúra

Kliens → Stripe Checkout →  Stripe Webhook (vtj_proxy/routes/billing.py)
                                    │
                    ┌───────────────┴──────────────┐
                    ▼                              ▼
           subscription_created           subscription_cancelled
           → Supabase: role = "pro"       → Supabase: role = "free"
           → Email: welcome drip          → Stripe: cancel_at_period_end

Pricing tier → Stripe product mapping

Tier Stripe product Billing Megjegyzés
Pro havi prod_pro_monthly Recurring/month cancel_at_period_end
Pro éves prod_pro_yearly Recurring/year cancel_at_period_end
BYOK havi prod_byok_monthly Recurring/month
BYOK LTD prod_byok_ltd One-time nincs recurr.

ÁFA kezelés

Taxually: automatikusan minden EU tagállamban
  HU: 27% | PL: 23% | CZ: 21% | SK: 23% | AT/DE: 19-20%
  B2B invoicing: reverse charge (nem kell ÁFA)

6. Platform-specifikus architektúrák

Windows

Technológia: Python + PySide6
Entry point: main.py
System tray: SystemTray + QMenu
Hotkey: pynput.keyboard listener (global hotkey)
Audio: pyaudio / sounddevice (WASAPI)
Installer: PyInstaller → EXE + WiX (MSI tervezett)

Floating bubble:
  QWidget (frameless, always-on-top, semi-transparent)
  Animation: QPropertyAnimation
  Known issue: animation timer init (v1.5.3 fixed)

Linux

Technológia: Python + PySide6
Display: X11 + Wayland (XWayland fallback v1.5.x)
Audio: PipeWire (elsődleges, Fedora 34+ / Ubuntu 22.10+) / PulseAudio (legacy)
System tray: AppIndicator / StatusNotifierItem
Packages: AppImage (kész) | Flatpak (Fázis 1) | .deb/.rpm/AUR

Autostart (Fázis 1):
  1. XDG Autostart: ~/.config/autostart/voicetypingbyjoe.desktop
  2. SystemD user service: ~/.config/systemd/user/VibeVox.service (opcionális)
  3. Flatpak: a .desktop fájl automatikusan kerül a megfelelő helyre

Wayland native (Fázis 2 — előrehozva Fázis 3-ból):
  XDG Desktop Portal (mikrofon hozzáférés)
  wtype (Sway/Hyprland input injection) -> ydotool (GNOME/KDE Wayland fallback)
  layer-shell protocol (system tray)
  Indoklás: Fedora 40+ és Ubuntu 24.04+ alapértelmezetten Wayland —
  2026 végére a CEE Linux userek >50%-a Wayland-en lesz.

6.1. Linux Audio Stack Detection (K2 — Fázis 1, P0)

⚡ IMPORTANT

2026-ra a CEE Linux userek >70%-a PipeWire-en fut (Fedora 34+, Ubuntu 22.10+). A VibeVox-nek auto-detektálnia kell az audio backendet — különben a Fedora/Ubuntu userek "nem működik a mikrofon" hibát kapnak az első indításnál → azonnali uninstall.

Detektálási lánc:

# workers.py / audio_setup.py — Linux audio backend detection
import subprocess

def detect_audio_backend():
    """4 szintű audio backend detektálás."""
    try:
        result = subprocess.run(
            ['pactl', 'info'],
            capture_output=True, text=True, timeout=2
        )
        if 'PipeWire' in result.stdout:
            return 'pipewire'        # Szint 1: PipeWire natív
        else:
            return 'pulseaudio'      # Szint 2: pipewire-pulse / PulseAudio
    except FileNotFoundError:
        # pactl nicht vorhanden
        try:
            subprocess.run(['aplay', '-l'], capture_output=True, timeout=2)
            return 'alsa'            # Szint 3: ALSA fallback
        except Exception:
            return 'unknown'         # Szint 4: ismeretlen -> hibaüzenet

PipeWire-specifikus hibaüzenetek (onboarding UI):

Hibaüzenet Felhasználói megjelenítés Megoldás gomb
ALSA: Unable to open slave "PipeWire audio service nincs elindítva" systemctl --user restart pipewire pipewire-pulse
Device or resource busy "Más alkalmazás foglalja a mikrofont" Eszközválasztó dropdown
pipewire-alsa hiány "PipeWire-ALSA bridge hiányzik" Telepítési útmutató link

Sandboxed Flatpak audio (PipeWire-kompatibilis manifest):

# com.voicetypingbyjoe.VoiceTypingByJoe.yaml
finish-args:
  - --socket=pulseaudio    # pipewire-pulse compatibility layer
  # Alternatíva Fázis 2-ben (natív PipeWire Flatpak portal):
  # - --socket=pipewire
  - --socket=x11
  - --socket=wayland
  - --share=network
  - --talk-name=org.freedesktop.secrets

6.2. Tiling WM Kompatibilitás (F1 — Fázis 2)

A CEE dev közösség ~15-25%-a tiling WM-et használ (i3, Sway, Hyprland, River). Ezek a véleményformáló "megmondóemberek" — ha ők ajánlják, a GNOME/KDE userek is kipróbálják.

Tesztelési mátrix:

WM Display szerver System tray Hotkey Státusz
i3 X11 AppIndicator (i3bar plugin) pynput global hotkey 🟡 Tesztelendő
Sway Wayland (natív) StatusNotifierItem pynput + XWayland 🟡 Tesztelendő Fázis 1
Hyprland Wayland (natív) waybar widget pynput + XWayland 🟡 Tesztelendő Fázis 1
River Wayland (natív) yambar / sfwbar pynput + XWayland 🔴 Tesztelendő Fázis 2

System tray fallback tiling WM-eken:

  • Ha nincs rendszertálca → floating window mód (minimális, always-on-top gyorsbillentyű ablak)
  • Fázis 2: Waybar widget (waybar-VibeVox) — StatusNotifierItem interfészen cross-WM megoldás

BYOK keyring fallback tiling WM-eken (lásd 7.2. szekció):

  • DE (GNOME/KDE) → libsecret
  • Tiling WM (i3/Sway/Hyprland) → pass (ajánlott) → encrypted config (fallback)

6.3. Wayland Natív Input Injection Specifikáció (F7 — Fázis 2)

PROBLÉMA: X11-en az xdotool type/SendKeys megbízhatóan működik.
          Wayland-en a biztonsági modell blokkolja a globális input injection-t.

VibeVox MEGOLDÁS (Fázis 2):

  Elsődleges: wtype (Sway, Hyprland, wlroots-based WM-ek)
    wtype -s 50 "szöveg"  <- 50ms delay karakter közt (megbízható)
    Installáció: nixpkgs, AUR, linuxbrew
    Teszt: wtype "Hello" -> aktív Wayland ablakba írja

  Fallback: ydotool (GNOME/KDE Wayland)
    ydotool type --delay 50 "szöveg"
    Szükséges: ydotoold daemon futása (systemd user service)
    Kompatibilis: GNOME Wayland, KDE Plasma Wayland

  Végső fallback: clipboard mód (jelenlegi MVP megoldás)
    pyperclip.copy(text) + xdotool key ctrl+v
    Hátránya: clipboard "pollution" (más clipboard tartalom felülírás)
    Megoldás: clipboard tartalom visszaállítása paste után

Implementáció (workers.py + platform_utils.py):
  1. $XDG_SESSION_TYPE == wayland detektálás
  2. which wtype -> wtype elsődleges
  3. which ydotool -> ydotool fallback  
  4. egyéb -> clipboard mód Toast-tal

6.4. Windows Disztribúció — Velopack Auto-Update Architektúra

Forrás: velopack_deployment_analysis.md (2026-04-17) | Státusz: ✅ Velopack kész (2026-04-11), kiegészítő intézkedések integrálva

Velopack framework:
  Runtime: Rust-alapú bootloader — delta patch (Zstandard algo > bsdiff)
  Telepítés: %LocalAppData%\{packId}\ — adminisztrátori jog nélkül
  Update: per-user silent background → UAC prompt nulla
  Delta merit: kis változásnál 30 KB – 5 MB patch (teljes ~80 MB helyett)

CI/CD pipeline:
  GitHub Actions → Velopack build → delta .nupkg generálás
  GitHub Releases CDN → bináris hosting (nem számít REST API limitbe)
  GitHub Pages → releases.stable.json manifest (SimpleWebSource)

🔴 KRITIKUS — Launch Blocker Követelmények

P0-V1: multiprocessing.freeze_support() kötelező hívás

# app/main.py — LEGELSŐ SOROK (Velopack init után, minden más import előtt!)
import velopack
velopack.App().run()

import multiprocessing
multiprocessing.freeze_support()
# EZUTÁN jön a PySide6 és minden egyéb import

Ha ez hiányzik: PyInstaller --onefile módban végtelen process-spawning loop → worker proceszek nyitott file handle-t tartanak a current könyvtáron → Velopack directory swap MEGSZAKAD → silent update failure → churn!

P0-V2: PyInstaller --onedir mód kötelező

  • --onefile módban a Velopack delta update hatástalan (teljes 80 MB bináris csere)
  • --onedir mód → fájlszintű delta diff → 30 KB – 5 MB update CEE mobil hálózaton

P0-V3: Perzisztens adatok szegregációja

✅ HELYES ÚTVONALAK:
  %AppData%\VibeVox\          → SQLite DB, settings.json, API kulcsok
  %LocalAppData%\VibeVox\data\ → cache fájlok

❌ TILOS:
  %LocalAppData%\{packId}\current\ → Velopack frissítéskor TELJES TÖRLÉS!

Ha SQLite fájl a current könyvtárban van → minden frissítés után adatvesztés


🟠 P1 — Code Signing és Manifest Hosting

Azure Artifact Signing (~$9,99/hó = ~$120/év)

Miért NEM EV tanúsítvány ($300–559/év)?
  2023 óta EV sem ad azonnali SmartScreen bypass-t
  Azure Trusted Signing → ugyanolyan reputáció-képzési folyamat, 3–4× olcsóbban
  CI/CD integráció: GitHub Actions natív, HSM USB token NEM szükséges

Kockázat: Azure CA rotáció (2026-március: reputáció nullázódott — MEGTÖRTÉNT!)
  → Monitoring: CA rotáció eseményre azonnali user kommunikáció szükséges

GitHub Pages Update Manifest Hosting (GitHub API rate limit bypass)

Probléma: GitHubSource (autentikáció nélkül) = 60 kérés/óra limit
  B2B NAT mögötti szervezetnél több user = egy IP = megosztott limit
  Kimeríthető limit → CheckForUpdatesAsync() 403 → silent update failure

Megoldás — Hybrid Bypass Architecture:
  releases.stable.json → GitHub Pages (CDN, korlátlan)
  .nupkg asset URL-ek → GitHub Releases CDN (nem REST API)
  UpdateManager konfig → SimpleWebSource (NEM GitHubSource)

🟠 P1 — Update UX (IsDictationActive védelem)

# Global state — workers.py / controller.py
is_dictation_active: bool = False

# Update thread — NEM szakítja meg az aktív session-t
def apply_update_if_ready():
    if is_dictation_active:
        return  # Diktálás aktív → halasztás

    # Passive notification: tálca badge + "Frissítés elérhető" menüpont
    # Legjobb UX: "Update on Exit" — bootloader next startup alkalmaz
    # → NEM kell explicit restart logika — zero kód, maximum UX

Miért kritikus: Aktív diktálás közbeni ApplyUpdatesAndRestart() hívás = audio stream azonnali megszakítás = #1 churn trigger audio dictation appokban


🟡 P2 — Rollback Watchdog (Fázis 2, B2B Sales Enabler)

# startup_metrics.json — crash counter watchdog
{
  "consecutive_crashes": 0,
  "last_successful_version": "1.2.3",
  "stability_threshold_seconds": 30
}

# Induláskor: consecutive_crashes += 1
# 30 másodperccel később (stabilitás): consecutive_crashes = 0
# Ha consecutive_crashes >= 2:
#   → Velopack n-1 csomag visszatöltés
#   → User notification: "Az előző biztonságos verzióra visszaállítottunk"

B2B értékajánlat: Jogi irodai deployment-nél egy törött frissítés saját IT kapacitás nélkül kezelhető automatikusan. „Silent rollback — zero IT jegy szükséges."


Android (Fázis 4)

Architektúra: InputMethodService (Custom IME)
  MIÉRT CUSTOM IME:
    Android 16: AAPM (Advanced Protection Mode) bevezetése
    → AccessibilityService blokkolás ha nem valódi disability tool
    → isAccessibilityTool="true" hamis használata → Play Store ban
    Android 17: side-loaded appoknak sincs accessibility toggle
    → "Restricted by Advanced Protection" warning
    Custom IME előnyei:
    → InputConnection.commitText() → natív text injection jog
    → Nem kell accessibility jogosultság
    → Play Store policy-compliant
    → Privacy USP: "Nem accessibility exploitation — natív billentyűzet"
  Paste megoldás: InputConnection.commitText()

Audio: MediaRecorder → WAV → Groq API (cloud-only)
  Offline Whisper: NEM implementáljuk (large-v3 = 8GB RAM)

Szinkronizáció: FCM push-to-wake + WorkManager
  MIÉRT NEM persistent WebSocket: FGS 6h quota Android 12+

FGS Enforcement (Android 15+):
  dataSync + mediaProcessing típusok: max 6 óra / 24h window
  Megosztott kvóta: összes dataSync FGS kumulatívan számít
  Timeout: Service.onTimeout() → stopSelf() → kötelező pár mp-en belül
  Crash: ha nem hív stopSelf() → RemoteServiceException (fatal!)
  Re-init ban: ForegroundServiceStartNotAllowedException (kimerült kvóta)
  Reset: CSAK ha user explicit előtérbe hozza az Activity-t
  BOOT_COMPLETED: NEM indíthat microphone/dataSync FGS-t!

Microphone WIU (While-In-Use) korlátok:
  Android 16/17: background audio hardening
  WIU státusz CSAK ha app vizuálisan aktív volt az indításkor
  Ha háttérből indul: AUDIOFOCUS_REQUEST_FAILED / process freeze
  → Custom IME természetesen megoldja (IME vizuálisan aktív)

Wireless mic mód:
  Android app = hangfelvevő mikrofon
  PC app = paste cél
  Protokoll: FCM + WebSocket (session alatt)

MIÉRT WIRELESS MIC MÓD (nem clipboard sync):
  Android 10+ elvette a háttér clipboard olvasási jogot
  Android 12+ kötelező toast minden clipboard hozzáférésnél
  KDE Connect: csak LAN (cellular → nem működik, out-of-office halott)
  Phone Link: csak Windows (Linux usereknek használhatatlan)
  → A VibeVox saját cross-device protokollt épít:
    Android rögzít → Groq EU → szöveg → Supabase → desktop WS
    Desktop-ról: Supabase → FCM push → WorkManager → Android local DB
  Előny: ISP-agnosztikus, LAN nem szükséges, WAN-on is működik

6.5. Integrációs célpontok — CEE B2B szoftverek

⚡ IMPORTANT

B2B Sales Prerequisite: Ez a szekció dokumentálja, hogy a VibeVox OS-level keyboard injection konkrétan melyik CEE jogi és orvosi szoftverrel kompatibilis. Nélküle nem hihető a B2B pitch. Tesztelés státusza szoftvercímenként jelzett.

Jogi szektor

Szoftver Piac Architektúra VibeVox injection módszer Tesztelési státusz
Kleos (Wolters Kluwer) PL, CZ, SK, HU Web SaaS (Azure) Browser text field — standard keyboard sim 🟡 Elméletileg rendben
Praetor (Wolters Kluwer) CZ, SK, HU Natív .NET thick client Windows SendKeys / xdotool — DevExpress form 🔴 Tesztelés szükséges
Evolio CZ, SK Web + MS Word Browser + Word interop 🟡 Elméletileg rendben
SingleCase CZ, SK Web SaaS Browser text field 🟡 Elméletileg rendben
Jogtár (Wolters Kluwer) HU Web + Word plug-in Browser + Word interop 🟡 Elméletileg rendben
Amberlo PL, CZ, SK, HU Web SaaS + Mobile Browser text field 🟡 Elméletileg rendben
LEX / Legalis PL Web database Browser search/analysis field 🟡 Elméletileg rendben

Orvosi szektor

Szoftver Piac Architektúra VibeVox injection módszer Tesztelési státusz
mMedica (Asseco) PL Hibrid (Desktop + Cloud) Windows native text field — ICD-10 form 🔴 Tesztelés szükséges
ZnanyLekarz (Docplanner) PL Web SaaS Browser EDM modul 🟡 Elméletileg rendben
Medicus (CGM) CZ, SK Hibrid (Desktop + Cloud) Windows native / browser field 🔴 Tesztelés szükséges
PC DENT CZ Natív Windows (64-bit) Windows form — clipboard blokkolás RISK 🔴 KOCKÁZATOS — tesztelés szükséges
netDoktor HU Web SaaS Browser — EESZT reporting modul 🟡 Elméletileg rendben
Cloudent HU Web SaaS Browser patient card + NAV invoicing 🟡 Elméletileg rendben
⚠️ WARNING

PC DENT és Praetor: Egyes natív Windows alkalmazások aktívan blokkolhatják a clipboard-ot és a harmadik fél virtual keyboard eszközöket. A VibeVox OS-level keyboard simulation ezt megkerüli (nem clipboard-ot használ), de tényleges környezetben tesztelés szükséges Fázis 1 előtt B2B sales claim-hez.

VDI/Citrix injection mechanizmus

PROBLÉMA: Más cloud diktáló eszközök audio routinggal próbálják megoldani:
  Lokális mikrofon → VDI session → cloud STT → VDI szövegrouting
  Ez 3 lépés, magas latencia, karakter-kiesés, audio codec probléma.

VibeVox MEGOLDÁS (OS-level):
  1. Lokális OS elfogja a hangot (helyi mikrofon)
  2. Hang → EU Frankfurt szerver (Groq Whisper)
  3. Szöveg → xdotool/SendKeys → VDI ablakba ínjektál
  
  A VDI session számára ez egyszerű billentyűzet Input — nem tud
  különbséget tenni a VibeVox és a kézi gépelés között.

KOMPATIBILIS VDI MEGOLDÁSOK (tesztelés szükséges):
  • Citrix Virtual Apps and Desktops
  • VMware Horizon
  • Microsoft AVD (Azure Virtual Desktop)
  • RDP (Remote Desktop Protocol)

Tesztelési prioritások (Fázis 1 előtt kötelező)

Prioritás Szoftver Piac Befektetett idő
🔴 P0 Praetor CZ, SK, HU 2-3 óra trial verzióval
🔴 P0 mMedica PL 2-3 óra (van ingyenes demo)
🟡 P1 Medicus CZ, SK 2 óra
🟡 P1 PC DENT CZ 2 óra — clipboard blokk kockázat
🟢 P2 Kleos, netDoktor, Cloudent HU/PL Web-alapú, alacsony kockázat

7. Biztonsági architektúra

Adatbiztonság rétegek

Réteg Megoldás
Átvitel HTTPS / TLS 1.3 (minden API hívás)
Auth Supabase Auth JWT (RS256)
Row-level security Supabase RLS (minden tábla)
API kulcs tárolás OS keychain / encrypted local store
Crashlog Sentry (send_default_pii=False, opt-in)

BYOK API kulcs kezelés — 4 szintű Keyring Fallback (K4)

# API kulcs tárolás — 4 szintű platform-specifikus fallback lánc:
#
# Windows:  Windows Credential Manager (mindig elérhető)
#
# Linux:
#   Szint 1: libsecret (GNOME Keyring / KWallet)
#            - Detektálás: python-secretstorage csomag + dbus service
#            - GNOME, KDE, Cinnamon, XFCE (ha gnome-keyring fut)
#
#   Szint 2: pass (GNU Password Manager, GPG-titkosítva)
#            - Detektálás: shutil.which('pass')
#            - Ha elérhető: ajánlott opció tiling WM-en (i3/Sway/Hyprland)
#            - Miért: a CEE dev közösség ~20-25%-a tiling WM-et használ
#              Ők a véleményformálók — pass támogatás = trust signal
#            - Implementáció: pass insert VibeVox/api-key "sk-..."
#
#   Szint 3: Encrypted config fájl
#            - Path: ~/.config/VibeVox/keys.enc (AES-256, user-jelszóval)
#            - Opt-in figyelmeztetés: "Keyring daemon nem elérhető"
#            - Setup wizardban: jelszó megadás + megerősítés
#
#   Szint 4: Plaintext -> SOHA nem default
#            - Csak explicit "I understand the risk" checkbox + WARNING után
#            - Alkalmazásnaplóban megjelenik: SECURITY_DEGRADED event
#
# SOHA: plaintext config fájlban felhasználói beleegyezés nélkül
#
# Validáció (minden szinten egyforma):
#   Minden BYOK session elején: test connection
#   Hiba esetén: user értesítés + graceful fallback

Tiling WM onboarding üzenet (pass elérhetősége esetén):

"Tiling window manager felismerve (KeyringUnlockError)"
Javasolt kulcs tárolási mód: pass (GPG-titkosított)
[Beállítás most >]  [Titkosított fájl >]  [Részletek]

Auth flow (Managed Cloud)

1. User regisztrál/bejelentkezik → Supabase Auth
2. Supabase visszaad JWT token-t
3. Kliens minden API híváshoz Bearer token-t küld
4. Proxy validálja a token-t → quota check → STT routing
5. Stripe subscription state tükröződik a Supabase role-ban

8. Ismert technikai adósságok

Problem Súlyosság Státusz Megoldás
Supabase sync bulk insert 🔴 Magas Fázis 1 blokkolt sync.py refactor
Wayland natív (X11 fallback) 🟡→🔴 Emelkedő Fázis 2 (előrehozva) XDG Portal + wtype migráció
Windows floating bubble init 🟡 Közepes v1.5.3 fixed Lezárva
Supabase free tier ping 🟢 Alacsony Workaround: Uptime Robot Pro tier bevételig
VPS US régió (GDPR marketing) 🟢 Alacsony Nem blokker EU régió mérlegelés Fázis 2
Supabase dashboard konfiguráció 🔴 Magas ❌ Szinkronizáció NEM live Dashboard-on engedélyezni: RLS policy, realtime channel, user table — Fázis 1 launch prerequisite


9. Email Infrastruktúra [Email Infrastructure Analysis - #1, #2, #4 beépítve]

Platform döntés: Loops.so - natív Stripe webhook sync (Zapier nélkül), vizuális branching drip builder, $/hó <1K kontaktig.

9.1. Backend API integráció spec

A backend-nek (proxy_server/ vagy dedikált email_service.py) a következő két Loops.so hívást kell implementálnia:

Contact létrehozás (regisztráció / Stripe webhook)

`python

POST https://app.loops.so/api/v1/contacts/create

Trigger: új regisztrációnál VAGY Stripe checkout.session.completed webhook

payload = { "email": user_email, "userId": supabase_user_id, "userGroup": "free", # "free" | "pro_monthly" | "pro_annual" | "b2b" "source": "stripe_checkout", # "registration" | "stripe_checkout" | "waitlist" "mailingLists": { "cm_onboarding": True, # Onboarding drip (30 napos szekvencia) } } `

Lifecycle esemény küldés

`python

POST https://app.loops.so/api/v1/events/send

--- Silent Churn detektálás (14 nap inaktivitás) ---

payload_churn = { "email": user_email, "eventName": "silent_churn_detected", "eventProperties": { "days_inactive": 14, "last_session_words": last_word_count, "plan": current_plan, } }

--- Havi digest (minden hónap 1-én, cron job) ---

payload_digest = { "email": user_email, "eventName": "monthly_digest", "eventProperties": { "total_words_month": monthly_word_count, "total_minutes_saved": monthly_minutes_saved, "streak_days": streak, } } `

9.2. Lifecycle esemény taxonómia

Esemény neve Trigger Kiváltó logika helye Loops flow
contact_created Regisztráció / Stripe checkout auth_handler.py / Stripe webhook Onboarding drip indítás
first_dictation Első sikeres STT session workers.py -> session_complete Day 3 email
onboarding_completed Onboarding wizard 3. lépés befejezve onboarding.py → wizard_step_3_complete TTFD mérés: timestamp Supabase-be → Time-to-First-Dictation KPI
silent_churn_detected 14 nap 0 session Napi cron job (VPS) Re-engagement szekvencia
monthly_digest Hónap 1. napja Havi cron job (VPS) Havi összefoglaló
upgrade_to_pro Stripe webhook stripe_webhook_handler.py Pro welcome
subscription_cancelled Stripe webhook stripe_webhook_handler.py Win-back D1/D14/D45
nps_survey_trigger 30/60/90 nap anniversary Napi cron job NPS email

9.3. Implementációs prioritás

Fázis Feladat Prioritás
Fázis 0 (Launch ELOTT) DNS beállítás (SPF, DKIM, DMARC) P0 BLOCKER
Fázis 0 (Launch ELOTT) Domain warmup terv aktiválása P0 BLOCKER
Fázis 0 (Launch ELOTT) contact_created + upgrade_to_pro API hívások backend-ben P0 BLOCKER
Fázis 1 silent_churn_detected cron job P1
Fázis 1 monthly_digest cron job P1
Fázis 2 nps_survey_trigger cron job P2

A Loops.so API kulcs a .env fájlban LOOPS_API_KEY változóként tárolódik. Soha nem kerülhet a kliensoldali kódba (desktop app). Kizárólag a backend proxy hívja.

9.4. SHA-256 Release Hash Generálás — CI/CD spec (GAP-4)

ℹ️ NOTE

A SHA-256 hash a letöltési oldalon erős trust signalt küld a privacy-tudatos, technikai CEE szegmensnek. CI/CD pipeline-ba integrálva automatizálható — minimális implementációs coston maximal trust gain.

# Minden release előtt futtatandó a build pipeline-ban (PyInstaller után):
sha256sum vibevox-*.exe vibevox-*.AppImage > SHA256SUMS.txt

# GitHub Actions workflow (javasolt):
# jobs.release.steps:
#   - name: Generate SHA256
#     run: sha256sum vibevox-${{ env.VERSION }}-win64.exe vibevox-${{ env.VERSION }}.AppImage > SHA256SUMS.txt
#   - name: Upload to GitHub Release
#     uses: actions/upload-release-asset@v1
#     with: asset_path: ./SHA256SUMS.txt

Megjelenítés a download interstitial-on (/download/[os]/success):

vibevox-1.5.x-win64.exe    SHA-256: [auto-generated hash]
vibevox-1.5.x.AppImage     SHA-256: [auto-generated hash]

Implementációs cost: ~2 óra (CI script + UI elem) | Roadmap: P2 — D+7-ig Kapcsolódó: 08_Product.md §SHA-256 Hash Követelmény · 14_Launch_Playbook.md §2.3a


§E2E Encryption Architecture — Zero-Knowledge Cloud Sync

Implementálva: 2026-04-18 (app/encryption.py v2 — Key Wrapping architektúra) Kompetitív moat: Wispr Flow és Typeless NEM kínál semmilyen E2E sync titkosítást. Garancia: Szerver (Supabase) SOHA nem látja a plaintext adatot. Jelszó visszaállítás: LEHETETLEN.


Architekturális döntés #1 — Sync = E2E (azonos toggle)

⚡ IMPORTANT

Döntés (2026-04-18): A cloud sync és az E2E titkosítás ugyanaz a feature — nem két külön beállítás. Nincs "titkosítatlan cloud sync" mód.

Miért?

Az eredeti "Deferred Opt-In" modell (alapból titkosítatlan szinkron, E2E opt-in) elfogadhatatlan:

  • Amíg a user nem kapcsolja be az E2E-t, a marketing claim „soha nem látjuk az adataidat" nem igaz
  • Átmeneti "unencrypted sync" állapot = jogszabályi és reputációs kockázat
  • A user nem érti, miért kap "titkosítás kikapcsolva" warningot egy szinkronált szoftverben

A helyes modell:

Alapállapot (cloud sync kikapcsolva):
  ├── Adatok: CSAK lokálisan (SQLite)
  ├── Supabase: üres — semmi sem megy fel SOHA
  └── Marketing claim: ✅ mindig igaz ("soha nem látjuk az adataidat"
                           — mert nincs mit látni a szerveren)

Cloud sync bekapcsolva (= E2E bekapcsolva):
  ├── Első bekapcsoláskor: jelszóbekérés + DEK generálás + Supabase push
  ├── Ezután: minden adat titkosítva megy fel — szerver csak ciphertext-et lát
  └── Marketing claim: ✅ mindig igaz — szerver soha nem látja a plaintextet

Friction elemzés:

Felhasználói csoport Friction? Megjegyzés
Cloud syncet nem akar 0 Sosem találkozik jelszómegadással
Cloud syncet bekapcsol Alacsony — egyetlen jelszóbeállítás Tudatos döntés, elfogadják a tradeoff-ot
Második eszközön nyit Egyetlen jelszóbekérés startup-on Azonos a jelszókezelők UX-éhez

Architekturális döntés #2 — Kétszintes kulcs-architektúra (KEK + DEK)

⚡ IMPORTANT

Döntés (2026-04-18): Kétszintes Key Wrapping (1Password / Bitwarden modell). Ez az egyetlen elfogadható megoldás a jelszóváltoztatás skálázhatóságára.

A probléma az egyszintes modellel:

Naiv modell: password → PBKDF2 → key → MINDEN EGYES adatsor titkosítva ezzel
  Jelszóváltoztatáskor → minden sort újra kell titkosítani
  3 éves felhasználó, 50 000 sor → percekig tart, megszakadhat, adatvesztés kockázata

A kétszintes megoldás:

KEK (Key Encryption Key):
  password → PBKDF2-HMAC-SHA256(salt, 600k iter) → KEK  [32 byte, RAM-ban]
  Felhasználás: CSAK a DEK titkosítására/visszafejtésére

DEK (Data Encryption Key):
  os.urandom(32) — generálva EGYSZER, első cloud sync setupkor, SOHA nem változik
  Felhasználás: MINDEN history/vocabulary sor titkosítása
  Tárolás: AES-256-GCM(DEK, key=KEK) → Supabase user_encryption_metadata.wrapped_dek

Jelszóváltoztatás (O(1) — eszközszámtól és adatmennyiségtől FÜGGETLEN):
  1. old_KEK → unwrap(wrapped_dek) → DEK
  2. new_KEK = PBKDF2(new_password, SAME salt)
  3. new_wrapped_dek = AES-GCM(DEK, new_KEK)
  4. Supabase: user_encryption_metadata ← 1 sor írás (wrapped_dek frissítve)
     History / vocabulary sorok: ÉRINTETLEN ✅

Skálázhatóság:

Jelszóváltoztatás Naiv modell KEK+DEK modell
5 history sor ~1 mp ~100ms
500 history sor ~30 mp ~100ms
50 000 history sor ~50 perc ❌ ~100ms ✅
Hálózatkimaradás közben Adatvesztés kockázata ❌ Atomi művelet ✅

Kriptográfiai algoritmusok

Komponens Algoritmus Paraméter Indok
KEK levezetés PBKDF2-HMAC-SHA256 600 000 iteráció (NIST SP 800-132, 2023) Brute-force ellenállás ~600× nyers SHA-256-nál
DEK generálás os.urandom(32) 256 bit Kriptográfiai minőségű véletlenszám az OS-től
DEK wrapping AES-256-GCM 256-bit KEK, 12-byte IV Authenticated encryption — szerver nem oldhatja ki
Adat titkosítás AES-256-GCM 256-bit DEK, 12-byte IV Minden sorhoz friss IV — nonce reuse ellen
Salt os.urandom(16) 128 bit Egyedi userenként; Supabase-ben tárolva — nem titkos
Auth Tag GCM tag (auto) 16 byte Bit flip → decryption fail (tamper detection)
ℹ️ NOTE

AES-GCM vs AES-CBC: A GCM egyszerre ad titkosítást (confidentiality) ÉS integritásvédelmet (integrity). A CBC csak titkosít — silently corrupted ciphertext-et nem észlelne. A Supabase-ben tárolt adatoknál az integritásvédelem kritikus.


Teljes adatfolyam

ELSŐ BEKAPCSOLÁS (cloud sync setup):
  user jelszót ad meg
      │
      ▼ generate_salt() + generate_dek()   [os.urandom — egyszer fut le]
  salt (16 byte) + DEK (32 byte)
      │
      ▼ derive_kek(password, salt)          [PBKDF2, ~0.5 másodperc]
  KEK (32 byte, RAM-ban marad)
      │
      ▼ wrap_dek(DEK, KEK)                  [AES-256-GCM, ~0ms]
  wrapped_dek + wrapped_dek_iv
      │
      ▼ push_encryption_meta(salt_b64, wrapped_dek, wrapped_dek_iv)
  Supabase: user_encryption_metadata (1 sor)
      │
      ▼ set_session(dek, salt)              [DEK → RAM cache]
  Cloud sync aktív ✅

MÁSIK ESZKÖZÖN:
  user bejelentkezik Google-lel
      │
      ▼ e2e_salt_exists() → True            [pull_encryption_meta()]
  Dialog: "Add meg a szinkron jelszavad"
      │
      ▼ derive_kek(password, salt)          [PBKDF2, ~0.5 másodperc]
  KEK → unwrap_dek(wrapped_dek, iv, KEK) → DEK
      │
      ▼ set_session(dek, salt)
  Minden eszközön azonos DEK — szinkron aktív ✅

ADAT TITKOSÍTÁS (minden dictation push):
  DEK (RAM-ból) + record JSON
      │
      ▼ AES-256-GCM encrypt  [fresh 12-byte IV minden encrypt híváshoz]
  encrypted_payload: {"encrypted_data": "<b64>", "iv": "<b64>", "e2e_version": 2}
      │
      ▼ Supabase history sor  [raw_text="" + final_text="" — server nem látja a tartalmat]

JELSZÓVÁLTOZTATÁS (O(1) — adatsorok érintetlenek):
  old_password → KEK_old → unwrap(wrapped_dek) → DEK  [validálja a régi jelszót]
  new_password → KEK_new → wrap(DEK, KEK_new) → new_wrapped_dek
  Supabase: SET wrapped_dek = new_wrapped_dek           [EGY sor update]
  History/vocabulary sorok: ÉRINTETLEN ✅

UX flow

Első bekapcsolás (Cloud Sync toggle → ON):

Settings → Cloud Sync → [Kapcsolja be]
    │
    ▼
┌─────────────────────────────────────────────────────────┐
│  ☁️ Cloud szinkronizáció bekapcsolása                    │
│                                                         │
│  Az adataid végponttól végpontig titkosítva lesznek.    │
│  Csak te férhetsz hozzájuk — mi sem látjuk őket.        │
│                                                         │
│  Állíts be egy szinkronizálási jelszót:                 │
│  [Jelszó            ]                                   │
│  [Jelszó megerősítés]                                   │
│                                                         │
│  ⚠️ Ha elveszted ezt a jelszót, az adatok nem           │
│     állíthatók vissza. Jegyezd fel biztonságos helyre.  │
│                                                         │
│           [Mégsem]          [🔒 Bekapcsolás]            │
└─────────────────────────────────────────────────────────┘
    → setup_cloud_sync(password) hívódik
    → Supabase: 1 sor write (encryption metadata)

Második eszközön / app újraindítás (ha cloud sync konfigurálva):

Google Login sikeres
    │
    ▼ cloud_sync_is_configured() → True
    │
    ▼
┌─────────────────────────────────────────────────────────┐
│  🔒 Cloud szinkronizáció titkosítva                      │
│                                                         │
│  Ez a fiók titkosított cloud sync-et használ.           │
│  Add meg a szinkronizálási jelszavad:                   │
│                                                         │
│  [Jelszó            ]                                   │
│                                                         │
│  [⏭ Kihagyás — csak lokálisan dolgozom]                │
│                               [Szinkronizálás]         │
└─────────────────────────────────────────────────────────┘
    → unlock_cloud_sync(password) hívódik
    → Ha helyes: DEK → RAM, sync indul
    → Ha rossz jelszó: "Hibás jelszó" toast, ismét próbálhatja
    → Ha kihagyja: lokális adat elérhető, szinkron nem fut

Jelszóváltoztatás (Settings → Cloud Sync → Jelszó megváltoztatása):

[Régi jelszó] + [Új jelszó] + [Megerősítés]
    │
    ▼ change_sync_password(old_pw, new_pw)
    - Ha régi jelszó helyes: ~100ms → "Jelszó sikeresen megváltoztatva"
    - Ha helytelen: "Hibás régi jelszó" toast
    - Adatsorok: ÉRINTETLEN

Ha elfelejti a jelszót:

Settings → Cloud Sync → "Elfelejtettem a jelszavam"
    ▼
┌─────────────────────────────────────────────────────────┐
│  ⚠️ Jelszó visszaállítása                               │
│                                                         │
│  A titkosított szerver-oldali adatokat töröljük.        │
│  (Lokális adataid érintetlen maradnak.)                 │
│  Új jelszóval folytathatod a szinkront.                 │
│                                                         │
│  [Mégsem]      [Törlés és új jelszó beállítása]        │
└─────────────────────────────────────────────────────────┘
    → Supabase: DELETE user_encryption_metadata + history + vocabulary
    → Lokális SQLite: érintetlen
    → setup_cloud_sync(new_password) újrafut

Supabase séma (key-wrapping)

user_encryption_metadata (
    user_email      text PRIMARY KEY,
    salt_b64        text NOT NULL,       -- PBKDF2 salt — NEM titkos
    wrapped_dek     text NOT NULL,       -- AES-GCM(DEK, KEK) — opaque a szerver számára
    wrapped_dek_iv  text NOT NULL,       -- 12-byte GCM nonce — NEM titkos
    created_at      timestamptz,
    updated_at      timestamptz
)
-- RLS: minden user csak a saját sorát látja/módosítja

Fájlstruktúra

app/
  encryption.py            ← KEK derivation, DEK generate/wrap/unwrap,
                               AES-GCM encrypt/decrypt, session DEK cache
  sync/
    encryption_meta.py     ← push_encryption_meta() / pull_encryption_meta()
    history.py             ← DEK-aware push_history_entry + pull_history
    vocabulary.py          ← DEK-aware push_vocabulary + pull_vocabulary
    __init__.py            ← setup_cloud_sync() / unlock_cloud_sync() /
                               change_sync_password() / cloud_sync_is_configured()
docs/
  supabase_schema.sql      ← user_encryption_metadata with wrapped_dek columns

Zero-knowledge garancia (marketing claim alap)

„A jelszavad kizárólag a te fejedben él. Szervereink soha nem látják az adataidat — technikailag lehetetlen. Ha elveszted a jelszavad, az adat nem állítható vissza. Ez nem korlátozás — ez a garancia."

Technikai alap:

  • Cloud sync kikapcsolt: Supabase üres — semmi nem megy a szerverre
  • Cloud sync bekapcsolt: Szerver csak wrapped_dek (opaque) + ciphertext sorokat tárol
  • Supabase admin sem látja a tartalmat — csak base64-kódolt opaque byte-okat
  • DEK kizárólag kliens-oldalon él (RAM-ban) — wrapped_dek nélkül semmit ér
  • wrapped_dek kizárólag a jelszóval oldható ki — jelszó soha nem hagyja el az eszközt
  • Jelszóváltoztatás O(1): Csak a wrapped_dek változik — összes adatsor érintetlen

Kapcsolódó dokumentumok: