Una caché que aguanta
La ventana del historial solo se mueve cuando eso ahorra más que la caché. Las imágenes y el razonamiento anteriores se quedan donde estaban, así que el prompt en caché no se reescribe.
Dulus es un agente de IA para tu escritorio y tu terminal. Trabaja en tus archivos, tu shell, tu navegador y tu pantalla — con el modelo que elijas. Y cuando una sola mente no basta, llama a la bandada.
Funciona con los modelos que ya usas
Medido, no prometido
Seis sesiones de programación, desde un arreglo de 8 turnos hasta una auditoría de 120, repetidas frente a Claude Code, Cursor, Codex CLI, Cline, Aider y GitHub Copilot: la misma transcripción, el mismo tokenizador y los mismos precios. Dulus quedó primero en las cinco formas en que ponderamos los resultados.
La ventana del historial solo se mueve cuando eso ahorra más que la caché. Las imágenes y el razonamiento anteriores se quedan donde estaban, así que el prompt en caché no se reescribe.
El modelo recibe los turnos recientes; la conversación completa se queda en tu máquina. Cuando necesita algo más viejo, Dulus lo busca con su propia herramienta Loopback.
Un kernel de Python persistente guarda los datos grandes en memoria y no en la conversación. Al contexto solo llega lo que imprime.
Memoria que puedes abrir: markdown en un palacio de salas. Lo esencial se carga en cada sesión, y cada turno trae de vuelta hasta tres memorias relevantes.
A Dulus se le midió corriendo su propio código de contexto. Los demás agentes se modelaron según cómo maneja cada uno su contexto, sin correr su código fuente. El método y sus salvedades están en la página de benchmarks.
Míralo trabajar
Cada llamada a herramienta ocurre a la vista — la herramienta, sus argumentos, su resultado — y puedes guiar a Dulus antes de que dé el siguiente paso.
Dijiste
El test de renovación de sesión está fallando. Averigua por qué y arréglalo.
src/auth/session.py:43: def refresh(self, refresh_token: str): src/auth/session.py:44: session = self.db.get(refresh_token) src/auth/session.py:58:def new_refresh_token() -> str: src/api/routes.py:88: return sessions.refresh(body.refresh_token)
FAILED tests/test_session.py::test_refresh_rotates_token E AssertionError: token not rotated 1 failed, 3 passed in 0.41s
Dijiste, mientras Dulus trabajaba
Registra también cuando un token expire.
Dalo por hecho. El fallo es real: refresh() devuelve la sesión con su refresh token viejo, así que el token nunca se rota.
@@ -44,5 +44,8 @@ def refresh(self, refresh_token: str): session = self.db.get(refresh_token) if session.expired: - raise SessionExpired() + log.info("token expired: session %s", session.id) + raise SessionExpired(session.id) + session.refresh_token = new_refresh_token() + self.db.rotate(refresh_token, session) session.expires_at = now() + SESSION_TTL return session
.............. [100%] 14 passed in 1.12s
Arreglado. El test detectó un bug real: refresh() nunca emitía un refresh token nuevo.
Pasan los 14 tests, y guardé un checkpoint del archivo antes de editarlo.
Dijiste
¿Postgres o SQLite para el estado del motor de sincronización? Quiero que esto se debata como se debe.
Table convened with 3 members on: sync engine storage A dulus-x-397b B claude (your key) C gemini (your key)
SQLite en cada dispositivo: un solo archivo, nada que levantar, y las lecturas se quedan locales y rápidas. Del servidor de sincronización no estoy tan seguro.
A tiene razón en lo del dispositivo. El servidor es otra cosa: muchos dispositivos escriben a la vez, y eso es trabajo para Postgres.
De acuerdo con los dos. Hay que mantener un solo esquema para las dos bases y correr los tests de conflictos contra cada una, o van a terminar divergiendo.
Recomendación: SQLite en cada dispositivo, Postgres en el servidor de sincronización. A y B coinciden en esa división, y lo que dice B sobre las escrituras concurrentes zanja lo del servidor. La advertencia de C es el verdadero trabajo: un esquema, dos migraciones, tests de conflictos en ambas. ¿Quieres que te prepare un borrador del esquema?
Dijiste
Tengo abierto el PDF del recibo de Descargas al lado del formulario de gastos. Revisa que coincidan y luego envíalo.
Screen grounded: 23 text elements | logical 1920x1080 ( 214, 188) conf=0.99 'Receipt #0412' ( 236, 402) conf=0.98 'Total RD$ 2,350.00' ( 652, 318) conf=0.99 'Amount 2,350.00' ( 662, 372) conf=0.97 'Date 14 Oct 2026' ( 812, 604) conf=0.99 'Submit'
Coinciden: RD$ 2,350.00, con fecha del 14 de octubre de 2026. Voy a enviar el formulario.
( 760, 640) conf=0.99 'Expense submitted'
Listo. El formulario coincidía con el recibo y ya está enviado — la pantalla ahora dice “Expense submitted”.
Dijiste
¿A cuánto están el USD/DOP y el BTC ahora mismo? Con fuentes, por favor.
USD/DOP [yahoo:USDDOP=X] = 60 DOP source: https://finance.yahoo.com/quote/USDDOP=X
BTC/USDT [binance:BTCUSDT] = 100,000 USDT source: https://www.binance.com/en/trade/BTC_USDT?type=spot
Consulté los dos en vivo hace un momento, cada uno con la página de donde salió. ¿Quieres que le dé seguimiento a alguno?
Dijiste
/verify yahoo USDDOP=X 60 1%
Ejecuciones de ejemplo con guion, recreadas a partir de la app de escritorio. Los nombres de archivo y las cifras son ilustrativos.
Escribe mientras Dulus trabaja. Lee tu mensaje antes de su siguiente paso, y lo que no alcance a leer vuelve a tu cuadro de texto.
Cada llamada muestra la herramienta, sus argumentos y su resultado mientras se ejecuta: Grep, Bash, Edit e incluso ScreenClick.
Antes de cada Write y Edit se guarda una instantánea de los archivos, así que /checkpoint puede restaurar los archivos, la conversación o ambos.
Anatomía de un agente
Siete partes, siete oficios — desde el pico que ejecuta tus herramientas hasta el canto que te contesta.
En vuelo, vista lateral
Siete partes, un agente
Lee, escribe y ejecuta.
Read, Write, Edit, Glob, Grep, notebooks y diagnósticos (pyright, mypy, flake8, tsc, shellcheck).Bash para una shell de verdad, y git: status, diff y log.WebFetch y WebSearch — unas 80 herramientas integradas.Usa la computadora con OCR — sin tokens de modelos de visión.
ScreenGround lee cada elemento de texto en tu pantalla, con coordenadas listas para hacer clic.ScreenClick hace clic por texto en pantalla o por x,y, en Windows y macOS.dulus-vl-72b.Cuando una sola mente no basta.
/mesa convoca una Mesa Redonda: de 2 a 26 asientos, cada uno un agente completo con su propio modelo, hablando entre sí a mitad del turno. Dulus preside.Ediciones precisas — cada una con su marcha atrás.
Write y Edit; /checkpoint restaura la conversación, los archivos o ambos./undo deshace el último turno. /fork bifurca la sesión en cualquier turno.auto, manual, accept-all y plan. En auto, todo lo que cambie algo pide permiso primero.Plumas nuevas, cada vez que el trabajo las pida.
SKILL.md) del marketplace oficial de Anthropic, skills.sh y más: el Skills Market busca entre decenas de miles./plugin install name@git_url.Recuerda — en archivos que puedes leer.
/memory consolidate extrae los aprendizajes de largo plazo.Te contesta — en español dominicano, a menos que le digas otra cosa.
/voice, /tts y una palabra de activación, “hey Dulus”./lang cambia entre 34 idiomas — o a uno que describas libremente, como “inglés británico formal”.Cualquier modelo
Trae tus propias claves, corre modelos locales o usa los modelos alojados por Dulus con Fuel — y cambia cuando quieras con /model. Cuando una sola opinión no basta, sienta a varios en una Mesa Redonda.
Ronda de ejemplo
La pregunta
BAnthropictu clave
Hay que perfilarlo antes de que alguien abra un archivo .rs. Mi apuesta: las inserciones, no el parseo.
DDeepSeektu clave
Misma apuesta que B: un INSERT por fila. Mejor en lotes, mil por transacción.
CGeminitu clave
D arregla las escrituras. Las lecturas están peor: el archivo entero se carga en memoria antes de la primera fila. Hay que leerlo en streaming.
EKimitu clave
C tiene razón, y es una sola línea: csv.reader ya hace streaming. El código lo envuelve en list().
FOllamalocal
Corrí el perfilado de B en esta máquina: primero las inserciones, y el parseo muy por detrás. Python no es el cuello de botella.
Adulus-x-397bAlojado por Dulus
Los números de F lo deciden: dos arreglos pequeños, no una reescritura. Dejemos Rust para el día en que un perfilado lo pida.
Moderador — síntesis: nada de reescribir. Leer las filas en streaming (C, E), agrupar las inserciones en lotes (D) y volver a correr el perfilado de B antes y después (F). Rust espera a que un perfilado lo pida (A).
/mesa convene …, /roundtable o la pestaña Round Table de la app.Un modelo puede venir de tres lugares. Combínalos como quieras — incluso en una misma mesa.
Usa la clave de un proveedor que ya pagas. Dulus no te cobra nada.
Vertex AI entra con tu sesión de gcloud; AMD apunta a tu propio servidor vLLM.
Corre un modelo en tu propio hardware. Dulus no te cobra nada.
localhost:11434localhost:1234llama-server :8080/v1/model ollama/qwen2.5-coder
Model set to ollama/qwen2.5-coder
Se paga por token en Fuel. Los tokens en caché son gratis, y una llamada fallida se reembolsa completa.
dulus-a-9brápido y barato1×dulus-b-27bequilibrado2×dulus-coder-30b2×dulus-vl-72bvisión3×dulus-x-397bel grandote4×dulus-free-9b dulus-free-7b dulus-free-20b0×0× es el nivel gratis para holders: 40 mensajes cada 24 horas mientras mantengas al menos 1,000,000 $DULUS como Fuel en tu saldo de Dulus — se conservan, nunca se gastan.
$DULUS es un token de utilidad y comunidad que se usa para pagar Fuel en Dulus. Nada en este sitio es asesoría financiera.
/thinking 0–4
Cada familia de modelos expresa el razonamiento a su manera — aquí un presupuesto de tokens, allá una palabra de esfuerzo. Tú mueves un solo dial; Dulus traduce el nivel para el modelo que esté respondiendo.
/thinking debug muestra toda la escala de 0 a 4 para el modelo que estés usando.
Apagado. No se pide razonamiento. Un modelo que no lo puede apagar recibe su nivel más bajo.
Lo que se envía
thinking no se envíaenable_thinking: falsereasoning_effort: "none"Una pasada ligera. Un presupuesto pequeño para trabajo rápido y sencillo.
Lo que se envía
budget_tokens: 2048thinking_budget: 2048reasoning_effort: "medium"redondeado al alzaEquilibrado. Espacio para pensar, sin hacerte esperar mucho.
Lo que se envía
budget_tokens: 6000thinking_budget: 8192reasoning_effort: "medium"Profundo — el nivel por defecto. Tiempo para pensarlo bien antes de responder.
Lo que se envía
budget_tokens: 16000thinking_budget: 16384reasoning_effort: "medium"llega al topeEl techo, esté donde esté para cada familia.
Lo que se envía
budget_tokens: 32000thinking_budget: 32768reasoning_effort: "medium"llega al topeSi una familia no tiene un nivel equivalente, Dulus envía el más cercano que acepte.
Fuel
Los modelos alojados por Dulus funcionan con Fuel, y 1 Fuel = 1 $DULUS. Puedes seguir cada unidad desde tu depósito hasta el encabezado de la respuesta.
POST /v1/chat/completions
Cifras ilustrativas. Cada paso es real.
Depósito
Envía $DULUS en Solana a tu dirección de depósito personal.
Libro mayor
Se acredita una vez por transacción, más un bono del 1% en Fuel. El saldo nunca queda en negativo.
Clave
Genera una clave de API en la app de escritorio. Solo se te muestra una vez.
Reserva
Cada llamada de pago reserva primero un tope, de forma atómica. Sin Fuel, no hay llamada.
Ejecución
El modelo alojado se ejecuta. Se cuentan sus tokens de entrada, salida y razonamiento.
Liquidación
Se cobra por los tokens reales. Lo que sobra de la reserva se devuelve, y una llamada fallida se reembolsa.
Dirección del mint
$DULUS es un token de utilidad y comunidad que se usa para pagar Fuel en Dulus. Nada en este sitio es asesoría financiera.
Memoria y control
Dulus mantiene su contexto ligero, lo compacta cuando la caché del proveedor ya se enfrió de todos modos, y escribe lo que aprende en archivos markdown que puedes abrir. Mientras trabaja, puedes guiarlo, aprobar sus pasos, rebobinarlo o ponerle límites.
01Memoria y contexto
En cada turno, Dulus decide qué ve el modelo. Lo que se gana su lugar entra; lo demás se queda local, a una llamada de distancia.
Ventana de contexto 62%49%26% / 128K
Caché del prompt 1h TTL
sigue
[cache: 1h 12m idle > 1h TTL — cached prompt expired; this turn re-writes the prefix at write price (re-grounding + compacting now so it is paid once)]
70%
La capa 1 recorta las salidas viejas de las herramientas sin llamar a un modelo. Antes de que la capa 2 resuma los turnos anteriores, Dulus guarda un checkpoint al que puedes volver.
1h TTL
La caché del prompt de un proveedor se enfría pasado un tiempo: una hora, por defecto. Dulus sabe cuándo pasó y compacta justo en ese momento, porque la reescritura de la caché ya se está pagando.
Loopback
Solo se envían los últimos N turnos. El historial completo se queda local, y el modelo lo consulta cuando lo necesita.
Loopback(action="search", query="token expiry")
Las memorias son archivos markdown con un poco de frontmatter: unas para ti, otras para cada proyecto, y un índice que Dulus mantiene al día. Léelas, edítalas, abre la carpeta en Obsidian.
user, feedback, project o referenceuser_prefers_spanish.md
Gold · cargada al iniciar
--- type: user gold: true ---
Prefiere respuestas en español. El código y los mensajes de commit, en inglés.
project_payments.md
0.74 en contexto
--- type: project created: 2026-10-02 ---
Los webhooks pasan a /v2 el 2026-11-03. Mantén /v1 activo hasta entonces.
feedback_tests_first.md
0.41 en contexto
--- type: feedback created: 2026-09-18 ---
Primero escribe el test que falla, luego el arreglo. Por qué: dos regresiones llegaron a producción sin test.
reference_release_wiki.md
0.06 bajo el umbral
--- type: reference created: 2026-08-30 ---
Checklist de releases: wiki del equipo → Ingeniería → Releases.
02Control
Autonomía con límites claros. Tú los pones; Dulus trabaja dentro de ellos.
Tú, a mitad del turno
también registra cuando expire un token
Guiar a Dulus Lo lee antes de su siguiente paso.
también registra cuando expire un token
En colaEntregado
Escribe mientras Dulus trabaja. Lee tu mensaje antes de su siguiente paso, y lo que no alcance a leer vuelve a tu cuadro de texto.
Bashrm -rf build/
Allow: Bash(rm -rf build/) [y/N/a(ccept-all)]
autoEl modo por defecto. Las lecturas y los comandos seguros se ejecutan sin preguntar; todo lo que cambie algo pide permiso.manualCada llamada a herramienta pide permiso primero.accept-allNada pide permiso. Para cuando lo tienes claro.planSolo lectura. Dulus planifica; nada cambia.Elige cuánto puede hacer Dulus por su cuenta. Lo que no hayas permitido espera tu y: en la app, en la terminal o en Telegram.
Antes de cada Write y cada Edit, se guarda una instantánea de los archivos. /checkpoint restaura la conversación, los archivos o ambos; /fork bifurca una sesión en cualquier turno y /undo deshace el último.
Los cambios hechos con Bash no quedan en los checkpoints.
/budget tokens 200000
/budget tool_calls 300
tokens128,400 / 200,000
tool_calls96 / 300
/isolate on
Isolate: ON — writes locked to ~/code/payments
Registro de auditoría Write · Edit · Bash · ScreenClick
/budget pone un tope a los tokens y a las llamadas a herramientas de una sesión. /isolate restringe las escrituras al espacio de trabajo, en la medida de lo posible. Cada Write, Edit, Bash y ScreenClick queda en un registro de auditoría.
Donde trabajes
Un solo agente en tu ventana, tu shell, tu pestaña del navegador y tu bolsillo. Y crece con cada servidor, skill y plugin que le des.
La CLI viene dentro de la app: un clic abre dulus en una terminal de verdad, con el agente completo, el banner, los temas y el pajarito girando incluidos. La edición de código abierto la lleva a macOS, Linux, WSL y Termux.
Sesión de terminal de ejemplo: dulus imprime su banner de naranja a dorado. /model dulus/dulus-b-27b cambia el modelo; ante “arregla el test de login inestable” lee un archivo, corre un comando y su spinner dice “Afilando las garras en el AST…”.
Escribe mientras trabaja: leerá tu mensaje antes de su siguiente paso. Su navegador y su terminal corren en paneles que puedes mirar.
Ejemplo: la app de escritorio de Dulus con su barra lateral, una llamada a la herramienta Bash que ejecuta npm test, un mensaje para guiarlo que espera a ser leído antes del siguiente paso, y paneles laterales con el navegador en vivo y la terminal.
/webchat lan on — la misma sesión en el navegador de tu celular, por tu Wi-Fi.
Ejemplo: el navegador de un celular abierto en la dirección local de la computadora, con Dulus WebChat. Preguntas si ya terminaron los tests; Dulus responde que pasan los doce y que está escribiendo la línea del changelog.
Mándale fotos y notas de voz, y responde a sus solicitudes de permiso sin tener que volver a la computadora.
Ejemplo de chat de Telegram con el bot de Dulus: envías una nota de voz de cuatro segundos, Dulus la transcribe y pide permiso con “Allow: Bash(npm test)”; respondes “y”, y reporta que pasan doce tests.
Astral Voice responde en voz alta, frase por frase; para interrumpir, basta con hablar. La CLI tiene /voice, /tts y una palabra de activación.
Ejemplo: Astral Voice está hablando cuando interrumpes con “Espera, primero revisa staging”. Se detiene y escucha.
Vive en tu escritorio y se encarga de los trabajos largos —revisiones de seguridad, adaptaciones de repos— para que tu chat quede libre. Un mini Dulus por cada subagente en marcha.
Ejemplo: la mascota de Dulus está en el escritorio con un globo de diálogo que dice “listo”. En el borde derecho, tres mascotas pequeñas muestran subagentes: coder lleva 42 segundos en Edit, tester lleva 18 segundos en Bash y reviewer terminó a los 63 segundos.
Miles de servidores MCP, con la opción de una revisión de seguridad antes de cada instalación. Decenas de miles de skills. Plugins que se recargan en caliente, y AutoAdapter convierte un repo de Python en herramientas.
Ejemplo: tres tarjetas del marketplace —un plugin, la skill pdf y el servidor MCP postgres, con un botón Install y una revisión de seguridad ofrecida primero— junto a los comandos /mcp search, /plugin install name@git_url, /autoadapter y /lucky.
/sandbox abre un escritorio en tu navegador: decenas de apps, desde una terminal hasta el ajedrez. Su IA corre en modelos alojados por Dulus.
Ejemplo: una pestaña del navegador con Dulus OS, un escritorio con íconos de apps (terminal, VS Code, archivos, hoja de cálculo, notas, música, Fuel Wallet y ajedrez), una ventana de chat que responde con un modelo alojado por Dulus, una partida de ajedrez abierta y un dock.
-p ejecuta un prompt y termina. --output json emite eventos JSONL, y el código de salida le dice a tu CI cómo le fue.
Ejemplo: dulus -p --accept-all --output json -- "add a test" imprime tres líneas JSONL —step_start, text y step_finish con el uso de tokens— y termina con código 0. Luego, dulus -p "write the release notes" > NOTES.md guarda una respuesta en texto plano en un archivo.
App de escritorio para Windows 10 o posterior. La CLI necesita Python 3.11+. En las dos inicias sesión con una cuenta gratis de Dulus. Todas las descargas
Por qué un pájaro
El ave nacional de la República Dominicana es la cigua palmera, Dulus dominicus. Solo vive en La Española y es la única especie de su familia.
Las ciguas palmeras viven en bandadas. Juntas levantan un gran nido de ramitas, uno solo, en lo alto de las palmas reales, y adentro cada pareja tiene su propia cámara, con su propia entrada.
Un sistema multiagente en plena naturaleza:
muchas mentes, un solo nido,
cada quien con su cuarto.
Hecho en Santo Domingo 18°28′N 69°53′W
Dulus nace de la misma manera. Un humano, Kevin Rojo, marca el rumbo; una bandada de agentes hace el trabajo. El producto se construye tal como trabaja.
Por el pájaro, no por el cohete.
Únete a la bandada
Gratis para descargar. Trae tus propias claves, corre un modelo local o carga los alojados con $DULUS.