Skip to content
GitHub Get Started
Orchestration

Agent-to-Agent Communication

Agents communicate through bindings. You define a bindings group that lets one agent send work to another, and the agent calls it like any other CLI command.

This example gives the writer agent a review binding. The writer sends the file’s full contents (the VMs share no filesystem), and the binding writes them into a separate reviewer VM and sends a review prompt back through the reviewer.

server.ts
import { agentOS, setup } from "@rivet-dev/agentos";
import { createClient } from "@rivet-dev/agentos/client";
import { z } from "zod";
// The reviewer is its own isolated agent VM.
const reviewer = agentOS({});
// Bridge the writer to the reviewer. The VMs share no filesystem, so the writer
// sends the full file contents; the bridge writes them into the reviewer's VM
// and asks the reviewer to review. Runs on the host.
async function reviewCode(code: string): Promise<string> {
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const reviewerHandle = client.reviewer.getOrCreate("my-project");
// Write the submitted contents into the reviewer's VM.
await reviewerHandle.writeFile("/home/user/review.ts", code);
// Ask the reviewer to review.
const session = await reviewerHandle.createSession("claude", {
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
const result = await reviewerHandle.sendPrompt(
session.sessionId,
"Review the code at /home/user/review.ts and list any issues.",
);
await reviewerHandle.closeSession(session.sessionId);
return result.text;
}
// The writer agent gets a `review` binding. When the writer runs
// `agentos-review submit`, the bridge above executes on the host.
const writer = agentOS({
bindings: [
{
name: "review",
description: "Send code to the reviewer agent and get back a review.",
bindings: {
submit: {
description:
"Submit the full contents of a file to the reviewer agent for review. Returns the reviewer's feedback as text.",
inputSchema: z.object({
code: z.string().describe("The full source code to review."),
}),
execute: async (input: { code: string }) => ({
review: await reviewCode(input.code),
}),
},
},
},
],
});
export const registry = setup({ use: { writer, reviewer } });
registry.start();

See Full Example

The writer agent sees the review binding as a CLI command. Because the VMs share no filesystem, it sends the full file contents, not a path:

Terminal window
agentos-review submit --code "$(cat api.ts)"

The binding writes the contents into the reviewer’s VM, prompts the reviewer, and returns the review to the writer as JSON.

Bindings are the natural communication layer between agents because:

  • The agent doesn’t need to know about other agents. It just calls a binding. You can swap the implementation without changing the agent’s behavior.
  • No credentials in the VM. The binding executes on the server, so it can access other agents directly without exposing connection details.
  • Composable. Chain any number of agents by adding more bindings. Each binding is a self-contained bridge to another agent.
  • Each agent has its own isolated VM and filesystem (they share no filesystem). Pass file contents through the binding input, then use writeFile in the binding to land them in the other VM.
  • Use Workflows to make multi-agent pipelines durable across restarts.