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:

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:

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:

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:

  1. Confirm the target appears in axiowl list agents.
  2. Prefer a human-readable display name, not a raw provider session id.
  3. Use --stdin for multiline work orders.
  4. Use MCP tools for provider replies where available.
  5. Treat accepted_by_axiowl as a local receipt, not end-to-end proof.
  6. Require an MCP reply when you need proof that the recipient acted.
  7. 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.