
How to Hand Off Work Between Agents
Handing off work between agents should not depend on copying a paragraph into the right chat window and hoping the receiving model understands where it came from. A useful handoff needs an addressed recipient, a real sender identity, a visible task body, and a return path that the receiving agent can use when a reply is needed.
That is the problem AxiOwl is built to solve. In the current C++ implementation, AxiOwl is a local Windows coordinator for sending messages between AI provider sessions. It exposes both a CLI and an MCP server, keeps a durable local registry of provider sessions, discovers active sessions, and dispatches messages through provider-specific edges.
The practical goal is simple: one agent can send work to another named agent session, and the recipient can respond back through AxiOwl instead of inventing a separate return channel.
The AxiOwl Handoff Model
AxiOwl treats a handoff as a message delivery path, not as a hidden queue or background broker. The current architecture routes a request through this shape:
CLI or MCP tool call
-> AxiOwl command handler
-> MessagePipeline
-> sender and target resolution
-> one targeted discovery repair if needed
-> final visible body builder
-> provider edge
-> provider-specific delivery
-> logs, receipts, and reply evidence
The important detail is that the middle stays thin. Provider-specific details live in provider modules such as Codex, Cursor, VS Code native, VS Code Copilot-backed, Antigravity, and supported CLI surfaces. The shared pipeline validates the request, resolves the registry row, builds the final message, and hands it to the right provider edge.
That division matters during handoff work because different providers expose different session concepts. A Codex chat, a Cursor agent window, a VS Code Copilot-backed session, and an Antigravity conversation do not all look the same internally. AxiOwl keeps the operator-facing action consistent: send to a named target, let the provider edge handle the provider-specific mechanics.
Start With The Agent Registry
A handoff starts with a name, but AxiOwl does not treat a name as enough proof that delivery is possible. The registry stores rows with fields such as:
- display name
- aliases
- provider
- provider session id
- node id
- enabled state
- sendable state
- discovery source
- last-seen and last-verified timestamps
- last error
That sendable field is one of the most important safety checks in the system. The current pipeline can know about a provider session without considering it a valid delivery target. If a row is known but not sendable, AxiOwl rejects the send instead of pretending a handoff happened.
This is the right behavior for real agent operations. A stale display name, a weak discovery hint, or a provider session id found from incomplete evidence should not become a live handoff target just because the name exists in a file.
Operators can inspect available targets with:
axiowl list agents
Discovery can refresh provider state:
axiowl discover all
Specific provider discovery is also available for supported surfaces, including Codex, VS Code native, VS Code Copilot, Cursor, Antigravity, and several CLI-oriented provider targets represented in the current command surface.
Send A Direct Handoff
For a short task, the common CLI form is:
axiowl send --to "Target chat name" --body "Please review the failing test and report the smallest fix."
For a longer task, --stdin is the safer form because it preserves multiline instructions without turning quoting into the main problem:
@'
Please inspect the failing provider smoke test.
Return:
1. the failing provider surface
2. the exact failure boundary
3. the smallest fix you recommend
'@ | axiowl send --to "Target chat name" --stdin
The CLI also accepts an explicit sender:
axiowl send --from "Operator Agent" --to "Target chat name" --body "Please take the next investigation step."
In provider-driven workflows, though, the preferred reply path is MCP. The AxiOwl MCP server exposes typed tools such as axiowl_send_message and axiowl_create_agent. Its instructions tell providers to use those tools instead of constructing raw command-line arguments. That lets AxiOwl resolve sender identity from provider/session metadata rather than from a guessed display name.
What The Recipient Sees
AxiOwl does not deliver only the raw operator text. When sender identity is resolved, the final visible body is built with a sender header, the original task, and an MCP reply instruction block.
The current builder produces a body shaped like this:
Message from Sender Agent
<original handoff body>
If requested to, respond with this exact MCP tool call:
mcp__axiowl.axiowl_send_message({
"to": "Sender Agent",
"body": "<full reply>"
})
When a run id or receipt correlation id is present, the builder includes those values in the reply instruction too. Tests in the repo check that this MCP-first helper shape is present and that older shell fallback wording does not return.
If AxiOwl cannot resolve the sender, it deliberately does not attach a send-back command. The recipient may still see the message, but the body includes a warning that the sender could not be resolved. That is safer than telling an agent to reply to a target that AxiOwl cannot actually route.
Receipts Are Not The Same As Replies
AxiOwl separates several events that are easy to confuse:
accepted_by_axiowlmeans the request entered the AxiOwl pipeline and passed local validation.- Provider acceptance means a provider edge reported that it accepted delivery work.
- A reply through AxiOwl MCP is the stronger end-to-end proof.
The support and architecture docs are explicit about this boundary. A local receipt is not proof that the provider displayed the message, processed the task, or sent a response. For a true handoff test, the recipient must reply through AxiOwl with correct sender identity.
This distinction is useful in everyday work. If a handoff fails, you can ask where it failed:
- Was the target missing from the registry?
- Was the target known but not sendable?
- Did provider discovery find only weak evidence?
- Did AxiOwl hand off delivery but the provider edge fail?
- Did the provider receive the message but lack AxiOwl MCP tools for the reply?
- Did the reply arrive with missing or wrong provider metadata?
That gives operators a concrete troubleshooting path instead of a vague "the agent did not answer."
Creating A New Agent Session For A Handoff
Some handoffs go to an existing chat. Others need a new target session. The current CLI supports create for provider surfaces such as Codex, Antigravity, VS Code native, VS Code Copilot, Cursor, and supported CLI targets:
@'
Please investigate the installer regression and summarize the root cause.
'@ | axiowl create --provider vscode-copilot --name "Installer Regression Review" --from "Operator Agent" --stdin
The same handoff principles apply. The new chat needs a clear name, the initial task body, and a sender identity that can be used as a real return target. The implementation has had explicit work around this because a created chat can receive an initial prompt but still fail the round trip if the generated reply target is not actually sendable.
That lesson is central to AxiOwl's design: a handoff is not complete because text appeared somewhere. A handoff is complete when the addressed agent can act and, when asked, respond over the AxiOwl path.
Practical Handoff Checklist
Before sending important work between agents, use a short checklist:
- Confirm the target appears in
axiowl list agents. - Prefer a human-readable display name, not a raw provider session id.
- Use
--stdinfor multiline work orders. - Use MCP tools for provider replies where available.
- Treat
accepted_by_axiowlas a local receipt, not end-to-end proof. - Require an MCP reply when you need proof that the recipient acted.
- If delivery fails, inspect
%LOCALAPPDATA%\AxiOwl\logs,%LOCALAPPDATA%\AxiOwl\registry, and provider-specific bridge output.
For operators, the payoff is reliable delegation. You can assign a focused task to another agent session, keep the sender and recipient names visible, and verify whether the response came back through the intended route.
For developers, the payoff is a cleaner system boundary. The registry decides what is addressable, the pipeline builds one final visible body, and provider modules handle provider-specific delivery behavior. Failures are supposed to be loud and inspectable rather than hidden behind fallback behavior.
Closing
The useful version of agent-to-agent handoff is not magic. It is structured messaging with identity, routing, visible instructions, and proof. AxiOwl's current implementation centers on those pieces: a durable registry, a CLI and MCP surface, a final visible body that carries reply instructions, and provider edges that isolate each provider's delivery mechanics.
That makes handoff work operational instead of ad hoc. One agent can pass a task to another named session, the recipient can reply through AxiOwl when asked, and the logs can show which boundary succeeded or failed.