Manual Técnico

Manual completo de
Dicta

Guía técnica detallada del sistema de dictado por voz de InnovaAI. Arquitectura, modos, comandos, configuración y más.

v1.16.1 · Última actualización: Marzo 2026

1 Arquitectura General

Sistema de dictado por voz con servidor Windows y app Android

Dicta es un sistema de dictado por voz que convierte voz en texto y lo pega automáticamente donde está el cursor. Tiene dos fuentes de audio: el micrófono del PC (hotkey push-to-talk) y la app Android (streaming via WebSocket).

WiFi / LAN App Android ──(WebSocket ws://IP:9876)──┐ Servidor Rust (Windows) PC Microfono ──(Hotkey F9)─────────────►│ ┌──────────┴───────────┐ Pipeline │ │ │ 1. Whisper API │──► Groq / OpenAI │ 2. Post-procesado │ │ 3. LLM Polish │──► Groq LLM │ 4. Vision (Smart) │──► Claude Sonnet └──────────┬───────────┘ Clipboard + Ctrl+V = texto en cursor

La transcripción usa APIs cloud: Groq (default, ~0.3s) o OpenAI Whisper (~1-3s). El post-procesamiento con LLM usa llama-3.3-70b-versatile (Groq) o gpt-4o-mini (OpenAI). El modo Smart agrega análisis visual con Claude Sonnet de Anthropic.

2 Componentes del Servidor

12 módulos Rust que componen el servidor de escritorio

main
main.rs · 790 líneas
Punto de entrada, carga config, event loop Win32, inicializa todos los subsistemas
pipeline
pipeline.rs · 288 líneas
Orquesta la transcripción según el modo activo (Raw/Clean/Polish/Smart)
hotkey
hotkey.rs · 211 líneas
Detecta la tecla configurada, distingue push-to-talk vs manos libres
mic
mic.rs · 113 líneas
Captura audio del micrófono via cpal, resamplea a 16kHz mono
clipboard
clipboard.rs · 418 líneas
Copia texto al clipboard (Unicode + HTML), simula Ctrl+V, soporta Markdown
tray
tray.rs · 308 líneas
Icono en bandeja del sistema con menú contextual y estados visuales
overlay
overlay.rs · 266 líneas
Ventana overlay transparente en esquina inferior derecha con auto-hide
ws_server
ws_server.rs · 137 líneas
Servidor WebSocket en puerto 9876, recibe audio del celular
history
history.rs · 168 líneas
Base de datos SQLite con historial de dictados y datos de experimento
window_context
window_context.rs · 212 líneas
Captura título de ventana, proceso activo, y screenshot via GDI
experiment
experiment.rs · 171 líneas
Perfil de usuario automático, guardado de audio WAV y screenshots
mdns
mdns.rs · 37 líneas
Publica servicio _dicta._tcp.local. para auto-discovery Android

Librería compartida: takenotes-core

whisper
whisper.rs · 172 líneas
Cliente API Whisper para Groq y OpenAI. Convierte PCM a WAV y envía multipart
post_process
post_process.rs · 369 líneas
Filtros de texto, comandos de voz, LLM polish, Claude Vision
audio
audio.rs · 98 líneas
Resampling a 16kHz, conversión i16/f32, stereo a mono
protocol
protocol.rs · 46 líneas
Tipos serde para mensajes WebSocket (JSON)

3 Modos de Transcripción

4 niveles de procesamiento, seleccionables en tiempo real desde el menú de la bandeja

Raw Más rápido

Solo la salida de Whisper, sin ningún post-procesamiento. Ideal para testing o cuando la velocidad es prioridad.

⚡ Whisper solamente 🕒 ~0.3s
Clean

Whisper + eliminación de muletillas + comandos de voz. No usa LLM. Buena calidad sin latencia extra.

⚡ Whisper + regex 🕒 ~0.3s
Polish Default

Clean + pulido con LLM para puntuación, mayúsculas y gramática. Usa llama-3.3-70b via Groq.

⚡ Whisper + regex + LLM 🕒 ~0.6s
Smart Experimental

Polish + análisis visual (Claude Vision) + contexto de ventana + perfil de usuario. Formatea código, emails, etc.

⚡ Whisper + regex + LLM + Vision 🕒 ~2s
Config polish experiment Modo
MínimofalsecualquieraClean
RecomendadotruefalsePolish
AvanzadotruetrueSmart

4 Sistema de Hotkey

Push-to-talk y manos libres con una sola tecla

GestoAcciónDescripción
Mantener presionado Push-to-Talk Graba mientras mantienes la tecla. Al soltar, transcribe.
Doble tap (<500ms) Manos Libres Activa grabacion continua. Doble tap de nuevo para detener.

Flujo Push-to-Talk

F9 presionado
Grabando
F9 liberado
Transcribiendo
Ctrl+V en cursor

La tecla se configura en dicta.toml con el campo hotkey. Soporta teclas F1-F12, letras, numeros, y combinaciones con Ctrl, Shift, Alt, Win.

# Ejemplos de configuración de hotkey hotkey = "F9" # Tecla F9 hotkey = "Ctrl+Shift+Space" # Combinación de teclas

5 Post-Procesamiento

Muletillas, comandos de voz, limpieza y pulido con IA

Eliminación de muletillas

Se eliminan automáticamente en modos Clean, Polish y Smart:

IdiomaMuletillas eliminadas
Inglésum, uh, er, ah, "you know", "I mean", "like"
Españoleh, este, "o sea", "pues", "digamos", "básicamente"

LLM Polish

En modos Polish y Smart, el texto se envía a un LLM con temperatura 0 (determinístico). El prompt instruye al modelo a corregir solo puntuación, mayúsculas y gramática sin cambiar el significado. Si el LLM falla, se usa el texto sin pulir como fallback.

ProveedorModeloUso
Groqllama-3.3-70b-versatilePolish básico y contextual
OpenAIgpt-4o-miniAlternativa
Anthropicclaude-sonnet-4Vision (Smart mode)

6 Comandos de Voz

27 comandos que convierten palabras habladas en puntuación y formato

EspañolEnglishResultado
"punto""period".
"coma""comma",
"nueva linea""new line"\n
"nuevo parrafo""new paragraph"\n\n
"punto y coma""semicolon";
"punto y aparte".\n
"puntos suspensivos""ellipsis"...
"signo de interrogación""question mark"?
"signo de exclamación""exclamation mark"!
"abrir paréntesis""open paren"(
"cerrar paréntesis""close paren")
"dos puntos""colon":
"arroba""at sign"@
"guion""hyphen"-
Ejemplo: "hola coma mi correo es juan arroba gmail punto com" → hola, mi correo es juan@gmail.com

Los comandos compuestos ("punto y coma") se procesan antes que los simples ("punto") para evitar conflictos. Después de aplicar comandos, 5 regexes de limpieza eliminan espacios innecesarios alrededor de la puntuación.

7 Bandeja del Sistema

Icono de estado y menú contextual completo

Estados del icono

Verde — Idle, listo para dictar
Rojo — Grabando audio
Cyan — Procesando/transcribiendo

Menú contextual (click derecho)

Copy Last Transcription
Modo de transcripción
Transcripción cruda
Transcripción sin IA
Transcripción con IA
Comando inteligente
Preferences...
Reload Config
Open History Folder
Show Log File
About Dicta...
Quit

8 Overlay de Estado

Ventana transparente en la esquina inferior derecha

Recording... Hasta soltar la tecla
Processing... Hasta que se complete
Done! Auto-hide: 1.5s
Error: timeout Auto-hide: 3s

El overlay usa WS_EX_LAYERED | WS_EX_TOPMOST para ser transparente y siempre visible. Los estados Done y Error usan timers de Win32 (SetTimer) para ocultarse automáticamente.

9 Clipboard y Auto-Pegado

Texto se pega automáticamente donde está el cursor

Guardar clipboard original
Copiar texto nuevo
Simular Ctrl+V
Restaurar clipboard (200ms)

El texto se copia en dos formatos simultaneos: CF_UNICODETEXT (texto plano) y CF_HTML (HTML renderizado). El formato markdown **texto** se convierte a <strong> para apps que soporten rich text.

10 WebSocket y Android

App Android como micrófono inalámbrico via WebSocket

Protocolo (Puerto 9876)

// Cliente → Servidor: Inicio de sesión {"type": "session_start", "id": "uuid", "codec": "pcm16", "sample_rate": 16000} // Cliente → Servidor: Audio (frames binarios PCM16 LE) // Cliente → Servidor: Fin de sesión {"type": "session_end", "id": "uuid"} // Servidor → Cliente: Resultado {"type": "result", "session_id": "uuid", "text": "texto transcrito", "duration_ms": 1500}

Descubrimiento mDNS

El servidor publica _dicta._tcp.local. para que la app Android lo descubra automaticamente via Android NSD. No es necesario ingresar la IP manualmente.

App Android

ComponenteFunción
DictationManagerCoordinador: graba, envía, recibe resultado
AudioRecorderCaptura 16kHz mono PCM16, chunks de 60ms
WebSocketClientConexion OkHttp3 al servidor
ServerDiscoveryDescubrimiento mDNS automático
FloatingBubbleServiceBurbuja flotante para dictar sin abrir la app

11 Configuración

Archivo dicta.toml y vocabulario personalizado

dicta.toml

# Proveedor de Whisper: "groq" (rápido) o "openai" provider = "groq" # Clave API de Groq (https://console.groq.com/keys) groq_api_key = "gsk_..." # Clave API de OpenAI (alternativa) api_key = "sk-..." # Tecla para dictar hotkey = "F9" # Idioma (vacío = auto-detectar) language = "" # Post-procesamiento LLM polish = true # Modo Smart (visión + contexto) experiment = false # Clave API de Anthropic (solo Smart mode) anthropic_api_key = ""
Seguridad: Las API keys se guardan localmente en dicta.toml. Nunca se envían a terceros excepto a los proveedores de API correspondientes. El script de empaquetado verifica que no haya keys reales en la distribución.

dicta-vocab.txt

Una palabra o frase por línea. Se envía al API de Whisper como parámetro prompt para mejorar la precisión en terminología específica.

# Vocabulario personalizado para Whisper InnovaAI Kubernetes TypeScript React

Ubicación de archivos

ArchivoUbicación
dicta.tomlJunto al exe o %APPDATA%\Dicta\
dicta-vocab.txtJunto al exe o %APPDATA%\Dicta\
dicta.log%APPDATA%\Dicta\dicta.log
history.db%APPDATA%\Dicta\history.db
Experimentos%APPDATA%\Dicta\experiments\

12 Autenticación Cloud

JWT, planes de suscripción y sistema de créditos

Autenticación JWT

Dicta utiliza JSON Web Tokens (JWT) para autenticar usuarios contra el backend cloud. El flujo de login se realiza mediante un diálogo nativo Win32 (login_dialog.rs) que solicita email y contraseña sin depender de un navegador.

TokenDuraciónUso
Access Token1 horaAutenticación de requests al backend
Refresh Token30 díasRenovar access token sin re-login

Hashing de contraseñas

Las contraseñas se hashean con Argon2 (ganador de PHC) en el backend. Nunca se almacenan en texto plano. El cliente envía la contraseña via HTTPS y el servidor aplica Argon2id con salt aleatorio antes de guardar en la base de datos.

Planes de suscripción

PlanDescripciónLímite
FreeAcceso básico sin costoFuncionalidad limitada
TrialPrueba completa de funciones Pro50 transcripciones
ProMonthlySuscripción mensualCréditos mensuales renovables
ProAnnualSuscripción anual (descuento)Créditos anuales renovables
LifetimePago único, acceso permanenteSin límite de créditos

Sistema de créditos

Los usuarios Pro reciben créditos que se consumen con cada transcripción. Los planes Lifetime y ProAnnual no verifican créditos (acceso ilimitado). El endpoint GET /api/v1/credits retorna el saldo actual del usuario.

Login nativo: El diálogo de autenticación es una ventana Win32 nativa (login_dialog.rs) que se integra con el sistema de bandeja. Los tokens se almacenan de forma segura en %APPDATA%\Dicta\.

13 API Endpoints

Endpoints REST del backend cloud de Dicta

MétodoEndpointDescripciónAuth
POST /api/v1/auth/register Registro de nuevo usuario (email + password) No
POST /api/v1/auth/login Login, retorna access + refresh tokens No
GET /api/v1/me Perfil del usuario autenticado JWT
GET /api/v1/version Versión más reciente disponible No
POST /api/v1/transcribe Transcripción de audio (multipart/form-data) JWT
GET /api/v1/subscription Estado de suscripción del usuario JWT
GET /api/v1/credits Saldo de créditos restantes JWT
Formato de audio: El endpoint /api/v1/transcribe acepta audio como multipart/form-data con el archivo WAV en el campo audio. El backend reenvía a Groq o OpenAI según la configuración del servidor.

14 Traducción

Traducción automática del texto transcrito

Dicta soporta traducción automática del texto transcrito como paso adicional en el pipeline de post-procesamiento. El usuario puede configurar un idioma destino y el texto se traduce después de la transcripción y el pulido, antes de pegarse en el cursor.

La traducción utiliza el mismo LLM del pipeline de polish (llama-3.3-70b via Groq o gpt-4o-mini via OpenAI) con un prompt especializado que preserva el formato y la puntuación del texto original.

Caso de uso: Dictar en español y obtener el texto traducido al inglés directamente en el cursor. Útil para redactar emails o documentación en otro idioma.

15 Sistema de Actualizaciones

Actualizaciones automáticas con Inno Setup y verificación semver

Arquitectura de auto-update

El cliente Dicta verifica periódicamente si hay una nueva versión disponible consultando el endpoint GET /api/v1/version del backend. El módulo updater.rs gestiona todo el ciclo de actualización de forma transparente para el usuario.

updater.rs (cada 6h)
GET /api/v1/version
Comparación semver
Descarga a %TEMP%
Inno Setup /VERYSILENT
Auto-restart

Proceso detallado

PasoDescripción
1. VerificaciónCada 6 horas, updater.rs consulta GET /api/v1/version para obtener la versión más reciente
2. ComparaciónComparación semántica (semver) entre la versión local (CARGO_PKG_VERSION) y la del servidor
3. DescargaSi hay versión nueva, descarga el instalador al directorio %TEMP%
4. InstalaciónEjecuta Inno Setup con flag /VERYSILENT para instalación sin interacción del usuario
5. ReinicioDespués de la instalación, Dicta se reinicia automáticamente con la nueva versión
Silencioso: El proceso de actualización es completamente transparente. El usuario solo ve una notificación en el overlay cuando se aplica una actualización y el programa se reinicia.

16 APIs Externas

Servicios cloud utilizados para transcripción, pulido y visión

ServicioProveedorModeloLatencia
Transcripción Groq (default) whisper-large-v3 ~0.3-0.8s
Transcripción OpenAI whisper-1 ~1-3s
LLM Polish Groq (default) llama-3.3-70b-versatile ~0.2-0.5s
LLM Polish OpenAI gpt-4o-mini ~0.5-1s
Visión Anthropic claude-sonnet-4 ~1-2s

17 Base de Datos e Historial

SQLite local con historial completo de dictados

-- Esquema de la tabla dictations CREATE TABLE dictations ( id TEXT PRIMARY KEY, -- UUID v4 timestamp INTEGER NOT NULL, -- Epoch millis raw_text TEXT NOT NULL, -- Salida cruda de Whisper clean_text TEXT NOT NULL, -- Después de filtros duration_ms INTEGER DEFAULT 0, -- Duración del audio source TEXT DEFAULT 'microphone', -- 'microphone' o 'android' window_title TEXT DEFAULT '', -- Titulo de ventana process_name TEXT DEFAULT '', -- Proceso activo screenshot_path TEXT DEFAULT '', -- Ruta al screenshot audio_path TEXT DEFAULT '', -- Ruta al audio WAV context_text TEXT DEFAULT '', -- Polish contextual baseline_polish_text TEXT DEFAULT '' -- Polish básico );

Perfil de usuario automático

En modo Smart, el sistema analiza las últimas 100 dictaciones para construir un perfil: apps más usadas (ranking con porcentaje), idioma dominante (español vs inglés), y categorías de contexto (coding, email, chat, docs). El perfil se refresca cada 20 dictaciones.

18 Estructura del Proyecto

Organización de archivos del repositorio

desktop/ ├── takenotes-core/ # Librería compartida │ └── src/ │ ├── lib.rs # Exporta modulos │ ├── whisper.rs # Cliente API Whisper │ ├── post_process.rs # Filtros, LLM, Vision │ ├── audio.rs # Resampling, conversion │ └── protocol.rs # Tipos WebSocket ├── takenotes-server/ # Binario Windows │ └── src/ │ ├── main.rs # Entry point, event loop │ ├── pipeline.rs # Orquestación │ ├── hotkey.rs # Polling tecla │ ├── mic.rs # Captura audio │ ├── clipboard.rs # Clipboard + Ctrl+V │ ├── tray.rs # Icono bandeja │ ├── overlay.rs # Ventana overlay │ ├── ws_server.rs # WebSocket │ ├── history.rs # SQLite │ ├── window_context.rs # Captura ventana │ ├── experiment.rs # Perfil usuario │ └── mdns.rs # mDNS service ├── dist-template/ # Archivos para ZIP │ ├── dicta.toml │ ├── dicta-vocab.txt │ └── README.txt └── package.ps1 # Script empaquetado android/ └── app/src/main/java/com/takenotes/ ├── MainActivity.kt ├── DictationManager.kt ├── audio/AudioRecorder.kt ├── network/WebSocketClient.kt, ServerDiscovery.kt ├── service/FloatingBubbleService.kt, RecordingService.kt ├── data/AppDatabase.kt, DictationEntity.kt └── ui/MainScreen.kt, HistoryScreen.kt

19 Build y Distribución

Compilar, empaquetar y distribuir Dicta

Compilar

# Compilar release cd desktop cargo build --release # Resultado: desktop/target/release/takenotes-server.exe

Empaquetar

# Generar ZIP de distribucion cd desktop .\package.ps1 # Resultado: dist/Dicta-1.5.0-win64.zip # Contenido: Dicta.exe + dicta.toml + dicta-vocab.txt + README.txt

Gestión de versión

Cargo.toml es la fuente única de verdad para la versión. Se propaga automáticamente a:

DestinoMecanismo
Log de arranque y Aboutenv!("CARGO_PKG_VERSION")
Metadata del .exebuild.rs via winres
Nombre del ZIPpackage.ps1 lee Cargo.toml