Hosted models, paid in $DULUS Fuel

One agent. Made of many.

Dulus is an AI agent for your desktop and terminal. It works in your files, your shell, your browser and your screen — on any model you choose. And when one mind isn’t enough, it calls the flock.

  • No Python needed
  • Your keys, local models, or Dulus-hosted
  • Built in Santo Domingo

Runs on the models you already use

  • Anthropic
  • OpenAI
  • Google Gemini
  • DeepSeek
  • Moonshot Kimi
  • Qwen
  • Z.ai GLM
  • Perplexity
  • MiniMax
  • NVIDIA NIM
  • Azure OpenAI
  • Amazon Bedrock
  • Cloudflare Workers AI
  • Vertex AI
  • Ollama
  • LM Studio
  • llama.cpp
  • Dulus-hosted

Measured, not claimed

The agent that costs least to run. Measured.

Six coding sessions, from an 8-turn fix to a 120-turn audit, replayed against Claude Code, Cursor, Codex CLI, Cline, Aider and GitHub Copilot: same transcript, same tokenizer, same prices. Dulus came first under all five ways we weighed the results.

  • $25.63 for all six sessions Claude Code: $48.00. Cursor: $50.75. GitHub Copilot: $373.53.
  • 9 times the cached prompt was rewritten Claude Code 74, Cursor 88, Cline 102. Every rewrite bills tokens already sent at full price.
  • 0 context overflows Its peak was 139.8k tokens of a 200k window, in sessions up to 120 turns long.
  • 70.4% from the cache, on our own bill 155.7M input tokens in one week of building with Dulus, October 12–18, 2026.

A cache that holds

The history window only moves when that saves more than the cache would. Earlier images and reasoning stay where they were, so the cached prompt isn’t rewritten.

Lookback and Loopback

The model gets the recent turns; the whole conversation stays on your machine. When it needs something older, Dulus searches it with its own Loopback tool.

A Python console for the model

A persistent Python kernel keeps big data in memory instead of in the conversation. Only what it prints reaches the context.

MemPalace

Memory you can open: markdown in a palace of halls. The essentials load every session, and each turn brings back up to three relevant memories.

Dulus was measured running its own context code. The other agents are modelled from how each one manages its context, not run from their source. The method and its caveats are on the benchmarks page.

Watch it work

Ask once. Watch it work.

Every tool call happens in the open — the tool, its arguments, its result — and you can steer Dulus before it takes the next step.

Fix a failing test

You said

The session refresh test is failing. Find out why and fix it.

DULUS
Thinking Find where refresh tokens are handled, reproduce the failure, then fix the cause, not the test.
Grep "refresh_token" src/ 4 matches running…
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)
Read src/auth/session.py 71 lines running…
Bash pytest -q tests/test_session.py 1 failed, 3 passed running…
FAILED tests/test_session.py::test_refresh_rotates_token
E       AssertionError: token not rotated
1 failed, 3 passed in 0.41s

You said, while Dulus was working

Also log when a token expires.

Will do. The failure is real: refresh() hands back the session with its old refresh token, so the token is never rotated.

Checkpoint saved src/auth/session.py · before Edit
Edit src/auth/session.py +4 −1 running…
@@ -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
Bash pytest -q 14 passed running…
..............                           [100%]
14 passed in 1.12s

Fixed. The test caught a real bug: refresh() never issued a new refresh token.

  • Each refresh now rotates the token and retires the old one.
  • Expired tokens are logged with their session id.

All 14 tests pass, and the file was checkpointed before the edit.

Convene a Mesa Redonda

You said

Postgres or SQLite for the sync engine’s state? I want this one argued properly.

DULUS
Thinking A real trade-off, so one opinion is not enough. Seat three different models, then weigh what they say.
RoundTable convene seats=3 3 members running…
Table convened with 3 members on: sync engine storage
  A  dulus-x-397b
  B  claude (your key)
  C  gemini (your key)
RoundTable ask sent to 3 seats running…
Mesa Redonda sync engine storage 3 seats
Adulus-x-397b

SQLite on each device: one file, nothing to run, and reads stay local and fast. I am less sure about the sync server.

Bclaude (your key)

A is right about the device. The server is different: many devices write at once, and that is Postgres work.

Cgemini (your key)

Agree with both. Keep one schema for the two stores and run the conflict tests against each, or they will drift.

