aboutsummaryrefslogtreecommitdiffstats
path: root/config
diff options
context:
space:
mode:
Diffstat (limited to 'config')
-rw-r--r--config/asistente.toml173
1 files changed, 88 insertions, 85 deletions
diff --git a/config/asistente.toml b/config/asistente.toml
index a47f5b2..bab64c0 100644
--- a/config/asistente.toml
+++ b/config/asistente.toml
@@ -1,10 +1,12 @@
-# Configuración del asistente de voz.
+# Voice assistant configuration.
#
-# Las rutas relativas se resuelven contra la carpeta de este fichero, no contra
-# el directorio desde el que se lanza el binario.
+# Relative paths are resolved against the directory of this file, not against
+# the directory the binary is launched from.
#
-# Los valores que llevan un comentario con una medición vienen de
-# docs/RENDIMIENTO.md: son los que se midieron en esta máquina, no adivinanzas.
+# Values with a comment carrying a measurement come from docs/RENDIMIENTO.md:
+# they were measured on this machine, not guessed.
+#
+# The prompts are in Spanish because the assistant speaks Spanish.
[general]
language = "es"
@@ -18,22 +20,22 @@ URLs ni código salvo que te lo pidan explícitamente. Si no sabes algo, dilo \
en una frase.
"""
-# SUSTITUYE a system_prompt en la pasada en que el modelo decide si llamar a
-# una herramienta. Va sola a propósito: medido con Qwen3.5-2B, añadirle
-# cualquier indicación de estilo —dos palabras bastan— hace que deje de llamar
-# a las herramientas y se invente el dato. La guía sola acierta 8 de 8; con
-# «Responde breve.» detrás, 1 de 8; con la persona de asistente de voz, 0 de 8.
-# Ver docs/RENDIMIENTO.md. Se desactiva con tools.dedicated_prompt = false.
+# REPLACES system_prompt in the pass where the model decides whether to call
+# a tool. It goes alone on purpose: measured with Qwen3.5-2B, adding any style
+# instruction (two words are enough) makes it stop calling tools and make the
+# data up. The guide alone gets 8 of 8; with «Responde breve.» after it, 1 of 8;
+# with the voice-assistant persona, 0 of 8. See docs/RENDIMIENTO.md. Turn it
+# off with tools.dedicated_prompt = false.
tools_prompt = """
Antes de responder, comprueba si alguna de tus herramientas te da el dato. Si \
es así, llámala primero y espera su resultado; no contestes de memoria. Sólo \
cuando tengas el resultado, resúmelo en una frase.
"""
-# Se añade a system_prompt para redactar la respuesta cuando una herramienta ya
-# devolvió su resultado. Aquí sí se puede añadir estilo —la llamada ya ocurrió—
-# y hace falta: sin esto el modelo anuncia lo que acaba de hacer («he tomado una
-# foto, ahora puedo responderte sobre el color») en vez de decir lo que averiguó.
+# Appended to system_prompt to write the answer once a tool has returned its
+# result. Style can be added here (the call already happened) and it is needed:
+# without it the model announces what it just did («he tomado una foto, ahora
+# puedo responderte sobre el color») instead of saying what it found out.
tool_result_prompt = """
Acabas de recibir el resultado de una herramienta. Contesta a la pregunta \
usando ese resultado y nada más. No anuncies lo que has hecho ni lo que \
@@ -42,7 +44,7 @@ otro idioma, tradúcelo al español.
"""
[audio]
-# Vacío = el dispositivo por defecto. `asistente devices` los lista.
+# Empty = the default device. `asistente devices` lists them.
input_device = ""
output_device = ""
playback_prebuffer = 0.20
@@ -51,15 +53,15 @@ output_gain = 1.0
[vad]
frame_seconds = 0.1
preroll_seconds = 0.3
-silence_hold = 0.8 # silencio que cierra una intervención
-min_utterance = 0.3 # se mide sobre la voz, sin contar el preroll
+silence_hold = 0.8 # silence that ends an utterance
+min_utterance = 0.3 # measured on speech, not counting the preroll
max_utterance = 20.0
threshold_factor = 3.0
min_threshold = 0.0008
max_threshold = 0.02
-# Cortar al asistente hablando encima. Apagado por defecto: con altavoces
-# abiertos el micrófono se oye a sí mismo y el asistente se interrumpe solo.
-# Enciéndelo con auriculares, o con --barge-in.
+# Interrupt the assistant by talking over it. Off by default: with open
+# speakers the microphone hears itself and the assistant interrupts itself.
+# Turn it on with headphones, or with --barge-in.
barge_in = false
barge_in_factor = 4.0
@@ -72,8 +74,8 @@ step = 0.4
stability = 2
partials = true
dedicated_final_model = false
-# CPU a propósito: la GPU de 4 GB la ocupa el hablante del TTS y disputársela
-# sale más caro que decodificar aquí. Ver docs/RENDIMIENTO.md.
+# CPU on purpose: the 4 GB GPU is taken by the TTS talker and fighting over
+# it costs more than decoding here. See docs/RENDIMIENTO.md.
execution_provider = "cpu"
inter_threads = 2
intra_threads = 4
@@ -87,7 +89,7 @@ top_p = 0.9
top_k = 40
min_p = 0.1
repeat_penalty = 1.1
-max_tokens = 400 # una respuesta hablada larga cansa, y la síntesis es lo caro
+max_tokens = 400 # a long spoken answer is tiring, and synthesis is the expensive part
max_tool_rounds = 4
request_timeout_secs = 120
@@ -101,12 +103,12 @@ top_k = 50
top_p = 1.0
repetition_penalty = 1.05
max_new_tokens = 2048
-warmup = true # la primera síntesis cuesta ~3,5 s más que el resto
+warmup = true # the first synthesis costs ~3.5 s more than the rest
request_timeout_secs = 180
-# Voz clonada, registrada en el servidor al arrancar. Los tres ficheros salen
-# de `qwen-codec --talker` sobre una grabación de referencia; hay un guion en
-# scripts/clonar-voz.sh.
+# Cloned voice, registered with the server at startup. The three files come
+# from `qwen-codec --talker` on a reference recording; there is a script in
+# scripts/clone-voice.sh.
[tts.reference]
name = "asistente"
speaker = "../assets/voices/asistente.spk"
@@ -115,97 +117,98 @@ transcript = "../assets/voices/asistente.txt"
[tools]
enabled = true
-# Alterna entre tools_prompt (para decidir) y system_prompt (para redactar).
-# Es lo único que hace que las herramientas funcionen con este modelo; a
-# cambio, las respuestas que no usan herramienta pierden la guía de estilo.
-# Ponlo a false para priorizar el estilo sobre las herramientas.
+# Alternates between tools_prompt (to decide) and system_prompt (to write).
+# It is the only thing that makes tools work with this model; in exchange,
+# answers that use no tool lose the style guide.
+# Set it to false to favour style over tools.
dedicated_prompt = true
-# Ejecución de órdenes del sistema. Apagada por defecto a conciencia: darle
-# una shell a un modelo que obedece a lo que oye por el micrófono es un cambio
-# de postura de seguridad, no una comodidad. Actívala aquí o con --shell.
+# System command execution. Off by default on purpose: giving a shell to a
+# model that obeys what it hears through the microphone is a change of
+# security posture, not a convenience. Turn it on here or with --shell.
shell = false
shell_allowlist = ["date", "uptime", "free", "df", "ls", "mkdir", "cat"]
shell_timeout_secs = 10
shell_dry_run = false
shell_working_dir = ""
-# Búsqueda en internet. La clave NO va aquí: se lee de la variable de entorno
-# que indique api_key_env, porque este fichero se versiona y un secreto dentro
-# acaba en el historial de git.
+# Web search. The key does NOT go here: it is read from the environment
+# variable named by api_key_env, because this file is versioned and a secret
+# in it ends up in the git history.
#
-# Tres buscadores, medidos:
-# tavily ~2,4 s. Devuelve una respuesta YA REDACTADA además de los enlaces,
-# que es lo que se puede leer en voz alta sin gastar otra vuelta del
-# modelo en resumir. Necesita clave.
-# ddgs 1,5-5,8 s. Sin clave. Consulta DuckDuckGo, Brave, Mojeek, Startpage
-# y compañía a través de scripts/buscar-ddgs.sh. Sólo devuelve
-# fragmentos: la síntesis la tiene que hacer el modelo, y con 2B sale
-# algo peor que con tavily.
-# searxng Sin clave, pero hace falta una instancia propia. Como ddgs, sólo
-# devuelve resultados.
+# Three backends, measured:
+# tavily ~2.4 s. Returns an ALREADY WRITTEN answer besides the links,
+# which can be read aloud without spending another model round
+# summarizing. Needs a key.
+# ddgs 1.5-5.8 s. No key. Queries DuckDuckGo, Brave, Mojeek, Startpage
+# and friends through scripts/search-ddgs.sh. Only returns
+# snippets: the model has to summarize, and with 2B the result is
+# somewhat worse than tavily.
+# searxng No key, but needs your own instance. Like ddgs, it only returns
+# results.
[search]
enabled = true
backend = "tavily" # "tavily", "ddgs" o "searxng"
api_key_env = "TAVILY_API_KEY"
-base_url = "" # sólo para searxng, p. ej. "http://127.0.0.1:8888"
-# Programa del backend "ddgs". {consulta} y {max} se sustituyen antes de
-# ejecutar, y tiene que escribir JSON por la salida estándar. Vale cualquier
-# otro programa que respete eso, incluido un puente a un servidor MCP.
-command = ["../scripts/buscar-ddgs.sh", "{consulta}", "{max}"]
+base_url = "" # searxng only, e.g. "http://127.0.0.1:8888"
+# Program for the "ddgs" backend. {query} and {max} are substituted before
+# running, and it must write JSON to standard output. Any other program that
+# honours that works too, including a bridge to an MCP server.
+command = ["../scripts/search-ddgs.sh", "{query}", "{max}"]
max_results = 5
timeout_secs = 20
-# Mirar por la cámara. El servidor ya carga el proyector multimodal, así que el
-# mismo modelo que conversa describe lo que capta.
+# Looking through the camera. The server already loads the multimodal
+# projector, so the same model that converses describes what it captures.
[camera]
enabled = true
device = "/dev/video2"
-# La resolución manda en la latencia. Medido en esta máquina: 1,3 s a 320x240,
-# 2,9 s a 640x480 y 7,8 s a 1280x720. 640x480 es el equilibrio.
+# Resolution rules latency. Measured on this machine: 1.3 s at 320x240,
+# 2.9 s at 640x480 and 7.8 s at 1280x720. 640x480 is the balance.
width = 640
height = 480
-# Fotogramas descartados para que se asiente la exposición automática; el
-# primero suele salir quemado y descartar unos pocos es casi gratis.
+# Frames discarded so auto-exposure settles; the first one is usually
+# blown out and discarding a few is almost free.
warmup_frames = 5
timeout_secs = 15
-# Vacío = no se guarda ningún fotograma en disco, que es lo que corresponde.
-# Ponle una carpeta sólo para depurar qué está viendo el modelo.
+# Empty = no frame is saved to disk, which is right.
+# Set a directory only to debug what the model is seeing.
save_dir = ""
-# Mirar la pantalla. Es la misma visión que la cámara, pero con un ajuste
-# distinto porque el problema es distinto: una pantalla es TEXTO.
+# Looking at the screen. Same vision as the camera, but tuned differently
+# because the problem is different: a screen is TEXT.
#
-# Medido con tipografía de interfaz de 13 px, preguntando por datos concretos:
-# 1280 px 7,6 s acierta 3 de 3
-# 960 px 4,5 s acierta 2 de 3
-# 640 px 2,4 s acierta 1 de 3
+# Measured with 13 px UI type, asking for specific details:
+# 1280 px 7.6 s 3 of 3 right
+# 960 px 4.5 s 2 of 3 right
+# 640 px 2.4 s 1 of 3 right
#
-# Y cuando falla no dice que no lo lee: se lo inventa. A 640 px contestó que el
-# error era «no se pudo abrir el archivo involution» y que la reunión era «a
-# las 10:00»; ninguna de las dos cosas estaba en la imagen. Por eso 1280 aunque
-# cueste el triple que la cámara.
+# And when it fails it does not say it cannot read it: it makes it up. At
+# 640 px it answered that the error was «no se pudo abrir el archivo
+# involution» and the meeting was «at 10:00»; neither was in the image. Hence
+# 1280 even though it costs three times the camera.
[screen]
enabled = true
-# Detecta el entorno gráfico (grim en Wayland, maim/imagemagick en X11), captura
-# y reduce a {ancho}. Editar el guion es más fácil que recompilar.
-command = ["../scripts/capturar-pantalla.sh", "{ancho}", "{salida}"]
+# Detects the graphical environment (grim on Wayland, maim/imagemagick on
+# X11), captures and scales down to {width}. Editing the script is easier than
+# recompiling.
+command = ["../scripts/capture-screen.sh", "{width}", "{output}"]
width = 1280
-output = "" # monitor concreto; vacío = todo
+output = "" # a specific monitor; empty = all
timeout_secs = 20
-# Vacío = no se guarda ninguna captura. Aquí pesa más que en la cámara: en una
-# captura de pantalla caben contraseñas, mensajes privados y correo abierto.
+# Empty = no capture is saved. It weighs more here than for the camera: a
+# screenshot can hold passwords, private messages and open email.
save_dir = ""
[supervisor]
-manage = true # lanzar los servidores; --no-manage los supone arriba
+manage = true # start the servers; --no-manage assumes they are up
startup_timeout_secs = 180
[supervisor.llama]
binary = "../vendor/llama.cpp/build/bin/llama-server"
model = "../models/Qwen3.5-2B.Q8_0.gguf"
mmproj = "../models/mmproj-BF16.gguf"
-# Copia de la plantilla del modelo con el bloque <think> cerrado de entrada.
-# Sin esto el modelo razona entre 7 y 9 s antes de la primera palabra audible.
+# Copy of the model template with the <think> block closed from the start.
+# Without it the model reasons for 7 to 9 s before the first audible word.
chat_template = "qwen35-no-think.jinja"
extra_args = [
"--threads", "10", "--threads-batch", "10",
@@ -213,8 +216,8 @@ extra_args = [
"--gpu-layers", "10", "--split-mode", "layer",
"--tensor-split", "1", "--main-gpu", "0",
"--no-mmap",
- # 8192 en vez del contexto completo del modelo (262144): la caché KV de ese
- # tamaño no cabe en 4 GB junto al TTS. Ver docs/RENDIMIENTO.md.
+ # 8192 instead of the model's full context (262144): a KV cache that size
+ # does not fit in 4 GB next to the TTS. See docs/RENDIMIENTO.md.
"--ctx-size", "8192", "--parallel", "2",
"--cache-ram", "6144",
"--rope-freq-base", "1000000", "--rope-freq-scale", "0.25",
@@ -224,8 +227,8 @@ extra_args = [
binary = "../vendor/qwentts.cpp/build/tts-server"
model = "../models/qwen-talker-1.7b-base-Q8_0.gguf"
codec = "../models/qwen-tokenizer-12hz-Q8_0.gguf"
-# El ajuste con más efecto de todo el sistema: de fábrica son 24 s, y con eso
-# el servidor no devuelve nada hasta terminar la frase entera. Medido, baja el
-# primer audio de 4948 ms a 585 ms.
+# The single most effective setting in the system: the stock value is 24 s,
+# and with it the server returns nothing until the whole sentence is done.
+# Measured, it lowers the first audio from 4948 ms to 585 ms.
codec_chunk_dur = 1.0
extra_args = []