# AI Agent Orchestration by Task, Not by Name: Octomind 0.72.0

> AI agent orchestration in Octomind 0.72.0 matches each task to a specialist, ships a routing model retrained on task briefs, and sends diffs to your editor.

![Animated Octomind icon — purple pixel-art octopus](/octomind-icon-animated.gif)

AI agent orchestration in Octomind had one weak spot: an agent that wanted help had to know its helper by name. Its prompt carried a list of specialists, or it called a `discover` action, read the answer and picked one. A list went stale the day an agent was renamed, and a wrong pick showed only when the work came back wrong.

**In Octomind 0.72.0 the agent sends the task, and Octomind starts the specialist that fits it.** This semantic routing runs on your machine with a small embedding model, retrained for this job, that now gives the same score on ARM and x86. Each domain also has one lead agent named `chief`, which shipped in 0.71.0 three days earlier. There was no 0.71.0 post, so this one covers everything since [the 0.70.1 post](/blog/octomind-0-70-1-release). The open-source update is available today.

Two terms before the details. A **tap** is a Git repository of agent definitions that Octomind installs. The default one, `muvon/tap`, holds 186 agents in 34 domains such as `developer`, `lawyer` and `video`. A **specialist** is one of those agents, started by another agent to do one task in a fresh context of its own.

## Start a domain instead of remembering an agent name

Since 0.71.0 every domain has a lead agent named `chief`, and a domain name alone starts it:

| You type                       | What starts                                                                                |
| ------------------------------ | ------------------------------------------------------------------------------------------ |
| `octomind run`                 | `assistant:chief`, the global assistant, which picks the right domain for your request     |
| `octomind run developer`       | `developer:chief`, the developer lead, which hands larger work to the domain's specialists |
| `octomind run doctor:blood`    | That one specialist, with no lead in between                                               |
| `/role developer` in a session | Switches the session to the developer lead                                                 |

The same names work with `octomind acp` and `octomind server`. Workflows still need full `domain:agent` tags.

What you can count on:

- **Your own role wins.** If your config has a role called `developer`, `octomind run developer` starts yours. One banner line tells you the tap has a lead of that name too.
- **Old names keep working.** 16 lead agents were renamed, for example `developer:cto` to `developer:chief` and `assistant:concierge` to `assistant:chief`. A saved session, a script or a `/role` call that uses an old name loads the renamed agent and says so.
- **One model for a whole domain.** A `[taps]` key can be a bare domain, so `"developer" = "openai:gpt-4o"` sets the model for every developer agent. A key with a full tag still wins for that agent.

## Agent routing: agents describe the task, Octomind picks the specialist

Inside a session, agents delegate through the `tap` tool. The call used to need a role name. In 0.72.0 it needs only the task:

```json
{
	"action": "run",
	"prompt": "Audit src/auth/ for security bugs. Do not edit files. Return file:line evidence and concrete failure scenarios."
}
```

Octomind then does four things:

1. **It takes the agents the caller may reach.** A lead reaches the specialists of its own domain, plus what its manifest declares in a `# Uses:` header. A role from your own config reaches every installed agent.
2. **It compares the task with each candidate's title and description.** The comparison uses a local embedding model, which turns text into numbers so that texts with a similar meaning land close together.
3. **It starts the best candidate** when its score is at least 0.65 and it leads the runner-up by at least 0.05.
4. **Otherwise it starts nothing** and says which specialists came closest.

A run that starts answers with its id, the `role` that took the task and that specialist's title, so a wrong match is visible at once and can be stopped. A task that matches nothing gets this error:

```text
No specialist was matched to this task. The closest ones to this task:
- <name> — <title>. <description>
  (up to five)
If one of them covers the task, call `run` again with `role` set to its name. If none does, do the task with the tools you have, or report that it is outside what you can do.
```

Every case in one table:

| Situation                                  | What happens                                                          |
| ------------------------------------------ | --------------------------------------------------------------------- |
| One specialist clearly fits                | It starts, and the reply names it                                     |
| Two specialists score almost the same      | Nothing starts. The error lists the five closest                      |
| The agent passes a `role` it may reach     | That specialist starts without matching. A bare domain means its lead |
| The agent passes a `role` it may not reach | Refused, with the same list. The task is never sent to someone else   |
| The caller may reach no agent at all       | `No specialist matches this task.` The agent does the work or says no |