Recommendation: SQLite on each device, Postgres on the sync server. A and B agree on the split, and B’s point about concurrent writers settles the server. C’s caveat is the real work: one schema, two migrations, conflict tests on both. Want me to draft the schema?

Use the computer

You said

The receipt PDF from Downloads is open next to the expense form. Check they match, then submit it.

DULUS
Thinking Read the screen first, compare the receipt with the form, and ask before clicking.
ScreenGround 23 text elements running…
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'

They match: RD$ 2,350.00, dated 14 Oct 2026. Submitting the form.

Allow: ScreenClick "Submit" at (812, 604)? [y/N/a] y · allowed once
ScreenClick text="Submit" Left-clicked 'Submit' at (812,604). running…
ScreenGround filter="submitted" 1 match running…
  ( 760, 640) conf=0.99  'Expense submitted'

Done. The form matched the receipt and it is submitted — the screen now says “Expense submitted”.

Live figures, with sources

You said

What are USD/DOP and BTC at right now? With sources, please.

DULUS
Thinking Fetch both live, in parallel. Never quote a price from memory.
LiveFeed yahoo USDDOP=X 60 DOP running…
USD/DOP [yahoo:USDDOP=X] = 60 DOP
source: https://finance.yahoo.com/quote/USDDOP=X
LiveFeed binance BTCUSDT 100,000 USDT running…
BTC/USDT [binance:BTCUSDT] = 100,000 USDT
source: https://www.binance.com/en/trade/BTC_USDT?type=spot
  • USD/DOP 60 — finance.yahoo.com
  • BTC/USDT 100,000 — binance.com

Both fetched live a moment ago, each with the page it came from. Want me to keep an eye on either?

You said

/verify yahoo USDDOP=X 60 1%

60 matches the live figure (0.00% off, tolerance 1%) USD/DOP [yahoo:USDDOP=X] = 60 DOP source: https://finance.yahoo.com/quote/USDDOP=X

Scripted example runs, drawn from the desktop app. File names and figures are illustrative.

  • Steer it mid-turn

    Type while Dulus works. It reads your message before its next step, and anything it didn’t get to comes back to your composer.

  • Every tool call in the open

    Each call shows the tool, its arguments and its result as it runs — Grep, Bash, Edit, even ScreenClick.

  • A checkpoint before every edit

    Files are snapshotted before each Write and Edit, so /checkpoint can restore the files, the conversation, or both.

Anatomy of an agent

Every part of the bird has a job.

Seven parts, seven jobs — from the beak that runs your tools to the song that talks back.

Pl. VII Dulus dominicus

In flight, lateral view

Seven parts, one agent

The golden Dulus bird in flight, drawn as a field-guide plate with seven numbered parts: beak, eye, wings, talons, plumage, heart and song.

Beak Tools

It reads, writes and runs.

  • Files and code: Read, Write, Edit, Glob, Grep, notebooks, and diagnostics (pyright, mypy, flake8, tsc, shellcheck).
  • Bash for a real shell, and git: status, diff and log.
  • A persistent Python kernel whose variables survive between calls.
  • WebFetch and WebSearch — about 80 tools, built in.

Eye Sight

Computer use by OCR — no vision-model tokens.

  • ScreenGround reads every text element on your screen, with click-ready coordinates.
  • ScreenClick clicks by on-screen text or by x,y, on Windows and macOS.
  • WebDrive: a real Chromium browser — navigate, click, type, extract — whose logins persist, mirrored live in the desktop app.
  • Send it a photo over Telegram, or pick a vision model such as dulus-vl-72b.

Wings The flock

When one mind isn’t enough.

  • Sub-agents run in the background: general-purpose, coder, reviewer, researcher, tester — or your own type, from a markdown file.
  • Optional git-worktree isolation. Up to 3 at once, nested up to 3 deep.
  • /mesa convenes a Mesa Redonda: 2–26 seats, each a full agent on its own model, talking to each other mid-turn. Dulus chairs.
  • Dulus can call a table on its own, and wakes when every seat has answered.

Talons Grip

Precise edits — and a way back from each one.

  • A checkpoint before every Write and Edit; /checkpoint restores the conversation, the files, or both.
  • /undo takes back the last turn. /fork branches the session at any turn.
  • Permission modes auto, manual, accept-all and plan. In auto, anything that changes things asks first.
  • An audit trail of every Write, Edit, Bash and ScreenClick. Changes made through Bash aren’t snapshotted.

