> ## 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.

# Utilisation du SDK Agent

> Construisez un premier agent qui utilise des outils avec le SDK Agent Phaseo et suivez le déroulement d’une exécution.

Définissez un outil, créez un agent et exécutez-le avec un client gateway. Le modèle appelle votre outil, le SDK l’exécute et renvoie le résultat, puis l’exécution se termine quand le modèle répond sans appeler d’outil, se met en pause pour une personne ou qu’une [condition d’arrêt](https://phaseo.app/docs/fr/v1/sdk-reference/agent/stop-conditions.md) est remplie. Si l’exécution atteint d’abord sa limite d’étapes, le SDK lève une erreur ; seul Rust renvoie l’exécution avec le statut `stopped`. Phaseo n’héberge pas l’agent et ne stocke pas ses exécutions ; c’est votre application qui s’en charge.

## Construire un premier agent

```typescript TypeScript theme={null}
import {
  createAgent,
  createGatewayAgentClient,
  defineTool,
} from "@phaseo/agent-sdk";

const lookupDocs = defineTool({
  id: "lookup-docs",
  description: "Look up an internal docs page by slug.",
  parameters: {
    type: "object",
    properties: {
      slug: { type: "string" },
    },
    required: ["slug"],
    additionalProperties: false,
  },
  async execute(input: { slug: string }) {
    return {
      slug: input.slug,
      url: `https://phaseo.app/docs/v1/${input.slug}`,
    };
  },
});

const agent = createAgent({
  id: "support-docs-agent",
  model: "openai/gpt-6-astra",
  instructions: "Use tools when helpful and finish with a concise answer.",
  tools: [lookupDocs],
});

const result = await agent.run({
  input: "Find the docs page for presets and explain when to use them.",
  client: createGatewayAgentClient({
    clientOptions: {
      apiKey: process.env.PHASEO_API_KEY!,
    },
  }),
});

console.log(result.output);
```

```python Python theme={null}
import os
from phaseo_agent import AgentTool, create_agent, create_gateway_agent_client, define_tool

lookup_docs = define_tool(AgentTool(
    id="lookup-docs",
    description="Look up an internal docs page by slug.",
    parameters={
        "type": "object",
        "properties": {"slug": {"type": "string"}},
        "required": ["slug"],
        "additionalProperties": False,
    },
    execute=lambda tool_input, runtime: {
        "slug": tool_input["slug"],
        "url": f"https://phaseo.app/docs/v1/{tool_input['slug']}",
    },
))

agent = create_agent({
    "id": "support-docs-agent",
    "model": "openai/gpt-6-astra",
    "instructions": "Use tools when helpful and finish with a concise answer.",
    "tools": [lookup_docs],
})

result = agent.run(
    input="Find the docs page for presets and explain when to use them.",
    client=create_gateway_agent_client(client_options={"api_key": os.environ["PHASEO_API_KEY"]}),
)

print(result.output)
```

```go Go theme={null}
package main

import (
  "context"
  "fmt"

  phaseoagent "github.com/phaseoteam/Phaseo/packages/sdk/agent-sdk-go"
)

func main() {
  client, err := phaseoagent.CreateGatewayAgentClient(phaseoagent.GatewayAgentClientOptions{})
  if err != nil {
    panic(err) // PHASEO_API_KEY est obligatoire
  }

  lookup := phaseoagent.DefineTool(phaseoagent.Tool{
    ID:          "lookup_docs",
    Description: "Look up a Phaseo documentation topic",
    Parameters: map[string]any{
      "type":       "object",
      "properties": map[string]any{"topic": map[string]any{"type": "string"}},
      "required":   []string{"topic"},
    },
    Execute: func(input any, runtime phaseoagent.RuntimeContext) (any, error) {
      args, _ := input.(map[string]any)
      return map[string]any{"topic": args["topic"], "found": true}, nil
    },
  })

  agent := phaseoagent.CreateAgent(phaseoagent.AgentDefinition{
    ID:           "docs-agent",
    Model:        "openai/gpt-6-astra",
    Instructions: "Use tools when helpful and finish with a concise answer.",
    Tools:        []phaseoagent.Tool{lookup},
    MaxSteps:     6,
  })

  result, err := agent.Run(context.Background(), phaseoagent.RunOptions{
    Input:  "Explain when to use routing presets.",
    Client: client,
  })
  if err != nil {
    panic(err)
  }

  fmt.Println(result.Output)
  fmt.Println(result.Run.Status, result.Usage.TotalTokens)
}
```

```csharp C# theme={null}
using System.Text.Json;
using PhaseoAgentSdk;