The `discover` action and the `intent` parameter are gone. The [MCP tools guide](/docs/usage/07-mcp-tools#specialist-matching) has the full contract, and [multi-agent delegation](/docs/use-cases/05-multi-agent-delegation) walks through a run from start to follow-up.

## Why the choice moved out of the prompt

A prompt that lists helpers looks simple. It stopped working as the registry grew:

- **Names in prompts go stale.** A rename has to be chased through every prompt that names the agent, and 0.71.0 renamed 16 leads at once. Octomind Cloud's own orchestrator prompt carried a hand-written roster of specialist names. With this release the roster is gone.
- **One call does what took two.** `discover` returned up to five roles. The agent read them, chose one and made a second call to start it.
- **Reach is enforced, not requested.** A prompt used to tell a lead which agents it may call. Now the runtime matches only against the agents that lead may reach, so no wording in a prompt gets around it.
- **A refusal costs less than a wrong handoff.** The comment in the routing code says it: "a wrong handoff is silent, a refusal costs one turn." That is why two near-tied specialists start nothing.
- **Agent lists stay out of prompts.** The `{{SPECIALISTS}}` and `{{USES}}` placeholders, which pasted agent lists into a lead's prompt, are no longer expanded.

The similarity step alone is deliberately cautious. Measured on 2,184 task briefs written for the default tap's agents, each ranked against its own domain, it hands 45.6% of briefs to the right specialist and 1.1% to a wrong one. The rest get the no-match error with the list of names, and the agent picks from it.

## A routing model retrained on task briefs

The match uses `muvon/octomind-embed`, a 30-million-parameter embedding model. The same model decides when a capability switches on by itself and when a `semantic(...)` skill rule fires. For this release it was retrained: next to capability trigger phrases, it now learns from task briefs paired with the title and description of the agent that should take them.

| Measured on                                                   | Weights from 2026-09 | Weights from 2026-11 |
| ------------------------------------------------------------- | -------------------- | -------------------- |
| Capability: the right one switched on (1,384 prompts)         | 80.9%                | 83.7%                |
| Capability: one switched on for a prompt that needs none (90) | 3.3%                 | 2.2%                 |
| Routing: the brief ranks its own agent first (2,184 briefs)   | 68.2%                | 82.4%                |
| Routing: the brief is handed to its agent                     | 30.4%                | 45.6%                |
| Routing: the brief is handed to a wrong agent                 | 2.4%                 | 1.1%                 |

Each column uses the thresholds Octomind runs those weights with. The numbers and the scripts behind them are in the [model's README](https://github.com/muvon/octomind-tap/blob/master/model/README.md), and the weights are on [Hugging Face](https://huggingface.co/muvon/octomind-embed).

Two more changes make those numbers hold on your machine:

- **The same score on every CPU.** With the old model file, one text scored 0.620 on an ARM Mac and 0.664 on an x86 CI runner, so a threshold tuned on one machine misfired on another. The new file stores its weights as 8-bit integers (30 MB instead of 121 MB) but computes in 32-bit floats. It scored identically on ARM, x86 and x86 with VNNI.
- **One exact revision.** Octomind 0.72.0 loads one pinned revision of the model, the one its thresholds were calibrated against. An install that has older weights cached fetches the pinned ones on first use.

The thresholds moved with the weights. Capability auto-activation and the default for `semantic(...)` went from 0.65 to 0.68, and the required lead over the runner-up went from 0.06 to 0.05. If one of your skills sets its own number, as in `semantic(phrase, 0.7)`, that number was tuned against the old weights, so test the skill again. The [skills guide](/docs/usage/15-skills) explains the rule.

## Let a decision model make the final pick

Similarity is cheap and local, but a small model can read. One switch hands it the final choice:

```toml
[decision]
taps = true
```

It is off by default, and it needs the supervisor on and a `[decision] model` set. With it on, similarity only builds a shortlist of the 16 closest specialists. The decision model answers one question: which of these should do the task, or none of them. Its pick gets the task, `none` starts nothing, and if the model is unavailable the similarity result stands.

One measurement is on record. With the Jev decision model choosing among the 14 developer specialists, 168 written briefs produced 158 right picks and 8 wrong ones. That is one domain and written briefs, so read it as an indication, not a benchmark. Octomind Cloud runs with this switch on. The [config reference](/docs/reference/03-config-reference) lists every `[decision]` switch.

## The default tap moved with the runtime

Octomind syncs the default tap by itself, so these arrive without an install step:

- **A lead in every domain.** All 34 domains have a `chief`. 18 of those are new, among them `finance`, `marketing`, `sales`, `security` and `support`.
- **Leads declare who else they may call.** A header in the manifest lists it: `# Uses: content, seo` for the marketing lead, `# Uses: developer` for design. The global assistant has `# Uses: *`, which means the lead of every other domain.
- **The same checks for your own tap.** A tap made with `octomind tap init` gets a check script that rejects a `# Uses:` header on anything but a lead, leads that would delegate to each other in a loop, and the removed placeholders.
- **Code search through octofs.** Structural and graph code search now default to octofs, with its `view` and `symbol` tools. octocode stays available as the other provider.
- **A developer lead that respects your directory.** Ask `developer:chief` to deliver in your directory and it applies the verified change there without asking again. On a conflict it changes nothing and reports the paths. It never stashes, resets or cleans a worktree that has your edits.
- **New marketing and commerce work.** An `ai-visibility` workflow compares runs and prepares drafts for your review, without posting anything. New skills cover SEO content refresh, customer review programs and a commerce AI-readiness audit.

The [tap system guide](/docs/integration/04-tap-system) documents manifests, the `# Uses:` header and how taps are found.

## Your editor sees what a tool call does

Octomind talks to editors such as Zed, Neovim and JetBrains IDEs over ACP, the Agent Client Protocol. A tool call used to carry an id, a title and its raw input. It now carries three more things:

| Field       | What it holds                                                                                                                     |
| ----------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `kind`      | `execute` for a tool that runs a command, `read` for a read-only tool, `edit` for a write that names a file, `other` for the rest |
| `locations` | The files the call names, as absolute paths, with the line when the input gives one                                               |
| `content`   | For an edit, one diff per pair of old and new text in the input                                                                   |

With that an editor can classify a call, jump to the file it works on and show what an edit changes. The kind comes from what the tool declares about itself, not from its name, so tools from any MCP server get it. An edit that sends no old text, such as a whole-file write, comes without a diff. Pranoy Kumar Kundu contributed this change. The [editor integration guide](/docs/usage/12-editor-integration) covers setup.

## Installed taps are mirrors now

A tap cloned from GitHub used to update with a plain pull, and one local commit or edit in the clone could block every later update. A sync now makes the clone match the upstream default branch exactly:

- **It discards what you changed inside the clone:** edits, local commits and new files.
- **It runs at most every 15 minutes,** and at once on the first run of a new Octomind version, so renamed agents are there right after an upgrade.
- **It runs in the background.** A lookup that finds nothing waits up to 30 seconds for the sync and tries once more.
- **Local taps are never touched.** To customize agents, register your own directory with `octomind tap <user/repo> /path/to/local`, or push to the tap's repository.

## Other fixes since 0.70.1

- **A line after every turn (0.71.0).** Interactive sessions print `Worked for <duration> · done <time>`, plus what is still running in the background.
- **Sessions with a damaged fold file resume (0.71.0).** The file is removed and the session loads without it.
- **"Done" passes when the evidence settles everything (0.71.0).** The verify gate no longer reports `completion could not be verified` after its own check cleared every open condition.
- **Schedules reject impossible hours (0.71.0).** `13am` used to fire at 13:00 and `0pm` at noon. Both are errors now. `13:00` works as before.
- **`octomind configure` trims a pasted API key (0.71.0).** A stray space no longer gets saved and rejected by the provider.
- **Config validation names an MCP server with an empty `url` or `command` (0.71.0).**
- **Token counts from 999,950 print as `1.0M` (0.71.0),** not `1000.0k`.
- **Specialist reports render as markdown (0.72.0).** Messages that arrive in your session from background work use your markdown theme.
- **`/loglevel` shows the current level (0.72.0)** when you pick the level that is already active.

## Before you update

- **Your config migrates to version 31 on first start.** Version 30 renames old lead names in `[taps]` keys and in `default`. Version 31 adds `taps = false` under `[decision]`. Octomind saves a backup first. A migrated config won't load in an older Octomind.
- **Check your tap clones for local changes.** The first run syncs them at once and discards anything uncommitted or unpushed. The clones live under `taps/` in Octomind's data directory, `~/.local/share/octomind/taps/` on Linux.
- **`octomind run` with no agent now starts `assistant:chief`.**
- **`[[layers]]` is removed from the config.** Delete the entries. `octomind config --validate` reports them as unknown keys. `[[commands]]` is unaffected.
- **`octomind acp --hook` is removed.** It never started a listener. Webhooks stay with `octomind run`.
- **If you write tap agents:** `{{SPECIALISTS}}` and `{{USES}}` reach the model as written, so delete them. The `tap` tool has no `discover` action. A `# Uses:` header that names a missing agent, a domain without a lead or the agent's own domain stops that agent from loading. To rename an agent without breaking old names, leave a symlink from the old file to the new one.

## Update to Octomind 0.72.0

On macOS and Linux:

```bash
curl -fsSL https://octomind.run/install.sh | bash -s -- --version 0.72.0
octomind --version
```

On Windows, in PowerShell:

```powershell
$env:OCTOMIND_VERSION = "0.72.0"
irm https://raw.githubusercontent.com/muvon/octomind/master/install.ps1 | iex
```

Or run `scoop update octomind`. See the [installation guide](/docs/usage/01-installation) for other methods, the [full changelog](https://github.com/muvon/octomind/blob/0.72.0/CHANGELOG.md), and [the 0.70.1 notes](/blog/octomind-0-70-1-release) if you're coming from 0.69 or earlier.

Then try it: run `octomind run developer`, give it a task that needs more than one pair of hands, and read which specialist the `tap` call names.

— DK
