{"slug": "how-omp-runs-subagents-differently", "title": "How omp Runs Subagents Differently", "summary": "Omp, a terminal-based coding agent forked from Pi, differentiates its subagent system by allowing workers to return typed results matching a declared schema, send direct peer messages, and safely edit shared files, rejecting stale edits. This contrasts with tools like Claude Code, where subagents return free-form text that the parent must parse. omp's approach lets the parent read specific fields directly, such as `agent://ComponentsExports/files.0.path`, reducing the need to rewrite child reports.", "body_md": "## On this page\n\n# How omp Runs Subagents Differently\n\nMost 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.\n\nI spent the weekend reading about [omp](https://omp.sh/) and digging into how its subagent system works.\n\nThis 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.\n\n## First, What Is omp?\n\n[omp](https://omp.sh/) (Oh My Pi) is a coding agent for the terminal. It started as a fork of [Pi](https://pi.dev/). 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.\n\nThat is the product pitch. I will write a fuller omp post later. This one stays on the subagent model.\n\nI already wrote about [Pi as the thin layer between heavier tools](/blog/2026/pi-agent-multi-tool-workflow/). Pi skips built-in subagents on purpose. omp keeps the Pi base and then builds subagents into the product on purpose.\n\n## What Most Tools Mean by “Subagent”\n\nA 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.\n\nIn tools like [Claude Code](https://code.claude.com/docs/en/sub-agents), that result is mostly free-form text. The parent reads a summary and decides what to do next.\n\n``` php\n%%{init: {\"layout\": \"dagre\"}}%%\nflowchart TD\n    Parent[Parent agent] -->|\"task\"| Child[Child with fresh context]\n    Child -->|\"text summary\"| Parent\n    Parent --> Decide[Parent reads the text and continues]\n```\n\nThis 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.\n\n## How omp Changes That\n\nomp still starts child agents. The difference is the contract around them.\n\nWorkers 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>`\n\n. Two workers can edit the same file, and a stale edit is rejected before it lands.\n\nThe 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.\n\n**Why this matters:** the parent no longer has to rewrite every child’s report. It can read fields and move on.\n\n## 1. You Declare What the Child Must Return\n\nIn omp, a subagent is a Markdown agent file. Frontmatter sets tools, model, and an optional `output`\n\nschema. The child finishes through a `yield`\n\n. The harness checks the shape of that yield.\n\nThis 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:\n\nA scout agent, for example, is meant to return a short summary plus a list of files. Not “whatever prose feels right.”\n\n```\n---\nname: scout\ndescription: Fast read-only research for handoff.\ntools: read, grep, glob, web_search\nmodel: \"@smol\"\noutput:\n  properties:\n    summary:\n      type: string\n    files:\n      elements:\n        properties:\n          path:\n            type: string\n          description:\n            type: string\n---\n```\n\nYou can also set a schema on a single call. Soft mode warns if the shape stays wrong after retries. Strict mode fails the job.\n\nAfter the run, the full result lives at `agent://ComponentsExports`\n\n. One field can be read directly, such as `agent://ComponentsExports/files.0.path`\n\n.\n\n| Need | What omp gives you |\n|---|---|\n| Start several workers at once | `task` with shared context and a `tasks[]` list |\n| Force a clear return shape | agent `output` schema or call-site schema |\n| Read one field later | `agent://<id>/path` |\n| Inspect what the child did | `history://<id>` |\n\n## 2. Peers Can Talk Without the Parent\n\nMost 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.\n\nomp gives peers a shared message channel. The tool for that is `hub`\n\n. 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.\n\n``` php\n%%{init: {\"layout\": \"dagre\"}}%%\nflowchart LR\n    Parent[Parent] -->|\"starts both\"| A[Worker A]\n    Parent -->|\"starts both\"| B[Worker B]\n    A -->|\"direct message\"| B\n    B -->|\"direct message\"| A\n    Parent -->|\"reads agent:// results\"| Out[Combined answer]\n```\n\nA 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.\n\nFinished 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.\n\n## 3. Shared-File Edits Fail Safe\n\nThe common safe pattern is isolation: give each worker its own worktree, then merge later. omp can do that too.\n\nIt also supports a shared working tree with [hashline](https://github.com/can1357/oh-my-pi/tree/main/packages/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.\n\n``` php\n%%{init: {\"layout\": \"dagre\"}}%%\nflowchart TD\n    A[Worker A edits] --> Ok[Edit lands]\n    B[Worker B edits same file] --> Check{Anchors still match?}\n    Check -->|yes| Ok\n    Check -->|no| Reject[Reject write]\n    Reject --> Reread[Re-read file]\n    Reread --> Retry[Edit again]\n    Retry --> Ok\n```\n\nUse 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.\n\nomp 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.\n\n## This Is Not the A2A Protocol\n\nWhile reading about omp peer messaging, it is easy to mix it up with [A2A](https://a2a-protocol.org/latest/specification/), Google’s Agent2Agent protocol. They solve different problems.\n\nomp subagents live inside one local runtime. The parent starts them. They can share local files, use `hub`\n\nto talk, and return results through `agent://`\n\npaths. The contract is omp-specific. Latency stays low because there is no network hop between siblings.\n\nA2A 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.\n\n```\n%%{init: {\"layout\": \"dagre\"}}%%\nflowchart LR\n    subgraph ompSide[\"omp subagents\"]\n        Main[Main] --> W1[Worker A]\n        Main --> W2[Worker B]\n        W1 -->|\"hub DM\"| W2\n    end\n    subgraph a2aSide[\"A2A\"]\n        Client[Client agent] -->|\"Task / Message\"| Remote[Remote agent]\n        Remote -->|\"Artifact\"| Client\n    end\n```\n\n| Question | omp subagents | A2A |\n|---|---|---|\n| Where do agents run? | Inside one omp session | As separate services, often remote |\n| Main goal | Split work inside one coding harness | Let different agent systems work together |\n| How they talk | Local `hub` mailbox | Standard network protocol |\n| Shared state | Local files, `agent://` , hashline edits | Designed to avoid sharing internal state |\n| Best use | Workers for one repo and one session | Cross-team or cross-vendor agent calls |\n\n**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.\n\n## When This Model Helps\n\n| You need | Better fit |\n|---|---|\n| One specialist with a clean context | Almost any subagent system |\n| Fields you can trust without re-parsing prose | omp schema + `agent://` reads |\n| Two workers that must sync mid-run | omp peer messages over `hub` |\n| Two workers on one shared file | hashline reject-and-retry |\n| A change you may throw away | omp isolated worktree mode |\n| Talk to an agent owned by another team or vendor | A2A, not omp’s local subagent bus |\n\nIf 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.\n\n## The Bottom Line\n\nA subagent is easy to describe. It is also easy to build too thin.\n\nMost 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.\n\nI 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:\n\n- What can the child return?\n- Can siblings talk without the parent?\n- What happens when two workers touch the same file?\n\nThose questions show whether you have a summary helper or a real worker system.\n\nI will publish a broader omp post next, covering the rest of the product beyond subagents.\n\n*Working with multi-agent coding setups, or comparing how different tools spawn workers? Tell me what broke first. Reach out on LinkedIn.*", "url": "https://wpnews.pro/news/how-omp-runs-subagents-differently", "canonical_source": "https://kondasamy.com/blog/2026/omp-subagent-system-deep-dive/", "published_at": "2026-07-19 00:00:00+00:00", "updated_at": "2026-08-10 19:04:58.990770+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents", "artificial-intelligence"], "entities": ["omp", "Pi", "Claude Code"], "alternates": {"html": "https://wpnews.pro/news/how-omp-runs-subagents-differently", "markdown": "https://wpnews.pro/news/how-omp-runs-subagents-differently.md", "text": "https://wpnews.pro/news/how-omp-runs-subagents-differently.txt", "jsonld": "https://wpnews.pro/news/how-omp-runs-subagents-differently.jsonld"}}