Plumage Extensions

New feathers, whenever the job needs them.

  • An MCP market in the app — thousands of servers (stdio, SSE, HTTP), with a security review offered before every install.
  • Skills (SKILL.md) from the official Anthropic marketplace, skills.sh and more: the Skills Market searches tens of thousands.
  • Plugins add tools, skills and MCP configs with hot reload: /plugin install name@git_url.
  • AutoAdapter turns a Python repo into native, smoke-tested tools. Tool packs switch on and off live, each showing its token cost.

Heart Memory

It remembers — in files you can read.

  • Memories are markdown files, per user and per project, typed and auto-indexed. Obsidian-friendly.
  • Each turn recalls up to 3 relevant memories; gold memories load at startup.
  • /memory consolidate extracts the long-term insights.
  • The cache clock knows when the provider’s prompt cache has gone cold, and compacts exactly then — when the rewrite is already paid for.

Song Voice

It talks back — in Dominican Spanish, unless you say otherwise.

  • Astral Voice in the desktop app: hands-free conversation with spoken replies. Interrupt it just by talking.
  • In the CLI: /voice, /tts and a wake word, “hey Dulus”.
  • Voice notes work over the Telegram bridge too.
  • /lang switches among 34 languages — or free-form, like “formal British English”.

Any model

Every model at one table.

Bring your own keys, run local models, or use Dulus-hosted models on Fuel — and switch any time with /model. When one opinion isn’t enough, seat several at a Mesa Redonda.

Example round

Six seats, one chair

The question

Should we rewrite the CSV importer in Rust?

  1. BAnthropicyour key

    Profile it before anyone opens a .rs file. My bet: the inserts, not the parsing.

  2. DDeepSeekyour key

    Same bet as B: one INSERT per row. Batch them, a thousand per transaction.

  3. CGeminiyour key

    D fixes the writes. The reads are worse: the whole file sits in memory before row one. Stream it.

  4. EKimiyour key

    C is right, and it’s one line: csv.reader already streams. The code wraps it in list().

  5. FOllamalocal

    Ran B’s profile on this machine: inserts first, parsing a distant second. Python isn’t the bottleneck.

  6. Adulus-x-397bDulus-hosted

    F’s numbers settle it: two small fixes, not a rewrite. Keep Rust for the day a profile asks for it.

  7. Chair — synthesis: no rewrite. Stream the rows (C, E), batch the inserts (D), and rerun B’s profile before and after (F). Rust waits for a profile that asks for it (A).

  • 2–26 seatsEach one a full agent, with its own model, history and mailbox.
  • Dulus chairsIt never takes a seat. It can convene a table on its own, and is woken when every seat has answered.
  • 3 tables at onceUp to three can run at the same time.
  • Convene one/mesa convene …, /roundtable or the Round Table tab in the app.

Three places a model can come from. Mix them freely — even at one table.

Your keys

Use a key from a provider you already pay. Costs nothing from Dulus.

  • Anthropic
  • OpenAI
  • Google Gemini
  • Vertex AI
  • DeepSeek
  • Moonshot Kimi
  • Qwen / Model Studio
  • Z.ai GLM
  • Perplexity
  • MiniMax
  • NVIDIA NIM
  • Xiaomi
  • Sakana
  • Meta
  • Azure OpenAI
  • Amazon Bedrock
  • Cloudflare Workers AI
  • AMD

Vertex AI signs in with your gcloud login; AMD points at your own vLLM server.

Local

Run a model on your own hardware. Costs nothing from Dulus.

  • Ollamalocalhost:11434
  • LM Studiolocalhost:1234
  • llama.cppllama-server :8080
  • Any OpenAI-compatible server/v1

/model ollama/qwen2.5-coder

Model set to ollama/qwen2.5-coder

Dulus-hosted

Paid per token in Fuel. Cached tokens are free, and a failed call is refunded in full.

  • dulus-a-9bfast and cheap1×
  • dulus-b-27bbalanced2×
  • dulus-coder-30b2×
  • dulus-vl-72bvision3×
  • dulus-x-397bthe big one4×
  • dulus-free-9b dulus-free-7b dulus-free-20b0×
See all hosted models

0× is the holder free tier: 40 messages every 24 hours while you keep at least 1,000,000 $DULUS as Fuel in your Dulus balance — held, never spent.

$DULUS is a utility and community token used to pay for Fuel on Dulus. Nothing on this site is financial advice.

