Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions vendor/agents/docs/content/docs/agent-to-agent.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: "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.

<div style="overflow-x:auto">
<svg viewBox="0 0 600 250" role="img" aria-label="The coder agent&#x27;s request_review tool calls requestReview on the reviewer agent for the repository and returns right away. The reviewer schedules its own prompt, which runs as a follow-up if it is busy." style="width:100%;min-width:520px;max-width:600px;height:auto;display:block;margin:2.5rem auto;font-family:system-ui,sans-serif">
<svg viewBox="0 0 600 250" role="img" aria-label="The coder agent&#x27;s request_review tool calls requestReview on the reviewer agent for the repository and returns right away. The reviewer submits the request to its conversation, where it waits as a follow-up if a review is running." style="width:100%;min-width:520px;max-width:600px;height:auto;display:block;margin:2.5rem auto;font-family:system-ui,sans-serif">
<defs>
<marker id="agent-to-agent-arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0 L10 5 L0 10 z" fill="rgb(var(--site-ink, 27 25 22))"/></marker>
</defs>
Expand All @@ -15,17 +15,15 @@ A tool can send another agent a message. Here a coder agent hands a finished bra
<rect x="310" y="170" width="170" height="48" rx="7" fill="#ffffff" stroke="#1b1916" stroke-width="1.4"/>
<g stroke="rgb(var(--site-ink, 27 25 22))" stroke-width="1.4" fill="none">
<path d="M171 78 L308 78" marker-end="url(#agent-to-agent-arrow)"/>
<path d="M365 107 L365 168" marker-end="url(#agent-to-agent-arrow)"/>
<path d="M425 169 L425 108" marker-end="url(#agent-to-agent-arrow)"/>
<path d="M395 107 L395 168" marker-end="url(#agent-to-agent-arrow)"/>
</g>
<text x="95" y="83" text-anchor="middle" font-size="14" font-weight="600" fill="#1b1916">Coder agent</text>
<text x="395" y="75" text-anchor="middle" font-size="14" font-weight="600" fill="#1b1916">Reviewer agent</text>
<text x="395" y="92" text-anchor="middle" font-size="12" fill="#56524a">key: repository</text>
<text x="395" y="199" text-anchor="middle" font-size="14" font-weight="600" fill="#1b1916">Schedule</text>
<text x="395" y="199" text-anchor="middle" font-size="14" font-weight="600" fill="#1b1916">Conversation</text>
<text x="239.5" y="71" text-anchor="middle" font-size="12" fill="#56524a">requestReview</text>
<text x="239.5" y="94" text-anchor="middle" font-size="12" fill="#56524a">returns right away</text>
<text x="357" y="141.5" text-anchor="end" font-size="12" fill="#56524a">after(0)</text>
<text x="433" y="142.5" text-anchor="start" font-size="12" fill="#56524a">prompt</text>
<text x="403" y="141.5" text-anchor="start" font-size="12" fill="#56524a">submit</text>
</svg>
</div>

Expand All @@ -35,9 +33,9 @@ A tool can send another agent a message. Here a coder agent hands a finished bra
<CodeSnippet file="examples/docs/agent-to-agent/client.ts" title="client.ts" />
</CodeGroup>

- The reviewer is keyed by repository, so every coder working on the same repository reaches the same reviewer, and its session remembers past reviews.
- The `requestReview` action schedules the reviewer's `prompt` and 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.
- Passing `streamingBehavior: "followUp"` queues the request when the reviewer is busy with another review. Use it with `prompt`, not the `followUp` action, which only queues on an idle agent and never starts a run.
- The reviewer runs on a different model family than the coder.
- The reviewer is keyed by repository, so every coder working on the same repository reaches the same reviewer, and its conversation remembers past reviews.
- The `requestReview` action gets Pi's harness as `c.pi` and submits the request to the reviewer's root conversation without waiting. The request is saved before the action returns, so the review runs even if the coder's request goes away.
- When the reviewer is busy with another review, the request waits as a follow-up and runs next.
- The coder's `request_review` tool sits next to `CodingTools` in its registry. The reviewer runs on a different model family than the coder.

