On this page
How omp Runs Subagents Differently
Most coding agents treat a subagent as a nested chat that returns prose. omp gives workers typed results, direct peer messages, and safer shared-file edits.
I spent the weekend reading about omp and digging into how its subagent system works.
This post is about that part: what a subagent is, why most tools build them as nested chat, and how omp does it differently. I will write a fuller omp post later. This one stays on subagents.
First, What Is omp?
omp (Oh My Pi) is a coding agent for the terminal. It started as a fork of Pi. Pi keeps the core small. omp adds more of the IDE into that core: file edits, search, language tools, debug, plan mode, memory, and first-class subagents.

That is the product pitch. I will write a fuller omp post later. This one stays on the subagent model.
I already wrote about Pi as the thin layer between heavier tools. Pi skips built-in subagents on purpose. omp keeps the Pi base and then builds subagents into the product on purpose.
What Most Tools Mean by “Subagent”
A subagent is a second agent that the main agent starts for a piece of work. It usually gets a fresh context, its own prompt, and a smaller tool set. When it finishes, it sends a result back up.
In tools like Claude Code, that result is mostly free-form text. The parent reads a summary and decides what to do next.
%%{init: {"layout": "dagre"}}%%
flowchart TD
Parent[Parent agent] -->|"task"| Child[Child with fresh context]
Child -->|"text summary"| Parent
Parent --> Decide[Parent reads the text and continues]
This works for many jobs. It keeps the parent context clean. It also has a clear limit: the return value is prose. If you start five workers, you often end up asking the parent to parse five write-ups.
How omp Changes That
omp still starts child agents. The difference is the contract around them.
Workers can return data that matches a schema you set. Peers can message each other while they run. Outputs stay readable as paths like agent://<id>. Two workers can edit the same file, and a stale edit is rejected before it lands.
The homepage claim that made me look closer was simple: fan out workers, pull one field from one result, and let peers talk mid-run without sending every note through the parent.
Why this matters: the parent no longer has to rewrite every child’s report. It can read fields and move on.
1. You Declare What the Child Must Return
In omp, a subagent is a Markdown agent file. Frontmatter sets tools, model, and an optional output schema. The child finishes through a yield. The harness checks the shape of that yield.
This shows up in omp’s own schema surface too. The shot below is not a live fan-out demo. It is the internal contract view, and subagents are only one part of it:

