> ## Documentation Index
> Fetch the complete documentation index at: https://phaseo.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Phaseo Gateway base URL: https://api.phaseo.app/v1. Send `Authorization: Bearer $PHASEO_API_KEY` with every request.
> Model IDs look like `provider/model`, for example `openai/gpt-6-astra`. Do not guess IDs: list them with `GET /v1/models` or check https://phaseo.app/models. `phaseo/free` routes to an available free model and needs no wallet balance.
> For new text integrations prefer `POST /v1/responses`. `POST /v1/chat/completions` (OpenAI format) and `POST /v1/messages` (Anthropic format) suit existing code.
> The full API contract is https://phaseo.app/docs/openapi/v1/openapi.yaml. Official SDKs: `@phaseo/sdk` (TypeScript) and `phaseo` (Python), plus Go, C#, PHP, Ruby and Rust.
> Search these docs over MCP at https://phaseo.app/docs/mcp, and install Phaseo skills with `npx skills add https://phaseo.app/docs`. If a page is wrong or out of date, report it with the MCP `submit_feedback` tool.
> Manage Phaseo accounts with the `phaseo` CLI (`npm install -g @phaseo/cli`, then `phaseo login` or `phaseo login --device-code`), the `/v1` Management API or the MCP server at `https://mcp.phaseo.app/mcp?access=manage`. Do not send users to the dashboard for account tasks. A person is still needed for sign-up, approving a sign-in, paying the first top-up on the checkout link that `phaseo credits add` returns when no card is saved, confirming each saved-card top-up from the emailed link, and account security (password, MFA, passkeys). Create API keys with `phaseo keys create --name <name> --json`; never guess one. Credit top-ups need `phaseo login --scopes billing:write` first. Task map: https://phaseo.app/docs/v1/developers/manage-from-an-agent.md.

# Build with the Rust Agent SDK

> Create a synchronous Rust agent that calls a local tool through Phaseo Gateway.

Use this guide to build a small tool-using agent and inspect its completed run.

## Define a tool

```rust theme={null}
use phaseo_agent::{define_tool, Tool};
use serde_json::json;

let lookup = define_tool(Tool::new(
    "lookup_docs",
    "Look up a Phaseo documentation topic",
    json!({
        "type": "object",
        "properties": {
            "topic": { "type": "string" }
        },
        "required": ["topic"]
    }),
    |input, context| {
        Ok(json!({
            "topic": input["topic"],
            "run_id": context.run_id,
            "found": true
        }))
    },
));
```

The closure runs locally. Its `RuntimeContext` includes the run ID, agent ID, step index, application context, and original tool call.

## Create the agent

```rust theme={null}
use phaseo_agent::{create_agent, AgentDefinition};

let agent = create_agent(
    AgentDefinition::new("docs-agent", "openai/gpt-6-astra")
        .instructions("Use lookup_docs when it helps. Finish with a concise answer.")
        .max_steps(6)
        .tool(lookup),
);
```

## Run through Phaseo Gateway

```rust theme={null}
use phaseo_agent::{create_gateway_agent_client, RunOptions};

let mut client = create_gateway_agent_client("openai/gpt-6-astra")?;
let mut options = RunOptions::new("Explain when to use routing presets.");
options.context = serde_json::json!({
    "workspace": "docs"
});

let result = agent.run(&mut client, options)?;
println!("{}", result.output);
```

## Complete example

```rust theme={null}
use phaseo_agent::{
    create_agent, create_gateway_agent_client, define_tool, AgentDefinition,
    RunOptions, Tool,
};
use serde_json::json;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let lookup = define_tool(Tool::new(
        "lookup_docs",
        "Look up a Phaseo documentation topic",
        json!({
            "type": "object",
            "properties": {
                "topic": { "type": "string" }
            },
            "required": ["topic"]
        }),
        |input, context| {
            Ok(json!({
                "topic": input["topic"],
                "run_id": context.run_id,
                "found": true
            }))
        },
    ));

    let agent = create_agent(
        AgentDefinition::new("docs-agent", "openai/gpt-6-astra")
            .instructions("Use lookup_docs when helpful. Answer concisely.")
            .max_steps(6)
            .tool(lookup),
    );

    let mut client = create_gateway_agent_client("openai/gpt-6-astra")?;
    let result = agent.run(
        &mut client,
        RunOptions::new("Explain when to use routing presets."),
    )?;

    println!("{}", result.output);
    println!("steps: {}", result.run.step_count);
    println!("tokens: {}", result.usage.total_tokens);
    Ok(())
}
```

## Run state

`RunResult` contains:

* `run`: status, IDs, effective model, step limit, context, and pause state
* `steps`: each model turn, request ID, provider, model, finish reason, tool calls, and usage
* `messages`: the complete model and tool message history
* `output`: the final output value
* `usage`: aggregate token values and any cost supplied by the model client

## Current execution model

Rust Agent SDK runs are synchronous. Local tools execute one at a time. Use an application worker thread or task boundary when a run should not block a request handler.

## Next

* [Tools and approvals](https://phaseo.app/docs/v1/sdk-reference/rust/agent-sdk-tools.md)
* [Persist and resume runs](https://phaseo.app/docs/v1/sdk-reference/rust/agent-sdk-state-and-approval.md)
* [Events, retries, and errors](https://phaseo.app/docs/v1/sdk-reference/rust/agent-sdk-events-and-errors.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.