/thinking 0–4

One reasoning dial.

Every model family spells reasoning its own way — a token budget here, an effort word there. You turn one dial; Dulus translates the level for whichever model is answering.

/thinking debug prints the whole 0–4 ladder for the model you’re on.

Off. No reasoning asked for. A model that can’t switch it off gets its lowest setting.

On the wire

  • Claudethinking not sent
  • Qwenenable_thinking: false
  • DeepSeekreasoning_effort: "none"

A light pass. A small budget for quick, simple work.

On the wire

  • Claudebudget_tokens: 2048
  • Qwenthinking_budget: 2048
  • DeepSeekreasoning_effort: "medium"rounded up

Balanced. Room to think, without a long wait.

On the wire

  • Claudebudget_tokens: 6000
  • Qwenthinking_budget: 8192
  • DeepSeekreasoning_effort: "medium"

Deep — the default. Time to think it through before answering.

On the wire

  • Claudebudget_tokens: 16000
  • Qwenthinking_budget: 16384
  • DeepSeekreasoning_effort: "medium"tops out

The ceiling, wherever each family puts it.

On the wire

  • Claudebudget_tokens: 32000
  • Qwenthinking_budget: 32768
  • DeepSeekreasoning_effort: "medium"tops out

Where a family has no matching level, Dulus sends the nearest one it accepts.

Fuel

AI you can audit to the token.

Dulus-hosted models run on Fuel, and 1 Fuel = 1 $DULUS. You can follow every unit from your deposit to the header on the response.

Example call POST /v1/chat/completions Illustrative numbers. Every step is real.
  1. Deposit

    Send $DULUS on Solana to your personal deposit address.

    • + 2,000,000 $DULUS
    • → your deposit address
    • on Solana
  2. Ledger

    Credited once per transaction, plus a 1% Fuel bonus. The balance never goes negative.

    • + 2,000,000 Fuel
    • + 20,000 bonus · 1%
    • balance never < 0
  3. Key

    Mint an API key in the desktop app. It is shown to you once.

    • dulus_sk_live_••••••
    • shown once
    • stored as SHA-256
  4. Reserve

    Every paid call first holds an upper bound, atomically. No Fuel, no call.

    • hold = upper bound
    • taken atomically
    • no Fuel → HTTP 402
  5. Run

    The hosted model runs. Its input, output and reasoning tokens are counted.

    • dulus-b-27b · 2×
    • in 1,204 · out 388
    • reasoning 96
    • cached 2,048
  6. Settle

    Billed on actual tokens. The rest of the hold comes back; a failed call is refunded.

    • billed 1,688 tokens
    • cached 2,048 → free
    • unused hold → returned
    • X-Dulus-Fuel-Charged: …
  • 1 Fuel = 1 $DULUS Every $DULUS you deposit is credited as one Fuel.
  • 0 Fuel for cached tokens You pay for input, output and reasoning tokens. Cached ones are free.
  • 100% refunded when a call fails The whole hold goes back to your balance.
  • 40 free messages a day Hold 1,000,000 $DULUS as Fuel to use dulus-free-9b, dulus-free-7b and dulus-free-20b, up to 2,048 output tokens each. The balance is held, never spent.

$DULUS on Solana

  • Token-2022
  • 6 decimals

Mint address

9R8rrjXxcfQPmLTCLhmVpjr2uesjjkcgkinE6Lwdpump

$DULUS is a utility and community token used to pay for Fuel on Dulus. Nothing on this site is financial advice.

Memory & control

It remembers on purpose. You stay at the controls.

Dulus keeps its context lean, compacts it when the provider’s cache has gone cold anyway, and writes what it learns to markdown you can open. While it works, you can steer it, approve it, rewind it or cap it.

01Memory & context

Context, engineered.

Every turn, Dulus decides what the model sees. What earns its place goes in; the rest stays local, one call away.

Example, sped up: the context window is 62% full when the provider’s prompt cache goes cold after an hour without calls. On the next turn Dulus prunes old tool results without calling a model, saves a pre-compact checkpoint, summarizes the older turns and writes the smaller prompt once. The window drops to 26%.

Context window 62%49%26% / 128K

Example Shown at 500 times speed

Prompt cache 1h TTL

  • System prompt 15.4K cachedexpired
  • Memories ×3 4.6K recalled
  • Conversation 28.2K9.0K summarized
  • Tool results 30.7K14.1K3.8K pruned

