Deep market/tech analysis and phase-by-phase build plans for (1) a dialogue recorder with realtime speaker diarization + content-based name assignment, and (2) a Typeless-style AI voice input method, both running lightweight, preferably local, models.
Both products are realisable today with open-source, local-first components, no cloud dependency, no API fees. The two projects share a single AI foundation (speech → text → meaning) and are technically synergistic: the voice input method is essentially a single-speaker special case of the dialogue recorder. Building them as a shared "voice-AI core" with two thin product surfaces is the highest-leverage architecture.
Build a shared Rust/Python voice-AI core (streaming STT + diarization + local LLM polish). Project 2 (voice input) is a strict subset and should ship first, it is simpler, delivers standalone value, and de-risks the harder Project 1. Then Project 1 layers diarization + identity/name assignment on the same core.
Analysis grounded in live open-source reconnaissance (Agent-Reach / Exa semantic search + GitHub/README extraction, August 2026) plus the local stt-transcription skill reference. Key sources: Diart, pyannote.audio 3.x, sherpa-onnx, OpenTypeless, AriaType, and speaker-to-name LLM literature (arXiv 2509.15082). Figures marked as of 2026-08.
Goal: record a multi-person conversation in real time; continuously identify who is speaking by voice characteristics; then assign names to those voices based on content context, all with lightweight, preferably local, models.
The task splits into four distinct capabilities, each with a mature open-source answer:
| Capability | What it does | Flagship open-source |
|---|---|---|
| VAD (voice activity) | Detect speech vs. silence, when someone talks | Silero, pyannote.audio segmentation |
| Speaker diarization | Group segments into distinct voices (SPK_0, SPK_1…) — "who, when" | Diart (realtime, MIT), pyannote 3.1 (offline) |
| STT | Turn speech into text (for content + name inference) | Whisper (turbo/small), sherpa-onnx streaming |
| Name assignment | Bind a cluster to a real identity from content ("…as Mike said…") | Local LLM over the transcript + names |
juanmc2005/diart is a Python framework purpose-built for real-time speaker diarization (MIT, ~2k★). It fuses a speaker-segmentation model and a speaker-embedding model into an incremental clustering pipeline that becomes more accurate as the conversation progresses, exactly the online behavior Project 1 requires. Configurable latency (as low as ~500 ms) and native WebSocket serving make it the natural engine.
pyannote.audio 3.1 is superb offline (5–10× real-time on GPU, native overlap handling) but is batch-oriented. Diart is the only mainstream engine that streams diarization online, the deciding factor for a "realtime analyzer." Use Diart for live, pyannote for batch post-processing.
# Diart streaming speaker diarization (core loop)
from diart import OnlineSpeakerDiarization
from diart.sources import MicrophoneAudioSource
from diart.inference import RealTimeInference
from diart.sinks import RTTMWriter
import diart.inference as rec
pipeline = OnlineSpeakerDiarization.from_pretrained("diart/speaker-diarization-xenova")
config = pipeline.config
async def on_stream(wav):
for turn, _, speaker in pipeline(wav):
yield turn, speaker # (start,end) → SPK_x, live
# Serve over WebSocket for a recorder + live UI
inference = RealTimeInference(pipeline, MicrophoneAudioSource(config.sample_rate))
Diarization gives anonymous clusters (SPK_0). Assigning real names is a content-inference problem, solved in the research literature (e.g. arXiv 2509.15082 "Identity-Aware LLM Refinement of Speaker Diarization") and by AssemblyAI's LLM workflows: feed the diarized transcript + a roster of expected names into a local LLM, which maps clusters to identities using linguistic context, "as Mike said," self-introductions, topic affinity.
| Signal | Example in transcript | Strength |
|---|---|---|
| Self-introduction | "Hi, I'm Mike…" (SPK_0's turn) | Strong, ground truth |
| Direct address | "…as Mike said" (one turn later) | Strong cross-cluster link |
| Role/topic affinity | SPK_1 always explains technicals | Medium (role → name via roster) |
| Turn cadence/count | dominant speaker = manager, etc. | Weak, use as tiebreak |
Local model choice: any instruct LLM ≥7B (Llama-3.1-8B, Qwen-2.5-7B, Mistral-7B) running via llama.cpp/Ollama is enough, the task is a short structured reasoning pass over segments, not heavy generation. Prompt: give diarized transcript + name roster, ask for a cluster→name map with confidence.
Name assignment is probabilistic, it can mislabel on noisy audio. Ship it as suggested with an edit affordance, and persist the user's mapping so the identity sticks for the session (voice embedding cache per name). Do not present it as infallible.
| Layer | Choice | Why |
|---|---|---|
| Audio capture | PortAudio / Python sounddevice (or Rust cpal) | 16 kHz mono, streamed in chunks |
| Diarization (live) | Diart + speaker embedding (pyannote or xenova) | Realtime online clustering, WebSocket-ready |
| VAD | Silero VAD (10 ms) or Diart built-in | Cheap, accurate onset/offset |
| STT | Whisper small/turbo (or sherpa-onnx streaming) | On-device, multilingual, good quality/speed |
| Name mapping | Local LLM (8B via Ollama/llama.cpp) + embedding cache | Private, no cloud cost |
| Record + replay | local WAV/MP3 + timestamps (.rttm/JSON) | Export SRT/meeting minutes |
Repo scaffold (Rust or Python backend + minimal web UI). Audio capture to 16 kHz mono chunks. Verify Silero VAD fires correctly on a two-voice test recording.
Integrate Diart online pipeline. Stream turns with live SPK_x labels to the UI. Benchmark latency (~500 ms–2 s) and correctness on a 3-speaker recording. Milestone: live "who is talking now" indicator.
Attach Whisper (small/turbo) segments to diarized turns. Produce per-speaker transcript lines with timestamps. Render an aligned, color-coded live transcript.
Roster UI (user enters expected names). Local LLM pass maps SPK_x → name with confidence. Editable + persistent voice-embedding cache per name. Milestone: "Mike (conf 0.93)" labels.
Meeting-minutes generation (LLM summary), SRT/VTT export, re-open recorded sessions for name re-assignment after the fact.
Overlapping-speech handling, noise robustness, accent coverage, GPU/CPU fallback, Windows/macOS packaging (Tauri).
The killer positioning is "meeting recorder that knows who said what, 100% on-device." Differentiation vs. cloud meeting-AI (Otter, Fireflies) is privacy + realtime + no per-minute fees. Win on a privacy-sensitive segment (legal, HR, healthcare, journalists).
Goal: a global hotkey → speak naturally → polished text injected into whatever app you're in. Like Typeless, but powered by a lightweight local model (no cloud).
The space already has two strong references, one cloud-BYOK, one local-first:
| Project | Stack | Philosophy | License |
|---|---|---|---|
| OpenTypeless (tover0314-w) | Tauri 2 + React 19 + Rust; Whisper + LLM providers | BYOK — bring your own (mostly cloud) API key | MIT |
| AriaType (joe223) | Desktop (macOS/Windows); llama.cpp sidecar, SenseVoice, WhisperFlow | Local-first, privacy-first, GLM/SenseVoice | AGPL-3.0 |
| sherpa-onnx (k2-fsa) | Streaming ASR, C++/Python, offline | True streaming local STT (Zipformer-transducer) | Apache-2.0 |
Key insight: AriaType already proves the exact architecture you want, a Tauri desktop app driving a llama.cpp/ONNX sidecar for fully local speech-to-text + LLM "polish." Your build is a focused, product-polished iteration on this pattern (ideally landing as your own opinionated app, or a clean fork), not a from-scratch research problem.
For on-device Chinese+English dictation, SenseVoice-Small (Alibaba, ~220M params, very fast, multilingual, punctuation-aware) is the sweet spot; Whisper small for maximum accuracy; sherpa-onnx streaming (Zipformer-transducer) if you need true per-word streaming as you speak. All run on CPU comfortably on a modern laptop.
Global hotkey ─▶ microphone capture (Rust cpal)
│
▼
[ Local STT: SenseVoice / Whisper / sherpa-onnx ] ── text
│
▼
[ Local LLM "polish": llama.cpp sidecar (8B) ] ── clean, punctuated text
│
▼
Inject into focused app (Windows SendInput / macOS CGEvent)
│
Optional: per-app context & custom templates
Keep a fast path (STT → raw text, injected immediately, sub-300ms feel) and a polish path (after silence, local LLM fixes punctuation, capitalization, filler words, and applies app-specific templates). This matches how Typeless/AriaType feel "instant yet polished."
Tauri app shell; global hotkey (Rust global-hotkey crate); mic capture to 16 kHz mono; permission handling (mic + accessibility).
Integrate SenseVoice-Small via ONNX Runtime or llama.cpp (or sherpa-onnx for streaming). Hold-to-talk → live partial transcript. Milestone: raw dictation into any app, fully offline.
Spawn llama.cpp server with an 8B model; on utterance end, run punctuation/casing/cleanup pass; inject polished text. Add custom templates + per-app rules.
Settings UI (model selection, hotkey, language, templates), error states, first-run model download, tray icon, "learn corrections" (record user edits as correction maps, as AriaType does).
macOS + Windows installers; model bundling/lazy download; memory footprint tuning; startup speed. Milestone: two-OS installers with zero cloud calls.
Model-quality regression harness on a personal dictation testset (Chinese+English); telemetry-free usage stats; community model packs.
(1) On-device latency and first-word delay are the UX battleground, tune aggressively. (2) Chinese dictation quality varies sharply across local models; benchmark SenseVoice vs Whisper on your accent before committing. (3) Accessibility-permission UX is fiddly on macOS, budget time. (4) AriaType is AGPL, if you fork it, your derivative must stay AGPL; if you build fresh with MIT libs (OpenTypeless-style), keep MIT.
The two products are one engine with two surfaces. Recommene building a shared voice-AI core:
| Shared module | Used by P1 | Used by P2 |
|---|---|---|
| Streaming STT (SenseVoice / Whisper / sherpa) | ✅ transcript | ✅ dictation |
| VAD (Silero) | ✅ turn boundaries | ✅ hold-to-talk |
| Local LLM runner (llama.cpp sidecar) | ✅ name mapping + minutes | ✅ polish + templates |
| Audio capture/IO (Rust cpal / Python) | ✅ record | ✅ capture |
| Tauri shell | recorder UI | input-method UI |
It is simpler (single speaker, no identity resolution), delivers standalone daily value, and proves the entire local voice stack (capture → STT → LLM → injection). Project 1 then only adds diarization + name inference on the same proven core, dramatically cutting its risk and time-to-value.
| Risk | Impact | Mitigation |
|---|---|---|
| Local STT quality below cloud | High (P2 core) | Benchmark SenseVoice/Whisper on your own accents; allow optional API fallback |
| Realtime diarization accuracy in noise/overlap | High (P1) | Ship suggestions + edit UX; batch pyannote re-run for recorded sessions |
| Latency/first-word delay | High (P2 UX) | VAD-triggered streaming, model warm start, quantization (Q4) |
| License entanglement (AGPL forks) | Medium | Prefer MIT (Diart, OpenTypeless) or Apache-2.0 (sherpa); avoid wholesale AGPL forks |
| On-device model footprint (RAM/disk) | Medium | Small models (~200M STT + 4–8B Q4 LLM), lazy download, CPU-friendly |
| Privacy positioning vs cloud incumbents | Strategic | Lead with "nothing leaves your device" — legal/HR/journalist segments |
Both products are fully achievable with today's open-source, local-first stack. Build the shared core once; ship the voice input method first for quick standalone value and stack validation; then layer realtime diarization + content-based naming on top for the more ambitious conversation recorder. The differentiators, realtime on-device "who said what" and fully-offline voice input, are exactly where cloud incumbents are structurally weak.
Deep analysis grounded in Agent-Reach / Exa / GitHub reconnaissance, August 2026. Model names, star counts and licenses as of research date; verify before committing.
ARLI membership: the notes from the workshop
One site of yours, measured, with the price for the work in the same document
ARLI, Inc., a Delaware corporation. Questions: hq@arliwork.com.