Fusion is one of Atomic Agent’s three run modes, next to Local and Cloud. Instead of one model doing everything, Fusion gives the job to two: an orchestrator that plans, writes a brief for each part and reviews what comes back, and workers that execute those parts, several at once.
Either seat can be a local model or a cloud model. That makes Fusion a way to pair a model on your own machine with a cloud model and get results closer to what the cloud model reaches on its own, while choosing which side does the thinking and which side does the building.
In Fusion, the orchestrator never builds anything itself. It reads your project, splits the job into self-contained parts and sends them out through a tool called fusion.delegate. Each worker takes one part, writes its files straight to disk and reports back. The orchestrator then checks the result and sends weak parts out again.
Orchestrator
Holds the conversation with you. Reads enough to choose an approach, breaks the job into parts, writes a brief for each, reviews the replies and runs checks. It cannot change files or run shell commands in your project during a Fusion turn. Its checks run in a throwaway copy.
Workers
Each worker runs one part in a fresh, throwaway session. It sees its brief and your original request, not the chat history or memory. It cannot ask you questions, request approval or delegate further.
A few details worth knowing:
There is no merge step by default. Workers write their files directly into the working directory (the optional worktree isolation changes this). The orchestrator reads what is on disk, verifies it and re-delegates anything that falls short.
Workers get your request, not just the brief. Each worker receives the orchestrator’s brief plus your original message (up to 16,000 characters), so a short brief does not leave it guessing.
The orchestrator is locked out of changes for the whole turn. Read-only tools, fusion.delegate, reply and finish are allowed. Anything that writes files, runs a shell command in your project, or comes from an MCP server is refused. This is by design: the workers build, the orchestrator judges.
Checks still run. The two check tools, verify.syntax and verify.run, count as read-only and pass the lock. verify.run can start a command, a service or a page, but only in a throwaway copy of the working directory, so writes inside that copy do not reach your project. The copy is not a sandbox: a command that writes to an absolute path can still reach your files. Like a shell command, it may ask for your approval first. See verification.
Parts can depend on each other. A fusion.delegate call can carry a contract (owners, provides, requires, checks). Tasks that need something another task provides run in a later wave, and name mismatches are caught before workers start.
Choosing a direction
Fusion runs in two directions, and which side plans and which side builds changes the result. Cloud plans with local workers is the default pairing. Local plans with cloud workers suits jobs with a lot of output, such as large code files, because the heavy writing happens on the cloud side.
This is what /runmode fusion sets up by default: a cloud model as orchestrator and your local model as the workers.
Fits when the job splits into many small, self-contained parts and you want the bulk of the execution on your own hardware.
Watch out for jobs that need a lot of generated output per part. Every line of code a worker writes comes from your local model, and parallel local workers share one GPU. For large code tasks, the reverse direction is usually the better fit.
Your local model orchestrates and cloud models execute. Switch to it with /runmode swap.
Fits when the plan is short but the output is large. A plan is a small amount of text that a local model handles well, while the long writing goes to cloud workers. In our own runs this direction reached the same level as cloud-only on a code-heavy task, where the local model alone fell well short.
Keep in mind that cloud workers see your request and the files they read, so your data does reach the cloud provider. The local orchestrator runs with a single request slot on the local server, which Atomic Agent sets automatically when the server’s slot count is left on "auto".
Two cloud models or two local models also work. Use two different providers for the two seats. The terminal app enforces this, and /runmode fusion will not put one provider in both seats. The desktop app accepts one cloud provider in both seats, but both seats then run that provider’s default chat model and escalation is off, so pick two providers there too. In both apps the managed local model can take only one seat.
Turning Fusion on
In the desktop app, pick Fusion in the composer (see In the desktop app). In the terminal app, the quickest way is from the TUI: run /runmode fusion. There you need two configured providers, usually one cloud provider with an API key and one local model that is already downloaded. Atomic Agent pins both seats, saves the mode to your config and starts the local model server if it is down.
From the TUI
/runmode open the "where it runs" switch (same as ctrl+r)
/runmode fusion switch to Fusion
/runmode swap trade the two seats (orchestrator becomes worker and back)
/runmode workers 3 set the default number of workers (1-8)
/runmode status show what the mode resolves to right now
/runmode cloud leave Fusion for Cloud
/runmode local leave Fusion for Local
The first time a session switches into Fusion, the chat shows a short introduction naming the two models it resolved. After that, /runmode status prints the orchestrator, the worker provider and how many workers can run at once.
From config.json
The mode lives under llm.runMode in <stateDir>/config.json (by default ~/.atomic-agent/config.json). These keys cannot be set with atomic-agent config set, so either use the TUI or edit the file by hand.
{
"llm": {
// "providers": [ ... ] keep your existing providers as they are
"activeTextProvider": "openrouter",
"runMode": {
"mode": "fusion",
"fusion": {
"orchestratorProvider": "openrouter",
"workerProvider": "local-llama",
"workers": 2
}
}
}
}
The provider ids must match entries in your llm.providers list. local-llama is the id Atomic Agent gives its managed local model.
All Fusion settings
Key (under llm.runMode.fusion)
Default
Range
What it does
orchestratorProvider
the active cloud provider, else the first cloud provider
a provider id
Which provider plans and reviews.
workerProvider
the first local provider that is not the orchestrator
a provider id
Which provider runs the workers.
workers
2 (a local worker seat runs 1 at a time until you set this)
1 to 8
Default fan-out width when the orchestrator does not name one.
cloudWorkers
4
1 to 32
Hard cap on parallel workers when the workers are in the cloud.
workerMaxSteps
60
1 to 1000
Step budget for one worker.
workerTimeoutMs
2,700,000 (45 min)
1,000 to 86,400,000
Time budget for one worker.
workerReasoning
provider default
low, medium, high
Reasoning effort sent with worker requests.
workerMaxOutputTokens
model maximum
1 to 1,000,000
Output cap per worker step.
reviewStallSteps
6
0 to 1000 (0 turns it off)
How long the orchestrator may only read before it is pushed to delegate or reply.
orchestratorModel, workerModel
unset
any label
Labels shown in the app and in /runmode status. The key itself changes nothing that serves. In the composer, picking a model for a local seat also switches the local model; for a cloud seat it only sets this label, and the provider’s defaultChatModel serves. To change a cloud seat’s model, change that provider’s model.
In the desktop app
The desktop app runs the same Fusion as the TUI and saves it to the same config.json. You set it up in the composer instead of with commands.
Pick Fusion. Open the Where it runs switch in the composer and choose Fusion. It is the last row, after Cloud, Local models and Custom server. When Fusion cannot start yet, the row says why, for example that it needs a second provider for the workers, and offers to add one.
Choose each role. The composer then shows two seats, Orchestrator and Worker. Each seat has its own provider control and its own model control (Orchestrator model, Worker model). For a local seat the model control picks which downloaded model runs. For a cloud seat it currently only changes the label; the provider’s default chat model serves, so set that model on the provider itself. Changing the worker never makes it the orchestrator.
Local seat. A seat on your own machine is listed as Local models (“Runs on this machine”). Its model list shows the models already downloaded (“On this machine”) and a Download more models… row.
Swap. The swap control (⇄) between the seats trades the two roles. If another model change is still landing or an approval is open, the swap is queued until it can go through. Press it again to take the queued swap back. While a turn is running, finish or stop it first.
One local model at a time. The app runs one managed local model, so it can serve only one role. The seat that does not hold it still lists Local models, greyed, with the note “Your computer runs one local model at a time, so the local engine can take only one role.” Use the swap control to move it, or pick a cloud provider for that seat.
One cloud provider in both seats. Unlike the TUI, the desktop app accepts the same cloud provider in both seats. Both seats then run that provider’s default chat model, and escalation is off, so use two providers.
While it runs. Each running worker gets a live row with the task, the model, the tool in use and the elapsed time:
Steer opens a one-line field under the row. Enter sends the note to that worker alone, and it reads it at its next step. Esc closes the field.
Stop ends that worker alone. The others carry on.
The row shows tokens and, for a priced model, the cost so far, for example 41.2k tok · $0.03.
A row is marked stuck when the worker has run at least twice its expected time and at least 3 minutes, or when the agent escalated it because it stalled or its first answer was cut off. The expected time comes from the orchestrator’s estimate, or from how long finished workers took.
The composer also accepts the /runmode commands, and /runmode status says what is resolved right now.
Not in the desktop app yet. There is no button to resume a cut-off run and no Escalate button. Use /fusion resume and /worker escalate in the TUI for those. The turn caps and the options below are set in config.json only.
How many workers run
The orchestrator decides the width of each fan-out itself. Your workers setting only fills in when it names no number. What really limits parallel workers is physical: the number of tasks, the local server’s request slots for a local worker seat, and the cloudWorkers cap for a cloud worker seat.
Local workers. Every worker needs a request slot on the local model server, and all slots share one GPU and one context pool. If the orchestrator names no width and you have not set workers yourself, local workers run one at a time. Extra tasks queue and the result tells the orchestrator how many slots there were.
Cloud workers. There are no server slots to size. A request above cloudWorkers is clamped and the result says so.
Changing the count./runmode workers N saves the default width and also sets the local server’s slot count (localModels.managed.parallel) to the same number. A server that is already running keeps its old slot count until you restart it (Manage › LLM › Local, then s).
One fusion.delegate call holds at most 16 tasks, and each brief is capped at 32,000 characters.
Verification and re-delegation
The orchestrator reviews every part before it accepts the work. It has two check tools that count as read-only, so the orchestrator lock lets them through: verify.syntax checks the syntax of the files a part produced, and verify.run runs a command, a local service or a web page in a throwaway copy of the working directory. verify.run may ask for your approval first, the same way a shell command does. Anything weak goes back out as a new, more specific brief.
What each check covers:
verify.syntax picks a checker per file type (JavaScript and JSON, TypeScript through the project’s tsc, Python, shell, HTML inline scripts, CSS brace balance). A file with no checker is reported as unchecked, never as passing.
verify.run has three kinds: command (a test runner, compiler or script), service (start it, wait for a port, send requests) and page (open a local HTML file or URL in a headless browser, collect uncaught errors, console errors and missing selectors). Writes inside the copy do not reach your real workspace, but the copy is not a sandbox: a command that writes to an absolute path can still reach your files. Network access is off by default (network: false), which is a soft block through a proxy, not a sandbox.
Re-delegation. A task that comes back failed, cancelled, needs_orchestrator or simply not good enough goes out again in another fusion.delegate call that says what was wrong and what good looks like.
Stalled reviews. If the orchestrator only reads for 6 steps in a row (the reviewStallSteps default), it is told to delegate or reply. At twice that, it can only call fusion.delegate, reply or finish. The threshold is halved when your message reads as a repair request.
Stalled workers. A worker that has written no file by half its budget is handed back early with what it found, so the orchestrator can split the task and try again.
What you see while it runs
A Fusion turn shows the plan, one approval for the fan-out, and a live row per worker. Each row names the task, the model running it, the tool in use and the elapsed time, beside the orchestrator’s time estimate when it gave one. A summary line then reports how many tasks came back ok.
The approval. When approvals are on, Atomic Agent asks you once per fan-out, before any worker starts. The prompt lists the task titles and the directories the workers may write to and run commands in. Your answer covers the rest of the turn, so a review that re-delegates five times does not ask five times. A later fan-out that reaches a new directory asks again.
Anything a worker cannot do alone (because it needs a person, or a wider write scope than you approved) comes back to the orchestrator marked needs_orchestrator instead of stalling.
Steering workers, resuming runs and cost caps
Steer, stop or escalate one worker
In the TUI, each running worker row shows its tokens and cost as it runs, for example · 41.2k tok · $0.03. Local workers show tokens only. You can act on one worker without stopping the others:
/worker steer <id> <note> send a note to one running worker
/worker stop <id> stop one worker, the rest keep going
/worker escalate <id> ask a stronger model to help this worker
The worker reads your note at its next step. The note tells the worker that it comes from the person running the session and outranks its brief where the two disagree. /worker escalate asks the orchestrator’s model (or escalationProvider, see escalation) for a hint. It works without turning on automatic escalation. One worker gets at most two escalations, automatic and manual together. It fails when no provider other than the worker’s is configured for it, including when both seats use one provider.
In the desktop app, each running worker row has Steer and Stop buttons. See In the desktop app.
Resume a cut-off run
Fusion saves each run as it goes, in <stateDir>/fusion-runs/, and keeps the record for 7 days. If the app crashes, quits or is stopped mid-run, the next start tells you that a run was cut off. Open that chat from /sessions and use:
/fusion list runs that can be resumed
/fusion resume [id] continue the unfinished part, keep what was done
/fusion discard [id] drop a cut-off run
A resume never starts on its own. Tasks with side effects, such as shell commands, git, HTTP, e-mail, MCP calls, paid generation or verify.run, are not run again unless you confirm them. Resuming is available in the TUI only; the desktop app has no resume button yet.
Cost caps
Fusion cost figures now count cached tokens at the cached price, so cloud worker costs are no longer overstated. The header shows N in, M cached / K out. Costs are estimated from the provider’s price list, not taken from your bill. Local tokens count as $0.
Two keys cap one Fusion turn. Both are off when unset or 0. They live in config.json only: there is no setting for them in the TUI or the desktop app.
Key (under llm.runMode.fusion)
Range
What it does
turnBudgetUsd
0 to 10,000
Money cap for one Fusion turn, in US dollars: the orchestrator’s own spend plus every worker’s.
turnTimeBudgetMs
0 to 86,400,000 (24 h)
Time cap for one Fusion turn, in milliseconds, counted from the start of the turn.
When a cap is reached, running workers are stopped, workers that had not started are marked cancelled with not started: <reason>, and the orchestrator is told to reply to you in plain words. A resumed run counts what it spent before the restart toward the same cap.
New options, off by default
These options change how Fusion plans and checks work. All of them are off until you set them in config.json under llm.runMode.fusion. There is no switch for them in the TUI or the desktop app.
Key
Default
What it does
roles
unset
Give different jobs to different providers: plan, build, review, explore, utility, each set to a provider id. The orchestrator then picks a role per task. plan does not change the orchestrator, which still comes from orchestratorProvider.
mixLocalModels
false
Allow two local models in one fan-out. The second model must already be running on its own llama-server; the agent does not start it.
A worker whose task is too big can propose a split, and Fusion runs the parts under it, up to maxDepth levels deep (2 by default, at most 3). maxNodes caps all tasks of one fan-out, from 1 to 64. The TUI shows the parts as rows named parent/child.
isolation
"off"
"worktree" gives each worker its own git worktree and merges the changes back afterwards. Merge conflicts are saved under .atomic-agent/fusion-merge/<task>/ and handed to the orchestrator. Submodules are not checked out in worktrees.
judge
"off"
"on" gives each task a checklist that a separate judge model checks. A task closes only when the list is green; a red task is retried once, then marked failed item by item. judgeProvider picks the judge (default: the orchestrator; with roles, the review model).
autoReplan
0
From 1 to 5: when a fan-out leaves tasks unfinished, the orchestrator plans them again and sends them out, up to this many times per task, instead of waiting for you to type “continue”.
escalation
"off"
"advisor" lets a stuck worker ask a stronger model for a short hint. A worker counts as stuck when it repeats the same result 3 times, only reads for 6 steps, or its first answer is cut off by its time limit. It gets one automatic hint, and at most two escalations in total with /worker escalate. escalationProvider picks that model (default: the orchestrator; if it points at the worker provider, or both seats share one provider, escalation is off; the provider’s default chat model answers), escalationMaxUsd caps the spend of one escalation (default 0.25, at most 1,000), and escalationReplace: true lets the stronger model take the task over when the worker is still stuck after its hint.
{
"llm": {
"runMode": {
"mode": "fusion",
"fusion": {
"orchestratorProvider": "openrouter",
"workerProvider": "local-llama",
"turnBudgetUsd": 2,
"judge": "on",
"autoReplan": 2
}
}
}
}
None of these options has been measured on real models yet. Turn them on one at a time and check the results yourself.
A frozen local server fails fast
If the local model server stops answering after a worker on it was cut off, the next Fusion task fails at once with “not dispatched: the local model server stopped answering after an earlier worker on it was cut off” and a hint to restart the local server. Before, it could wait for up to 45 minutes.
Limits and gotchas
Pin a real model on the cloud side. Routers such as openrouter/auto can pick small, cheap models that ignore Fusion’s instructions. Choose a specific model for the cloud provider (/model or /llm).
The local seat needs real hardware. A 27B-class local model is practical from a GPU with around 24 GB of memory. On smaller cards the local seat can be slow enough that a single run stretches into hours.
Your data is not confined to your machine. Whichever seat is in the cloud sees your request and the file contents it works with.
Two providers in the terminal app. Two cloud models or two local models are fine, but the TUI will not put the same provider in both seats. The desktop app accepts one cloud provider in both seats, but both then run the same default model and escalation is off. Neither app puts the managed local model in both seats.
The orchestrator cannot call MCP tools during a Fusion turn. They are treated as tools that change things and are refused.
Troubleshooting
Most Fusion problems come from which provider is active, a missing second provider, or the local server’s slot count. Start with /runmode status: it prints what the mode resolves to, how many workers can run and, when the stored and the effective mode differ, why.
What you see
What it means
Fix
stored fusion, effective cloud in /runmode status
The active provider is no longer the orchestrator.
Run /runmode fusion again.
”Fusion needs a cloud orchestrator. No cloud provider is configured. Staying on local.”
No orchestrator could be resolved.
Add a cloud provider (Manage › LLM › Cloud, or /llm), or pin both seats in config.
”Fusion needs two providers, one to orchestrate and one to run the workers.”
A note that work was sent but only some workers ran at a time
The local server has fewer request slots than tasks.
Set /runmode workers N and restart the local server, or let the orchestrator send fewer, larger tasks.
The orchestrator’s writes are refused
This is Fusion working as designed.
Nothing to fix. The workers do the writing.
A worker “handed back early: no file written by half the budget”
The worker read but did not write.
Usually handled by the orchestrator re-splitting the task. If it repeats, give the task a clearer deliverable.
”The local engine can serve one Fusion role at a time. Choose a cloud provider for the other role.” (desktop app)
Both seats point at the local model.
Pick a cloud provider for one seat, or press the swap control to move the local model to the other role.
Unsure whether Fusion is really active
The mode chip alone does not prove the orchestrator has the delegate tool.
Run /tools and check that fusion.delegate is listed.
FAQ
Which direction should I start with?
For code-heavy jobs, try a local orchestrator with cloud workers (/runmode swap after /runmode fusion). For jobs that split into many small parts, the default cloud orchestrator with local workers is the natural fit.
Does the cloud model see my files?
The cloud seat sees what it is given and what it reads: in the default direction, your conversation and the files it reviews; with cloud workers, your request (up to 16,000 characters) plus the files each worker opens.
Can I use two cloud models, or two local ones?
Yes. Any two different providers work, for example a careful cloud model directing a fast one, or a large local model directing a small one. With two local providers, pin both seats. To get two different cloud models, use two providers: one provider in both seats runs the same default model twice.
How do I leave Fusion?
Run /runmode cloud or /runmode local, or pick another mode in the switch (ctrl+r in the TUI, Where it runs in the desktop app).