keep going

[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)]

  1. Cache cold1h 12m idle, past the 1h TTL
  2. Layer 1Old tool results pruned, no LLM call
  3. CheckpointSaved before summarizingRoll back
  4. Layer 2Older turns summarized
  5. Re-cachedOne prefix write instead of two

70%

Auto-compact

Layer 1 prunes old tool results without calling a model. Before layer 2 summarizes older turns, Dulus saves a checkpoint you can roll back to.

1h TTL

A clock on the cache

A provider’s prompt cache goes cold after a while — an hour, by default. Dulus knows when it has, and compacts exactly then, because the rewrite is already being paid for.

Loopback

The archive stays local

Only the last N turns are sent. The full archive stays local, and the model fetches from it on demand.

Loopback(action="search", query="token expiry")

Memory you can read.

Memories are markdown files with a little frontmatter — one set for you, one per project, and an index Dulus keeps current. Read them, edit them, open the folder in Obsidian.

type
user, feedback, project or reference
Recall
Up to 3 per turn, and only above a relevance floor
gold: true
Loads at startup, every session
/memory consolidate
Pulls the long-term insights out of a session
Example turn: for “the webhook retries are failing again”, two memories score above the relevance floor and are recalled; one scores below it and stays out. The gold memory was already loaded at startup.
the webhook retries are failing again Recalled 2/3
  • user_prefers_spanish.md

    Gold · loaded at startup

    ---
    type: user
    gold: true
    ---

    Prefers replies in Spanish. Code and commit messages stay in English.

  • project_payments.md

    0.74 recalled

    ---
    type: project
    created: 2026-10-02
    ---

    Webhooks move to /v2 on 2026-11-03. Keep /v1 alive until then.

  • feedback_tests_first.md

    0.41 recalled

    ---
    type: feedback
    created: 2026-09-18
    ---

    Write the failing test before the fix. Why: two regressions shipped without one.

  • reference_release_wiki.md

    0.06 below the floor

    ---
    type: reference
    created: 2026-08-30
    ---

    Release checklist: team wiki → Engineering → Releases.

02Control

Steer, approve, rewind, cap.

Autonomy with clear limits. You set them; Dulus works inside them.

  • Edit src/auth/session.py running… +18 −4

    You, mid-turn

    also log when a token expires

    Edit src/auth/tokens.py running… +3

    Steer Dulus It reads this before its next step.

    also log when a token expires

    QueuedDelivered

    Desktop app

    Steer mid-turn

    Type while Dulus works. It reads your message before its next step, and anything it didn’t get to comes back to your composer.

  • Bashrm -rf build/

    Allow: Bash(rm -rf build/) [y/N/a(ccept-all)]

    • autoThe default. Reads and safe commands run; anything that changes things asks.
    • manualEvery tool call asks first.
    • accept-allNothing asks. For when you mean it.
    • planRead-only. Dulus plans; nothing changes.

    auto · manual · accept-all · plan

    Permission prompts

    Choose how much Dulus may do on its own. Anything you haven’t allowed waits for your y — in the app, in the terminal or on Telegram.

    1. #1“add rate limiting to /login”Edit limits.pyEdit app.py
    2. #2“use a sliding window instead”Edit limits.py
    3. #3“now write the tests”Write test_limits.py

      Rewind to here

      • Conversation + files
      • Conversation only
      • Files only
    4. #4“also log when a token expires”Edit tokens.py
    5. #5“refactor the session store”Edit session.pyEdit store.py

    /checkpoint · /fork · /undo

    Checkpoints

    Files are snapshotted before every Write and Edit. /checkpoint restores the conversation, the files, or both; /fork branches a session at any turn and /undo takes back the last one.

    Changes made through Bash aren’t tracked.

  • /budget tokens 200000

    /budget tool_calls 300

    tokens128,400 / 200,000

    tool_calls96 / 300

    /isolate on

    Isolate: ON — writes locked to ~/code/payments

    Audit trail Write · Edit · Bash · ScreenClick

    1. 14:02:11Editsrc/auth/session.py
    2. 14:02:19Bashpytest -q tests/auth
    3. 14:03:02ScreenClickRetry

    /budget · /isolate

    Budgets and guardrails

    /budget caps tokens and tool calls for a session. /isolate locks writes to the workspace, best effort. Every Write, Edit, Bash and ScreenClick lands in an audit trail.

Everywhere you work