var lookup = AgentSdk.DefineTool(new Tool(
    "lookup_docs",
    async (input, runtime) =>
    {
        var topic = ((JsonElement)input!).GetProperty("topic").GetString();
        return new { topic, found = true };
    },
    "Look up a Phaseo documentation topic",
    new Dictionary<string, object?>
    {
        ["type"] = "object",
        ["properties"] = new Dictionary<string, object?> { ["topic"] = new { type = "string" } },
        ["required"] = new[] { "topic" },
    }));

var agent = AgentSdk.CreateAgent(new AgentDefinition
{
    Id = "docs-agent",
    Model = "openai/gpt-6-astra",
    Instructions = "Use tools when helpful and finish with a concise answer.",
    Tools = new[] { lookup },
    MaxSteps = 6,
});

var result = await agent.Run(new RunOptions
{
    Input = "Explain when to use routing presets.",
    Client = AgentSdk.CreateGatewayAgentClient(), // lève une exception si PHASEO_API_KEY manque
});

Console.WriteLine(result.Output);
Console.WriteLine($"{result.Run.Status} {result.Usage.TotalTokens}");
```

```php PHP theme={null}
<?php
require "vendor/autoload.php";

use Phaseo\AgentSdk\AgentDefinition;
use Phaseo\AgentSdk\AgentSdk;
use Phaseo\AgentSdk\Tool;

$lookup = AgentSdk::defineTool(new Tool(
    id: "lookup_docs",
    execute: fn (array $input, $runtime) => ["topic" => $input["topic"], "found" => true],
    description: "Look up a Phaseo documentation topic",
    parameters: [
        "type" => "object",
        "properties" => ["topic" => ["type" => "string"]],
        "required" => ["topic"],
    ],
));

$agent = AgentSdk::createAgent(new AgentDefinition(
    id: "docs-agent",
    model: "openai/gpt-6-astra",
    instructions: "Use tools when helpful and finish with a concise answer.",
    tools: [$lookup],
    maxSteps: 6,
));

$result = $agent->run(
    input: "Explain when to use routing presets.",
    client: AgentSdk::createGatewayAgentClient() // lève une exception si PHASEO_API_KEY manque
);

echo $result->output . PHP_EOL;
echo $result->run->status . " " . $result->usage["total_tokens"] . PHP_EOL;
```

```ruby Ruby theme={null}
require "phaseo_agent_sdk"

lookup = PhaseoAgentSdk.define_tool(
  PhaseoAgentSdk::Tool.new(
    id: "lookup_docs",
    description: "Look up a Phaseo documentation topic",
    parameters: {
      type: "object",
      properties: { topic: { type: "string" } },
      required: ["topic"]
    },
    execute: ->(input, runtime) { { topic: input["topic"], found: true } }
  )
)

agent = PhaseoAgentSdk.create_agent(
  id: "docs-agent",
  model: "openai/gpt-6-astra",
  instructions: "Use tools when helpful and finish with a concise answer.",
  tools: [lookup],
  max_steps: 6
)

result = agent.run(
  input: "Explain when to use routing presets.",
  client: PhaseoAgentSdk.create_gateway_agent_client # lève une exception si PHASEO_API_KEY manque
)

puts result.output
puts "#{result.run.status} #{result.usage[:total_tokens]}"
```

```java Java theme={null}
import app.phaseo.agent.AgentSdk;
import java.time.Duration;
import java.util.List;
import java.util.Map;

var lookup = AgentSdk.defineTool(new AgentSdk.Tool(
    "lookup_docs",
    (input, context) -> Map.of("topic", ((Map<?, ?>) input).get("topic"), "found", true),
    "Look up a Phaseo documentation topic",
    Map.of(
        "type", "object",
        "properties", Map.of("topic", Map.of("type", "string")),
        "required", List.of("topic")),
    Duration.ofSeconds(10)
));

var agent = AgentSdk.createAgent(new AgentSdk.AgentDefinition(
    "docs-agent",                       // id
    "openai/gpt-6-astra",               // model
    null,                               // preset
    "Use tools when helpful and finish with a concise answer.", // instructions
    List.of(lookup),                    // tools
    6,                                  // maxSteps
    null, null, null, null              // parseOutput, humanReview, modelRetry, toolExecution
));

