Tools
Agent-to-Agent Messages
Let one agent hand work to another agent without waiting for it.
A tool can send another agent a message. Here a coder agent hands a finished branch to the reviewer for that repository and keeps working.
import { Type } from "@earendil-works/pi-ai";
import { defineTool } from "@earendil-works/pi-coding-agent";
import { pi } from "@rivet-dev/pi";
import { createClient } from "rivetkit/client";
import type { registry } from "./server";
const requestReview = defineTool({
name: "request_review",
label: "Request review",
description: "Send a finished branch to the repository's reviewer. Don't wait for the review.",
parameters: Type.Object({ repo: Type.String(), branch: Type.String(), summary: Type.String() }),
async execute(_toolCallId, { repo, branch, summary }) {
await client.reviewer.getOrCreate([repo]).requestReview(`Review ${branch}: ${summary}`);
return { content: [{ type: "text", text: `Sent ${branch} for review.` }], details: undefined };
},
});
export const coder = pi({ model: "anthropic/claude-opus-5-5", customTools: [requestReview] });
const client = createClient<typeof registry>();
import { pi } from "@rivet-dev/pi";
import { setup } from "rivetkit";
import { coder } from "./coder";
const reviewer = pi({
model: "anthropic/claude-opus-5-5",
actions: {
requestReview: async (c, request: string) => {
await c.schedule.after(0, "prompt", request, { streamingBehavior: "followUp" });
},
},
});
export const registry = setup({ use: { coder, reviewer } });
- The reviewer is keyed by repository, so every coder working on the same repository reaches the same reviewer, and its session remembers past reviews.
requestReviewschedules the reviewer’spromptand returns, so the coder’s tool doesn’t wait for the review. The schedule is saved with the reviewer, so the review runs even if the coder’s request goes away.streamingBehavior: "followUp"queues the request when the reviewer is busy with another review. Use it withprompt, not thefollowUpaction, which only queues on an idle agent and never starts a run.
To wait for the other agent’s answer instead, see Subagents. See Schedules for more on c.schedule.