Files
multica/apps/docs/content/docs/daemon-runtimes.mdx
Jordan c27919a4d0 feat(agents): add DevEco Code (deveco) runtime agent (MUL-4050) (#4916)
Adds DevEco Code (Huawei's HarmonyOS coding agent, built on the OpenCode engine) as a first-class runtime provider: backend/model parser, daemon discovery (probe + login-shell list + Windows .cmd native resolver), runtime profile migration (protocol_family whitelist), provider UI, metrics, and four-language docs. MCP injection is deferred (UI gates it off). Migration numbered 175.
2026-07-14 15:21:45 +08:00

193 lines
10 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Daemon and runtimes
description: Agents don't run on Multica's servers — they run on your own machines.
---
import { Callout } from "fumadocs-ui/components/callout";
import { Mermaid } from "@/components/mermaid";
In Multica, [agents](/agents) do **not** run on our servers — they run on your own machines, driven by a small program called the **daemon** that invokes the [AI coding tools](/providers) installed locally. The Multica server only coordinates: it stores [issues](/issues), queues [tasks](/tasks), and dispatches them to the right **runtime** (runtime = daemon × one AI coding tool).
This structure is the biggest difference between Multica and Linear / Jira: **your API keys, toolchain, and code directories stay on your machine** — the Multica server never sees any of them. That means "my agent isn't working" is almost always a local problem — the daemon isn't running, an AI tool isn't installed, a key has expired. Check locally first; see [Troubleshooting](/troubleshooting) for a guide.
## Starting the daemon
The daemon is part of the Multica CLI. Once you've installed the [Multica CLI](/cli), run on your own machine:
```bash
multica daemon start
```
On startup it does four things:
1. Reads the credentials saved when you logged in
2. Detects AI coding tools installed on your `PATH` (15 built-in: [Antigravity](/providers#antigravity), [Claude Code](/providers#claude-code), [CodeBuddy](/providers#codebuddy), [Codex](/providers#codex), [Cursor](/providers#cursor), [Copilot](/providers#copilot), [Hermes](/providers#hermes), [Kimi](/providers#kimi), [Kiro CLI](/providers#kiro-cli), [OpenCode](/providers#opencode), [OpenClaw](/providers#openclaw), [Pi](/providers#pi), [Qoder](/providers#qoder), [Trae CLI](/providers#trae), [DevEco Code](/providers#deveco-code))
3. Registers itself with the server, along with a runtime for each detected tool
4. Keeps **polling every 3 seconds** for tasks to pick up, and **sends a heartbeat every 15 seconds**
Common commands:
| Command | Purpose |
|---|---|
| `multica daemon start` | Start (background by default; add `--foreground` to run in the foreground) |
| `multica daemon stop` | Stop |
| `multica daemon restart` | Restart |
| `multica daemon status` | Show status |
| `multica daemon logs` | Show logs (add `-f` to follow) |
Full CLI reference in [CLI commands](/cli).
**The desktop app ships with a daemon.** If you use the [desktop app](/desktop-app), you don't need to run `multica daemon start` manually — it launches the daemon automatically on startup. See the [Desktop app](/desktop-app) page for which option fits your workflow.
## Why one machine has multiple runtimes
A runtime is not a server and not a container — it's the combination of "**daemon × one AI coding tool**". For example: you start the daemon on a MacBook with both Claude Code and Codex installed, and you're a member of two workspaces. Multica then registers 4 runtimes:
<Mermaid chart={`
graph TD
D["Your daemon<br/>MacBook"]
D --> R1["Runtime<br/>Workspace A × Claude Code"]
D --> R2["Runtime<br/>Workspace A × Codex"]
D --> R3["Runtime<br/>Workspace B × Claude Code"]
D --> R4["Runtime<br/>Workspace B × Codex"]
`} />
Key points:
- **One daemon can map to multiple runtimes** — one per combination of installed tool and workspace you belong to
- **The same daemon, workspace, and tool produces exactly one runtime** — restarting the daemon never creates duplicate records
- The **Runtimes** page in the Multica UI lists these rows
## Custom runtime profiles
Built-in provider detection covers the common tools, but teams can also define
**custom runtime profiles** for AI CLIs that speak one of Multica's supported
protocol families and need a different launch command. Typical examples include
an internal wrapper around Codex, a version-pinned executable, or a team CLI
that adds fixed model arguments.
Do not create a custom profile just to use Claude Code, Codex, Kimi, or another
built-in provider with its normal command. The daemon detects those tools
automatically.
### Before you create one
- Install the custom command on at least one machine running a Multica daemon,
and confirm the same command works in that machine's terminal.
- Confirm the tool speaks one of the base protocol families shown in the UI.
Choosing a family tells Multica how to communicate with the process; it does
not make an incompatible CLI compatible.
- You must be a workspace owner or admin to create, edit, or delete a profile.
### Create one from the Runtimes UI
1. Open **Runtimes**, then select the machine where you installed the command.
2. Select **Add custom runtime**.
3. Choose the base protocol family implemented by the command.
4. Enter a display name and the command you would run in a terminal, including
any fixed arguments. Add an optional description so teammates know what it
is for.
5. Select **Create runtime**.
The profile definition belongs to the whole workspace and syncs to every
connected daemon. Each machine registers its own runtime only when it can
resolve that command. The machine where you started the flow shows a temporary
**Registering** row while it waits. If the row does not become online, check
that the command is installed and available to the daemon on that machine.
Creating a profile does not install the CLI, authenticate it, or copy it to
other machines. Install and sign in to the underlying tool separately on every
machine that should provide this runtime.
### Manage profiles from the CLI
The same workspace profiles can be managed from the CLI:
```bash
multica runtime profile list
multica runtime profile create --display-name "Composer" --protocol-family codex --command-name agent
multica runtime profile update <profile-id> --command-name agent
multica runtime profile delete <profile-id>
```
Custom and built-in runtimes share the same machine list. Use a custom runtime
row's actions menu to edit or delete its profile. Deleting a profile removes its
registered runtime instances after the daemons synchronize; it can be blocked
while agents still depend on it.
The command is argv-oriented, not a shell string. Multica stores an executable
name plus fixed arguments, then the daemon launches it directly with
`exec.Command(command_name, fixed_args...)`. Plain arguments, quotes, and
backslash escaping are supported; pipes, redirects, `&&`, `;`, backticks, and
`$VAR` / `$(...)` expansion are not. Use a wrapper script when the runtime needs
shell behavior. Today the Runtimes UI owns command-and-argument parsing; the CLI
profile commands manage the profile row and local path overrides.
If a desktop-launched daemon cannot find a command that works in your terminal,
pin the absolute path on that machine:
```bash
multica runtime profile set-path <profile-id> --path /abs/path/to/agent
multica runtime profile unset-path <profile-id>
```
Profile command or argument edits apply to newly claimed tasks after the daemon
re-registers. Running tasks keep the launch arguments they started with. For
mixed deployments, upgrade the server before rolling out newer daemons: the
server-side Runtimes UI stores `fixed_args`, and the server is what surfaces
`failed_profiles` registration reports. Older components may ignore fields they
do not understand instead of failing loudly, so treating the server upgrade as
the first step keeps the rollout observable.
<Callout type="info">
**Cloud runtimes are coming**, currently in a waitlist phase. Once available, you'll be able to execute agent tasks directly on Multica Cloud without running a local daemon. Sign up with your email on the [download page](https://multica.ai/download) to get notified.
</Callout>
## When a runtime is marked offline
Multica uses heartbeats to decide whether a runtime is online. Three key numbers:
| Event | Threshold |
|---|---|
| Daemon heartbeat frequency | Every **15 seconds** |
| Marked as missing | No heartbeat for **45 seconds** (3 missed beats) |
| Auto-deleted | Missing with no associated agents for over **7 days** |
Missing is not permanent — as soon as the daemon sends another heartbeat it returns to online, and the runtime record is preserved. Restarting the daemon does not lose runtimes.
<Callout type="warning">
**Tasks running on a missing runtime are marked as failed** (failure reason `runtime_offline`). For retryable sources (issues, chat), Multica automatically requeues them; Autopilot-triggered tasks are not retried automatically. See [Tasks → Which failures retry automatically](/tasks#which-failures-retry-automatically-which-dont).
</Callout>
## How many tasks can run in parallel
Multica enforces concurrency limits at two layers:
- **Daemon layer**: **20 concurrent tasks** by default (tunable via env var `MULTICA_DAEMON_MAX_CONCURRENT_TASKS`)
- **Agent layer**: **6 concurrent tasks per agent** by default (configured per-agent)
The tighter of the two wins. If your daemon is already running 20 tasks, new tasks wait even if an agent still has headroom.
If you see tasks stuck in `queued` without moving to `dispatched`, one of these two limits is usually saturated.
## What happens to in-flight tasks after a daemon crash
When the daemon crashes or is force-killed, the tasks it had picked up are left in `dispatched` or `running`. On the next start, the daemon tells the server: "these tasks are no longer mine, please mark them failed." The server flips them to `failed` with reason `runtime_recovery` — for retryable sources, the tasks are automatically requeued.
Even if this step fails due to a network issue, there's a server-side scan **every 30 seconds** as a backstop: any runtime without a heartbeat for over 45 seconds is marked missing, and its tasks are reclaimed along with it.
## Troubleshooting agents that aren't working
When you hit a "my agent isn't working" problem, run this three-step checklist first:
1. Run `multica daemon status` — confirm the daemon is running and online
2. Run `multica daemon logs -f` — check for errors
3. Open the **Runtimes** page in the Multica UI — confirm your runtime shows "online"
More scenarios in [Troubleshooting](/troubleshooting).
## Next
- [Tasks](/tasks) — the full lifecycle of a task once the daemon picks it up
- [Providers Matrix](/providers) — capability differences across the 15 AI coding tools