var result = agent.run(new AgentSdk.RunOptions(
    "Explain when to use routing presets.",  // input
    AgentSdk.createGatewayAgentClient(),     // lève une exception si PHASEO_API_KEY manque
    null, null, null, null, null, null, null, null
));

System.out.println(result.output());
System.out.println(result.run().status() + " " + result.usage().totalTokens());
```

```rust 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(())
}
```

L’ID de l’outil est le nom de fonction que voit le modèle, et ses paramètres sont le JSON Schema que le modèle remplit. Les arguments arrivent dans votre code sous la forme native de chaque langage :

| Langage | L’outil reçoit | Remarques |
| - | - | - |
| TypeScript | Objet typé | `execute(input, context)` |
| Python | `dict` | `execute(tool_input, runtime)` |
| Go | `any` (JSON décodé, généralement `map[string]any`) | `Execute(input, runtime) (any, error)` |
| C# | `JsonElement` | `Execute(input, runtime)`, attendu avec await |
| PHP | Tableau associatif | `execute(array $input, $runtime)` |
| Ruby | Hash à clés de type chaîne | Construisez les outils avec `PhaseoAgentSdk::Tool.new` ; `define_tool` renvoie ce que vous lui passez, donc un simple Hash ne fonctionne pas |
| Java | `Map` | Les records sont positionnels ; passez `null` pour tout ce que vous ne définissez pas |
| Rust | `serde_json::Value` | La closure s’exécute localement ; `RuntimeContext` contient l’ID d’exécution, l’ID de l’agent, l’index de l’étape, le contexte applicatif et l’appel d’outil |

Si l’agent, l’exécution et le client ne définissent ni modèle ni préréglage, le client gateway envoie `phaseo/free`. Le `create_gateway_agent_client` de Rust prend le modèle en argument.

## Déroulement d’une exécution

```mermaid theme={null}
flowchart TD
  start([run]) --> turn[Envoyer les messages au modèle]
  turn --> exec[Exécuter les appels d’outils qui ne demandent aucune entrée, ajouter leurs résultats]
  exec --> gate{{"Un appel attend une approbation, une personne ou une sortie manuelle ?"}}
  gate -- Oui --> paused([Renvoyer l’exécution : waiting_for_human])
  gate -- Non --> stopcheck{{"Condition d’arrêt atteinte ?"}}
  stopcheck -- Oui --> stopped([Renvoyer l’exécution : stopped])
  stopcheck -- Non --> more{{"Le modèle a-t-il appelé des outils ?"}}
  more -- Non --> done([Renvoyer l’exécution : completed])
  more -- Oui --> limit{{"Limite d’étapes épuisée ?"}}
  limit -- Oui --> failed([Échec : Max steps exceeded])
  limit -- Non --> turn
  paused -. reprendre .-> turn