To wait for the other agent's answer instead, see [Subagents](/agents/docs/subagents). See [Schedules](/actors/docs/schedule) for more on `c.schedule`.
To wait for the other agent's answer instead, see [Subagents](/agents/docs/subagents). See [Pi](/agents/docs/pi#your-own-actions-and-cpi) for more on `c.pi`.
2 changes: 1 addition & 1 deletion vendor/agents/docs/content/docs/api-keys.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Set the key for your model provider in the environment of the process that runs
ANTHROPIC_API_KEY=sk-ant-...
```

Pi reads the provider-named variable, such as `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `XAI_API_KEY`, `DEEPSEEK_API_KEY`, `GROQ_API_KEY`, or `OPENROUTER_API_KEY`. See Pi's [provider list](https://github.com/earendil-works/pi) for the rest.
Pi reads the provider-named variable, such as `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `XAI_API_KEY`, `DEEPSEEK_API_KEY`, `GROQ_API_KEY`, or `OPENROUTER_API_KEY`. See Pi's <a href="https://github.com/earendil-works/pi" target="_blank" rel="noopener noreferrer">provider list</a> for the rest.

## Keys in code

Expand Down
54 changes: 26 additions & 28 deletions vendor/agents/docs/content/docs/architecture.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ title: "Architecture"
description: "The states an agent moves through, and what survives sleep, crashes, and upgrades."
---

This page describes [`pi()`](/agents/docs/pi). A [`piDurable()`](/agents/docs/pi-durable) agent sleeps and drains the same way, and differs where noted in [Pi Durable](#pi-durable).
A [`pi()`](/agents/docs/pi) agent runs <a href="https://earendil.com/posts/pi-durable/" target="_blank" rel="noopener noreferrer">Pi Durable</a>, Earendil's durable agent harness, inside a Rivet Actor. Pi saves each step of a run to the Actor's SQLite database before the next step starts.

## States

An agent is idle until a prompt starts a run, and goes back to idle when the run ends or is cancelled. When the context fills up during a run, the agent compacts it and keeps going.
A conversation is idle until a prompt starts a run, and goes back to idle when the run ends or is cancelled. When the context fills up during a run, the agent compacts it and keeps going.

<div style="overflow-x:auto">
<svg viewBox="0 0 640 300" role="img" aria-label="Agent states: a prompt moves Idle to Running, and the run ending or being cancelled moves it back. Running moves to Compacting when the context is full and back when compaction is done. Idle moves to Sleeping when idle, and the next action wakes it back to Idle. Running sends tool calls to the sandbox." style="width:100%;min-width:520px;max-width:640px;height:auto;display:block;margin:2.5rem auto;font-family:system-ui,sans-serif">
Expand Down Expand Up @@ -49,7 +49,9 @@ An agent is idle until a prompt starts a run, and goes back to idle when the run

## Sleep

An idle agent sleeps and frees its memory. The next action on its key wakes it: the agent reloads its session, and reconnects to the same sandbox the first time a tool needs it, so clients don't do anything different. While the agent sleeps, its sandbox is suspended.
An idle agent sleeps and frees its memory. The next action on its key wakes it: the agent opens Pi from SQLite, resumes interrupted work, and reconnects to the same sandbox the first time a tool needs it, so clients don't do anything different. While the agent sleeps, its sandbox is suspended.

During a retry or poll wait longer than a minute, the Actor also sleeps, and a scheduled wake resumes the work when the wait ends.

<div style="overflow-x:auto">
<svg viewBox="0 0 640 280" role="img" aria-label="The agent loop runs in memory and saves each step to the Actor&#x27;s SQLite database, which also holds the sandbox id. On wake, the loop is restored from SQLite and reconnects to the same sandbox. Sleep, a crash, or an upgrade clears memory, and SQLite is kept." style="width:100%;min-width:520px;max-width:640px;height:auto;display:block;margin:2.5rem auto;font-family:system-ui,sans-serif">
Expand All @@ -71,7 +73,7 @@ An idle agent sleeps and frees its memory. The next action on its key wakes it:
<text x="235" y="91" text-anchor="middle" font-size="14" font-weight="600" fill="#1b1916">Agent loop</text>
<text x="235" y="108" text-anchor="middle" font-size="12" fill="#56524a">in memory</text>
<text x="235" y="197" text-anchor="middle" font-size="14" font-weight="600" fill="#1b1916">SQLite</text>
<text x="235" y="214" text-anchor="middle" font-size="12" fill="#56524a">session, sandbox id</text>
<text x="235" y="214" text-anchor="middle" font-size="12" fill="#56524a">conversations, sandbox id</text>
<text x="550" y="99" text-anchor="middle" font-size="14" font-weight="600" fill="#1b1916">Sandbox</text>
<text x="197" y="150.5" text-anchor="end" font-size="12" fill="#56524a">save each step</text>
<text x="273" y="151.5" text-anchor="start" font-size="12" fill="#56524a">restore on wake</text>
Expand All @@ -83,41 +85,37 @@ An idle agent sleeps and frees its memory. The next action on its key wakes it:

## What survives

| | Session | Sandbox |
| | Conversations | Sandbox |
| --- | --- | --- |
| Sleep | Every message so far. | Reconnected on first use. |
| Crash | Every message written before the crash. A run in progress resumes on wake if Pi can continue it. | Reconnected on first use. |
| Upgrade | Every message so far. A run in progress gets time to finish first. See [Upgrades](#upgrades). | Reconnected on first use. |
| Sleep | Every step so far. | Reconnected on first use. |
| Crash | Every step saved before the crash. A run in progress resumes on wake from the step it reached. | Reconnected on first use. |
| Upgrade | Every step so far. A run in progress gets time to finish first. See [Upgrades](#upgrades). | Reconnected on first use. |
| Destroy | Deleted. | Deleted. |

A model chosen with `setModel` is restored too, if it's still allowed. If the sandbox no longer exists when the agent wakes, a new one is created and the old files are lost.

Actions that don't touch the sandbox, such as `getMessages` or `setModel`, don't connect to it. They keep working while the sandbox provider is down.
A model or instructions set with `conversation.configure` are part of the conversation, so they are kept too. Without a sandbox, files live in the Actor's SQLite database and survive the same way as conversations. If the sandbox no longer exists when the agent wakes, a new one is created and the old files are lost.

## Upgrades
Actions that don't run a tool, such as `conversation.context` or `conversation.configure`, don't connect to the sandbox. They keep working while the sandbox provider is down.

When you ship new code, an agent in the middle of a run lets it finish, for up to `sleepGracePeriod` (15 minutes by default), before it restarts on the new version. See [Versions](/docs/versions).
## Resuming a run

A run that is still going when the grace period ends, or that a crash cuts off, resumes when the agent wakes if Pi can continue it from the saved messages:
After a crash or a cut-off upgrade, the agent reads the saved steps on wake and carries on from the step it reached:

| Stopped while | Resumes? |
| Stopped while | On wake |
| --- | --- |
| The model was answering | Yes. The model is asked again, and the partial answer is lost. |
| Parallel tool calls ran and at least one finished | Yes. Calls that didn't finish get a "No result provided" result. |
| A tool call ran and none finished | No. |
| The run was cancelled with `abort` | No. |
| The model was answering | The model call is sent again from the start. The partial answer is lost. |
| A tool marked `replay: "safe"` ran | The tool runs again. |
| Any other tool ran | The tool isn't run again. Its result tells the model the call stopped partway. |
| A task phase ran | The phase runs again, and earlier phases are kept. |
| The run was cancelled with `abort` | Nothing resumes. |

A run that doesn't resume is left as if it had been cancelled, and the next prompt continues the conversation. A client that was waiting on `prompt` gets an error. It can follow the resumed run through events, or read it with `getMessages`.
Nothing runs while a crashed Actor is down. The run resumes when the Actor starts again. A client that is still connected gets a fresh snapshot on its event stream.

Nothing runs while a crashed Actor is down. The run resumes when the Actor starts again.
## Upgrades

## Pi Durable
When you ship new code, running work gets up to `sleepGracePeriod` (15 minutes by default) to finish before the Actor restarts on the new version. See [Versions](/docs/versions). Work still running when the grace period ends resumes on wake, after your `onWake` runs.

A [`piDurable()`](/agents/docs/pi-durable) agent saves every step of a run, so it doesn't depend on what the saved messages look like:
A client waiting on `prompt` gets an error if the Actor stops first. It can send the prompt again with the same `requestId` to get the first prompt's result instead of a second run. Actions wait up to ten minutes, and a timed-out wait leaves the run going.

- **Runs carry on from the last saved step.** Model calls, tool calls, and tasks your tools launch each save their progress. After a crash, the Actor reads that record and carries on. A plain tool call that was running isn't rerun unless it's marked `replay: "safe"`, and the model learns it never completed.
- **Long waits don't keep the Actor awake.** During a long retry or poll wait, the Actor sleeps and wakes when the wait ends.
- **Streams come back on wake.** A client that is still connected gets a fresh snapshot.
- **Destroy stops at once**, without waiting for running work.
Destroying the Actor stops running work at once, without a grace period.

See [Known limitations](/agents/docs/pi-durable#known-limitations) for what this doesn't cover.
Roll forward only. An older version of Pi Durable can't open data that a newer version wrote, so don't roll back after an upgrade has run.
Loading
Loading