Desktop. Terminal. Browser. Your phone.

One agent in your window, your shell, your browser tab and your pocket — and it grows with every server, skill and plugin you give it.

The CLI

The CLI comes inside the app: one click opens dulus in a real terminal — the whole agent, banner, themes and bird spinner included. The open-source edition brings it to macOS, Linux, WSL and Termux.

  • macOS
  • Linux
  • WSL
  • Termux
  • Windows

Example terminal session: dulus prints its orange-to-gold banner. /model dulus/dulus-b-27b switches the model; on “fix the flaky login test” it reads a file, runs a command, and its spinner says “Sharpening talons on the AST…”.

The desktop app

Type while it works — your message is read before its next step. Its browser and terminal run in panes you can watch.

Windows 10 or later, 64-bit. No Python needed.

Example: the Dulus desktop app with its sidebar, a Bash tool call running npm test, a steer message waiting to be read before the next step, and side panes showing the live browser and the terminal.

WebChat on your phone

/webchat lan on — the same session in your phone’s browser, over your Wi-Fi.

Example: a phone browser open on the computer’s local address, showing Dulus WebChat. You ask whether the tests are done; Dulus answers that all twelve pass and it is writing the changelog line.

The Telegram bridge

Send it photos and voice notes, and answer its permission prompts without walking back to your desk.

Example Telegram chat with the Dulus bot: you send a four-second voice note, Dulus transcribes it, asks “Allow: Bash(npm test)”, you reply “y”, and it reports that twelve tests pass.

Voice

Astral Voice answers out loud, sentence by sentence — cut in just by talking. The CLI has /voice, /tts and a wake word.

Example: Astral Voice is speaking when you interrupt with “Wait — check staging first.” It stops and listens.

The desktop pet

It lives on your desktop and runs the long jobs — security reviews, repo adaptations — so your chat stays free. One small Dulus per running sub-agent.

Example: the Dulus mascot sits on the desktop with a speech bubble that says “listo”, Spanish for ready. On the right edge, three small mascots show sub-agents: coder in Edit for 42 seconds, tester in Bash for 18 seconds, and reviewer done after 63 seconds.

Extensions

Thousands of MCP servers, with a security review offered before every install. Tens of thousands of skills. Plugins that hot-reload, and AutoAdapter turns a Python repo into tools.

Example: three market cards — a plugin, the pdf skill, and the postgres MCP server with an Install button and a security review offered first — next to the commands /mcp search, /plugin install name@git_url, /autoadapter and /lucky.

Dulus OS

/sandbox opens a desktop in your browser — dozens of apps, from a terminal to chess. Its AI runs on Dulus-hosted models.

Example: a browser tab with Dulus OS — a desktop with app icons for Terminal, VS Code, Files, Spreadsheet, Notes, Music, Fuel Wallet and Chess, a Chat window answering on a Dulus-hosted model, an open chess game, and a dock.

Scripting

-p runs one prompt and exits. --output json streams JSONL events, and the exit code tells CI how it went.

Example: dulus -p --accept-all --output json -- "add a test" prints three JSONL frames — step_start, text, and step_finish with token usage — and exits with status 0. Then dulus -p "write the release notes" > NOTES.md writes a plain answer to a file.

Desktop app for Windows 10 or later. The CLI needs Python 3.11+. Both sign in with a free Dulus account. All downloads

An engraving of a red-orange palmchat perched on a pencil, circled by a small flock in flight.
Fig. 1 Dulus dominicus — the palmchat

Why a bird

Named after a bird that builds together.

The palmchat — Dulus dominicus, la cigua palmera — is the national bird of the Dominican Republic. Found only on Hispaniola, it is the only species in its family.

Palmchats live in flocks. Together they build one great nest of twigs, high in the royal palms, and inside it every pair keeps its own chamber with its own entrance.

A multi-agent harness in the wild:
many minds, one nest,
each with its own room.

Dulus is made the same way. One human, Kevin Rojo, sets the direction; a flock of agents does the work. The product is built the way it works.

  1. Truth over hype.
  2. Verify before claiming.
  3. Leave artifacts, not promises.
  4. Reversible: act. Irreversible: ask.
  5. The human is direction, not operator.
Read the story

Named after the bird, not the rocket.

We keep flying.

Join the flock

One install. A whole flock.

Free to download. Bring your own keys, run a local model, or fuel the hosted ones with $DULUS.

esc

Actions