A scout agent, for example, is meant to return a short summary plus a list of files. Not “whatever prose feels right.”
---
name: scout
description: Fast read-only research for handoff.
tools: read, grep, glob, web_search
model: "@smol"
output:
properties:
summary:
type: string
files:
elements:
properties:
path:
type: string
description:
type: string
---
You can also set a schema on a single call. Soft mode warns if the shape stays wrong after retries. Strict mode fails the job.
After the run, the full result lives at agent://ComponentsExports. One field can be read directly, such as agent://ComponentsExports/files.0.path.
| Need | What omp gives you |
|---|---|
| Start several workers at once | task with shared context and a tasks[] list |
| Force a clear return shape | agent output schema or call-site schema |
| Read one field later | agent://<id>/path |
| Inspect what the child did | history://<id> |
2. Peers Can Talk Without the Parent
Most harnesses keep the parent in the middle. Child A finishes. Parent reads the summary. Parent tells Child B. That costs another turn and often drops detail.
omp gives peers a shared message channel. The tool for that is hub. A worker can send a short message to another worker while both are still running. The parent can still steer. It does not have to route every note.
%%{init: {"layout": "dagre"}}%%
flowchart LR
Parent[Parent] -->|"starts both"| A[Worker A]
Parent -->|"starts both"| B[Worker B]
A -->|"direct message"| B
B -->|"direct message"| A
Parent -->|"reads agent:// results"| Out[Combined answer]
A send does not wait for a reply. You get a delivery receipt back: placed into a busy peer, used to wake an idle peer, used to bring back a parked peer, or failed if the peer is gone.
Finished workers can stay idle for a while, then come back if you message them. That is useful when you want a follow-up without starting from a blank child.
3. Shared-File Edits Fail Safe
The common safe pattern is isolation: give each worker its own worktree, then merge later. omp can do that too.
It also supports a shared working tree with hashline edits. Each line read by the agent carries a short content hash. An edit points at those anchors. If another worker changed the file first, the anchors no longer match, so the second write is rejected before it commits. The second worker re-reads and tries again. The first edit stays.
%%{init: {"layout": "dagre"}}%%
flowchart TD
A[Worker A edits] --> Ok[Edit lands]
B[Worker B edits same file] --> Check{Anchors still match?}
Check -->|yes| Ok
Check -->|no| Reject[Reject write]
Reject --> Reread[Re-read file]
Reread --> Retry[Edit again]
Retry --> Ok
Use a private worktree when the change should stay on its own branch. Use hashline when two specialists need the same file and you want the harness to catch stale writes early.
omp reports that Grok 4 Fast used 61% fewer output tokens on the same work once edits moved to anchors instead of large string rewrites. That is a side effect of the same design.
This Is Not the A2A Protocol
While reading about omp peer messaging, it is easy to mix it up with A2A, Google’s Agent2Agent protocol. They solve different problems.
omp subagents live inside one local runtime. The parent starts them. They can share local files, use hub to talk, and return results through agent:// paths. The contract is omp-specific. Latency stays low because there is no network hop between siblings.
A2A is a wire protocol for agents that may sit on different machines, teams, or stacks. Agents publish an Agent Card so others can find them. Work moves as Tasks, Messages, and Artifacts over JSON-RPC, gRPC, or HTTP. The point is interoperability across trust and service boundaries, not shared-file editing inside one coding session.
%%{init: {"layout": "dagre"}}%%
flowchart LR
subgraph ompSide["omp subagents"]
Main[Main] --> W1[Worker A]
Main --> W2[Worker B]
W1 -->|"hub DM"| W2
end
subgraph a2aSide["A2A"]
Client[Client agent] -->|"Task / Message"| Remote[Remote agent]
Remote -->|"Artifact"| Client
end
| Question | omp subagents | A2A |
|---|---|---|
| Where do agents run? | Inside one omp session | As separate services, often remote |
| Main goal | Split work inside one coding harness | Let different agent systems work together |
| How they talk | Local hub mailbox | Standard network protocol |
| Shared state | Local files, agent://, hashline edits | Designed to avoid sharing internal state |
| Best use | Workers for one repo and one session | Cross-team or cross-vendor agent calls |
Why this matters: omp peer DMs are not a replacement for A2A. They are a local coordination tool. If you need two specialists on the same checkout, use omp subagents. If you need your coding agent to call a booking agent or a support agent owned by another team, use A2A.
When This Model Helps
| You need | Better fit |
|---|---|
| One specialist with a clean context | Almost any subagent system |
| Fields you can trust without re-parsing prose | omp schema + agent:// reads |
| Two workers that must sync mid-run | omp peer messages over hub |
| Two workers on one shared file | hashline reject-and-retry |
| A change you may throw away | omp isolated worktree mode |
| Talk to an agent owned by another team or vendor | A2A, not omp’s local subagent bus |
If you only need “go research this and summarize it,” nested chat is enough. If you need five workers, one field from each, and light peer sync, the omp model is doing more of the work in the harness. If those workers must live outside your process, that is a different layer.
The Bottom Line
A subagent is easy to describe. It is also easy to build too thin.
Most tools build it as nested chat: spawn, wait, read prose. omp builds it as a small runtime: named workers, checked return shapes, peer messages, and file edits that refuse stale writes.
I am still early with omp day to day. The weekend read was enough to change how I judge other harnesses. When someone says “we have subagents,” I now ask three things:
- What can the child return?
- Can siblings talk without the parent?
- What happens when two workers touch the same file?
Those questions show whether you have a summary helper or a real worker system.
I will publish a broader omp post next, covering the rest of the product beyond subagents.
Working with multi-agent coding setups, or comparing how different tools spawn workers? Tell me what broke first. Reach out on LinkedIn.