# Agent

The handle of one agent session: it runs turns, changes settings, checkpoints, forks, and stops the session.

`SpawnBuilder.build`, `open_session`, `resume`, and `switch` return an `Agent` with its event stream. Clones of an `Agent` share one session. `Agent.prompt` starts a turn and returns a [`Turn`](/docs/api/rust/Turn).

```rust
// 1. Spawn an agent and run one turn
let (agent, _events) = runtime.spawn().build().await?;
let result = agent
    .prompt("List three risks of a Friday deploy.")
    .await?
    .await?;
println!("{}", result.final_message());

// 2. Wait for durable writes before the process exits
agent.flush().await?;
```

## Methods

### prompt

```rust
// Starts a turn from a string, a Prompt, or a PromptRequest
pub async fn prompt(
    &self,
    request: impl Into<PromptRequest>,
) -> Result<Turn, NanocodeError>
```

Validates the prompt and starts a turn. A prompt with a request ID can be repeated: after a crash the repeat recovers the turn, and after completion it returns the recorded result. See [`PromptRequest`](/docs/api/rust/Turn#promptrequest).

```rust
use nanocode::PromptRequest;

// Sends an identified prompt that can be retried safely
let turn = agent
    .prompt(
        PromptRequest::new("Run the checklist.")
            .request_id("checklist-1"),
    )
    .await?;
```

### subscribe

```rust
// A new stream of the agent's events
pub fn subscribe(&self) -> AgentEvents
```

Returns another receiver of the agent's events, for example for a second consumer.

```rust
// Logs every event kind from a background task
let mut events = agent.subscribe();
tokio::spawn(async move {
    while let Some(event) = events.recv().await {
        eprintln!("{:?}", event.kind);
    }
});
```

### session_id

```rust
// The durable identity of the session
pub fn session_id(&self) -> &str
```

Returns the session ID. `runtime.open_session` takes this value to reopen the session.

```rust
// Saves the ID for a later process
let id = agent.session_id().to_owned();
```

### agent_id

```rust
// The identity of this agent
pub fn agent_id(&self) -> &str
```

Returns the ID of this agent within its session.

```rust
// Prints the agent and session identities
println!("{} {}", agent.agent_id(), agent.session_id());
```

### checkpoint

```rust
// A portable snapshot of the conversation
pub async fn checkpoint(
    &self,
) -> Result<SessionCheckpoint, NanocodeError>
```

Returns a checkpoint that `runtime.resume` accepts. See [`SessionCheckpoint`](/docs/api/rust/types#sessioncheckpoint).

```rust
// Stores the checkpoint as JSON
let json = agent.checkpoint().await?.to_json()?;
```

### flush

```rust
// Waits for pending durable writes
pub async fn flush(&self) -> Result<(), NanocodeError>
```

Waits until the backend has written its pending state. Call it before reading the store or before the process exits.

```rust
// Makes sure the store holds the finished turn
agent.flush().await?;
let saved = store.load(agent.session_id()).await?;
```

### disconnect

```rust
// Releases the session without cancelling work
pub async fn disconnect(&self) -> Result<(), NanocodeError>
```

Stops admitting prompts and releases the session after the active turns finish. A backend without durable ownership treats `disconnect` as `shutdown`.

```rust
// Leaves the session for another process to open
agent.disconnect().await?;
```

### shutdown

```rust
// Stops the agent
pub async fn shutdown(&self) -> Result<(), NanocodeError>
```

Cancels the active turns and stops the agent. `runtime.shutdown` does this for every agent the runtime owns.

```rust
// Stops one agent and keeps the runtime
agent.shutdown().await?;
```

### cancel_active_turn

```rust
// Cancels the running turn, if any
pub async fn cancel_active_turn(&self) -> Result<(), NanocodeError>
```

Cancels the turn that is running now. The turn result is then `NanocodeError::TurnCancelled`.

```rust
// Cancels from another task
agent.cancel_active_turn().await?;
```

### set_thinking

```rust
// Changes the reasoning effort for later requests
pub async fn set_thinking(
    &self,
    thinking: Thinking) -> Result<(,
), NanocodeError>
```

Sets the reasoning effort of the session.

```rust
use nanocode::Thinking;

// Raises the effort for a harder turn
agent.set_thinking(Thinking::High).await?;
```

### set_fast_mode

```rust
// Turns the fast service tier on or off
pub async fn set_fast_mode(
    &self,
    enabled: bool) -> Result<(,
), NanocodeError>
```

Sets the service tier to `ServiceTier::Fast` when `enabled` is `true`, and to `ServiceTier::Standard` when it is `false`.

```rust
// Requests faster responses
agent.set_fast_mode(true).await?;
```

### set_service_tier

```rust
// Selects a service tier
pub async fn set_service_tier(
    &self,
    service_tier: ServiceTier) -> Result<(,
), NanocodeError>
```

Sets the service tier of later requests. Models that do not support a tier fall back, as [`ServiceTier`](/docs/api/rust/types#servicetier) describes.

```rust
use nanocode::ServiceTier;

// Requests priority processing
agent.set_service_tier(ServiceTier::Priority).await?;
```

### compact

```rust
// Compacts the conversation history
pub async fn compact(&self) -> Result<(), NanocodeError>
```

Compacts the conversation history of the session now. A failed compaction returns `NanocodeError::CompactionFailed`.

```rust
// Compacts before a long follow-up task
agent.compact().await?;
```

### side_question

```rust
// Asks about the conversation without starting a turn
pub async fn side_question(
    &self,
    question: impl Into<String>,
) -> Result<SideAnswer, NanocodeError>
```

Asks the model a question about the current conversation and returns a `SideAnswer` with `text` and `usage`. It also works while a turn runs, and tool calls that are still running appear to the model as not finished. A backend without side questions returns `NanocodeError::UnsupportedCapability`.

```rust
// Asks for a progress summary during a long turn
let answer = agent.side_question("What have you done so far?").await?;
println!("{}", answer.text());
```

### spawn

```rust
// A new agent on the same harness and settings
pub async fn spawn(&self) -> Result<(Agent, AgentEvents), NanocodeError>
```

Spawns another agent from this agent's backend. `spawn_with` takes `SpawnOptions` to change the harness, model, or thinking.

```rust
use nanocode::{Thinking, agent::SpawnOptions};

// Spawns a sibling with a different effort
let options = SpawnOptions::new().thinking(Thinking::Low);
let (sibling, events) = agent.spawn_with(options).await?;
```

### fork

```rust
// Branches the conversation into a new session
pub async fn fork(
    &self,
    request: ForkRequest) -> Result<(Agent, AgentEvents,
), NanocodeError>
```

Returns a new agent whose conversation starts from a point in this one. `ForkRequest::latest()` forks after the last completed turn, `ForkRequest::at_turn(&result)` after one turn, and `ForkRequest::at(checkpoint)` from a checkpoint.

```rust
use nanocode::ForkRequest;

// Tries a second answer from the same point
let (branch, events) = agent.fork(ForkRequest::latest()).await?;
```

### transcript

```rust
// The conversation as prompt messages
pub async fn transcript(
    &self,
) -> Result<Vec<PromptMessage>, NanocodeError>
```

Returns the messages of the conversation. `runtime.switch` uses the transcript to move a conversation to another harness.

```rust
// Counts the messages so far
let messages = agent.transcript().await?;
println!("{} messages", messages.len());
```

### context

```rust
// The workspace and raw history of the session
pub async fn context(
    &self,
) -> Result<AgentSessionContext, NanocodeError>
```

Returns an `AgentSessionContext` with the workspace path and the history items that the backend sends to the model.

```rust
// Prints the workspace of the session
println!("{}", agent.context().await?.workspace());
```

## Errors

### NanocodeError

Every async method returns [`NanocodeError`](/docs/api/rust/types#nanocodeerror). `prompt` returns `InvalidRequest` for an empty prompt or request ID. Methods on a stopped agent return `AgentStopped`. `fork` before the first completed turn returns `ForkBeforeCompletedTurn`.

```rust
use nanocode::{ForkRequest, NanocodeError};

// Forking a new agent fails until one turn completes
match agent.fork(ForkRequest::latest()).await {
    Err(NanocodeError::ForkBeforeCompletedTurn) => {
        eprintln!("run a turn first")
    }
    other => drop(other?),
}
```