```

Chaque étape est enregistrée comme point de reprise dans le résultat d’exécution renvoyé. Pour reprendre entre plusieurs requêtes ou après un redémarrage, enregistrez ce résultat dans votre propre stockage et passez-le à la méthode de reprise, ou donnez à l’agent un accesseur d’état ; voir [État et approbation](https://phaseo.app/docs/fr/v1/sdk-reference/agent/state-and-approval.md). La limite d’étapes et ce qui se passe quand elle est épuisée diffèrent selon le langage :

> [tab] TypeScript
>
> Chaque appel à `run()` ou `continueRun()` effectue au plus 12 étapes, sauf si vous définissez `maxSteps` ; au-delà, il lève `Max steps exceeded`. Utilisez les [conditions d’arrêt](https://phaseo.app/docs/fr/v1/sdk-reference/agent/stop-conditions.md) pour terminer proprement une exécution.

> [tab] Python
>
> Une exécution effectue au plus 12 étapes, sauf si vous définissez `max_steps` ; au-delà, elle lève `RuntimeError`. Les conditions d’arrêt ne sont vérifiées que sur une étape où le modèle ne fait aucun appel d’outil, donc l’ordre diffère du diagramme : une boucle d’outils continue jusqu’à ce qu’elle se mette en pause, réponde ou épuise `max_steps`.

> [tab] Go
>
> Une exécution qui demande plus de `MaxSteps` tours du modèle (8 par défaut) échoue avec `Max steps exceeded (N)`.

> [tab] C#
>
> Une exécution qui demande plus de `MaxSteps` tours du modèle (12 par défaut) lève `InvalidOperationException("Max steps exceeded (N)")`.

> [tab] PHP
>
> Une exécution qui demande plus de `maxSteps` tours du modèle (12 par défaut) lève `Max steps exceeded (N)`.

> [tab] Ruby
>
> Une exécution qui demande plus de `max_steps` tours du modèle (12 par défaut) lève `Max steps exceeded (N)`.

> [tab] Java
>
> Une exécution qui demande plus de `maxSteps` tours du modèle (12 par défaut) lève `Max steps exceeded (N)`.

> [tab] Rust
>
> Une exécution effectue au plus 8 tours du modèle, sauf si vous appelez `.max_steps(n)` ou définissez `RunOptions.max_steps`. Atteindre la limite ne provoque pas d’échec : l’exécution se termine avec `run.status` à `stopped` et `run.stop_reason` à `max_steps:<limit>`. Les exécutions sont synchrones et les outils locaux s’exécutent un par un ; utilisez donc un thread de travail ou une frontière de tâche quand une exécution ne doit pas bloquer un gestionnaire de requêtes.

## Lire le résultat de l’exécution

Chaque exécution renvoie les mêmes parties. Les noms de champs suivent la casse de chaque langage (`output`, `Output`, `output()`) :

| Partie | Contenu |
| - | - |
| `run` | Statut, ID, modèle effectif, limite d’étapes, contexte, état de pause et raison d’arrêt |
| `steps` | Un enregistrement par tour du modèle : ID de requête, fournisseur, modèle, raison de fin, avertissements, appels d’outils et utilisation |
| `messages` | Toute la conversation, y compris les résultats des outils |
| `output` | La sortie finale |
| `usage` | Tokens d’entrée, de sortie, en cache et totaux, et coût |

Le `usage.cost` de Rust provient uniquement d’un `meta.cost` ou `cost` numérique dans la réponse ; il ne convertit pas `cost_nanos` ni `cost_cents`. Utilisez la réponse du Gateway ou l’enregistrement de génération pour le suivi des dépenses en Rust.

## Trouver la bonne fonctionnalité

| Pour… | Page |
| - | - |
| Donner au modèle des outils locaux, manuels ou qui signalent leur progression | [Outils](https://phaseo.app/docs/fr/v1/sdk-reference/agent/tools.md) |
| Se mettre en pause pour une approbation ou une personne, puis reprendre | [État et approbation](https://phaseo.app/docs/fr/v1/sdk-reference/agent/state-and-approval.md) |
| Afficher le texte et l’activité des outils au fil de l’eau | [Streaming](https://phaseo.app/docs/fr/v1/sdk-reference/agent/streaming.md) |
| Afficher une chronologie des messages, du raisonnement et des appels d’outils | [Éléments](https://phaseo.app/docs/fr/v1/sdk-reference/agent/items.md) |
| Borner les étapes, les tokens, le coût ou la durée | [Conditions d’arrêt](https://phaseo.app/docs/fr/v1/sdk-reference/agent/stop-conditions.md) |
| Changer de modèle ou d’outils entre les tours | [Tours dynamiques](https://phaseo.app/docs/fr/v1/sdk-reference/agent/dynamic-turns.md) |
| Obtenir une sortie typée, réessayer les appels au modèle, utiliser un préréglage | [Sorties et nouvelles tentatives](https://phaseo.app/docs/fr/v1/sdk-reference/agent/run-controls.md) |
| Journaliser ou auditer chaque étape | [Hooks de cycle de vie](https://phaseo.app/docs/fr/v1/sdk-reference/agent/lifecycle-hooks.md) |
| Enregistrer l’utilisation, le coût et les ID de requête d’une exécution | [Observabilité](https://phaseo.app/docs/fr/v1/sdk-reference/agent/observability.md) |
| Gérer les erreurs du gateway, de schéma et de limite d’étapes | [Événements et erreurs](https://phaseo.app/docs/fr/v1/sdk-reference/agent/events-and-errors.md) |
| Inspecter les exécutions en local | [DevTools](https://phaseo.app/docs/fr/v1/sdk-reference/agent/devtools.md) |

Chaque export est listé dans la [référence de l’API](https://phaseo.app/docs/fr/v1/sdk-reference/agent/api-reference.md), et des agents complets se trouvent dans [Exemples](https://phaseo.app/docs/fr/v1/sdk-reference/agent/examples.md).


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