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

# Exemples

> Copiez des modèles ciblés du SDK Agent pour les approbations, le streaming et les exécutions bornées, ou partez d’une recette complète.

Commencez avec un seul agent, un ou deux outils déterministes et une approbation autour des effets de bord. Les extraits ci-dessous supposent un client gateway d’agent dans `client` (et un `ctx` en Go). Ils sont donnés à titre d’illustration : `deployments`, `store`, `search` et `fetchPage` remplacent votre propre code.

## Déploiement soumis à approbation

L’outil de déploiement met l’exécution en pause jusqu’à ce qu’une personne approuve l’appel exact. Enregistrez le résultat en pause, montrez l’appel en attente à un relecteur, puis reprenez avec la décision.

```typescript TypeScript theme={null}
const deploy = defineTool({
  id: "deploy",
  requireApproval: ({ environment }) => environment === "production",
  async execute(input: { environment: string }) {
    return deployments.deploy(input.environment);
  },
});

const agent = createAgent({ id: "release-agent", model: "openai/gpt-6-astra", tools: [deploy] });

let result = await agent.run({ input: "Ship release 42 to production", client });
if (result.run.status === "waiting_for_human") {
  await store.save(result); // montrez result.run.pause.pendingToolCalls à un relecteur

  // Plus tard, une fois que le relecteur a approuvé :
  const callId = result.run.pause!.pendingToolCalls[0].call.id;
  result = await agent.continueRun({ run: result, client, approvals: [{ toolCallId: callId }] });
}
```

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

deploy = define_tool(AgentTool(
    id="deploy",
    description="Deploy the selected release",
    parameters={"type": "object", "properties": {"environment": {"type": "string"}}},
    require_approval=True,
    execute=lambda tool_input, runtime: deployments.deploy(tool_input["environment"]),
))

agent = create_agent({"id": "release-agent", "model": "openai/gpt-6-astra", "tools": [deploy]})

result = agent.run(input="Ship release 42", client=client)
if result.run.status == "waiting_for_human":
    store.save(result)  # montrez result.run.pause.pending_tool_calls à un relecteur

    # Plus tard, une fois que le relecteur a approuvé :
    call_id = result.run.pause.pending_tool_calls[0].call.id
    result = agent.continue_run(run=result, client=client, approvals=[AgentToolDecision(call_id)])
```

```go Go theme={null}
deploy := phaseoagent.DefineTool(phaseoagent.Tool{
  ID:              "deploy",
  Description:     "Deploy the selected release",
  RequireApproval: true,
  Execute: func(input any, runtime phaseoagent.RuntimeContext) (any, error) {
    return deploymentService.Deploy(input)
  },
})

agent := phaseoagent.CreateAgent(phaseoagent.AgentDefinition{
  ID: "release-agent", Model: "openai/gpt-6-astra", Tools: []phaseoagent.Tool{deploy},
})

result, err := agent.Run(ctx, phaseoagent.RunOptions{Input: "Ship release 42", Client: client})
if err == nil && result.Run.Status == "waiting_for_human" {
  store.Save(result) // montrez result.Run.Pause.PendingToolCalls à un relecteur

  // Plus tard, une fois que le relecteur a approuvé :
  callID := result.Run.Pause.PendingToolCalls[0].Call.ID
  result, err = agent.Continue(ctx, phaseoagent.ContinueOptions{
    Run: result, Client: client,
    Approvals: []phaseoagent.ToolDecision{{ToolCallID: callID}},
  })
}
```

```csharp C# theme={null}
var deploy = AgentSdk.DefineTool(new Tool(
    "deploy",
    async (input, runtime) => await deployments.DeployAsync(input, runtime.CancellationToken),
    "Deploy the selected release")
{
    RequireApproval = true,
});

var agent = AgentSdk.CreateAgent(new AgentDefinition
{
    Id = "release-agent", Model = "openai/gpt-6-astra", Tools = new[] { deploy },
});

var result = await agent.Run(new RunOptions { Input = "Ship release 42", Client = client });
if (result.Run.Status == "waiting_for_human")
{
    await store.SaveAsync(result); // montrez result.Run.Pause.PendingToolCalls à un relecteur

    // Plus tard, une fois que le relecteur a approuvé :
    var callId = result.Run.Pause!.PendingToolCalls![0].Call.Id;
    result = await agent.ContinueRun(new ContinueOptions
    {
        Run = result, Client = client, Approvals = new[] { new ToolDecision(callId) },
    });
}
```

```php PHP theme={null}
use Phaseo\AgentSdk\{AgentDefinition, AgentSdk, Tool, ToolDecision};

$deploy = AgentSdk::defineTool(new Tool(
    id: "deploy",
    execute: fn (array $input, $runtime) => $deployments->deploy($input),
    description: "Deploy the selected release",
    requireApproval: true,
));

$agent = AgentSdk::createAgent(new AgentDefinition(
    id: "release-agent", model: "openai/gpt-6-astra", tools: [$deploy],
));

$result = $agent->run(input: "Ship release 42", client: $client);
if ($result->run->status === "waiting_for_human") {
    $store->save($result); // montrez $result->run->pause->pendingToolCalls à un relecteur

    // Plus tard, une fois que le relecteur a approuvé :
    $callId = $result->run->pause->pendingToolCalls[0]->call->id;
    $result = $agent->continueRun(run: $result, client: $client, approvals: [new ToolDecision($callId)]);
}
```

```ruby Ruby theme={null}
deploy = PhaseoAgentSdk.define_tool(
  PhaseoAgentSdk::Tool.new(
    id: "deploy",
    description: "Deploy the selected release",
    require_approval: true,
    execute: ->(input, runtime) { deployments.deploy(input) }
  )
)

agent = PhaseoAgentSdk.create_agent(id: "release-agent", model: "openai/gpt-6-astra", tools: [deploy])

result = agent.run(input: "Ship release 42", client: client)
if result.run.status == "waiting_for_human"
  store.save(result) # montrez result.run.pause.pending_tool_calls à un relecteur

  # Plus tard, une fois que le relecteur a approuvé :
  call_id = result.run.pause.pending_tool_calls.first.call.id
  result = agent.continue_run(
    run: result,
    client: client,
    approvals: [PhaseoAgentSdk::ToolDecision.new(tool_call_id: call_id)]
  )
end
```

```java Java theme={null}
var deploy = AgentSdk.defineTool(new AgentSdk.Tool(
    "deploy", (input, context) -> deployments.deploy(input), "Deploy the selected release",
    Map.of("type", "object"), null,
    null, null, null,
    true, null,             // requireApproval
    null, null, "fail-run"));

var agent = AgentSdk.createAgent(new AgentSdk.AgentDefinition(
    "release-agent", "openai/gpt-6-astra", null, null, List.of(deploy), 12, null, null, null, null));

var result = agent.run(new AgentSdk.RunOptions(
    "Ship release 42", client, null, null, null, null, null, null, null, null));

if (result.run().status().equals("waiting_for_human")) {
    store.save(result); // montrez result.run().pause().pendingToolCalls() à un relecteur

    // Plus tard, une fois que le relecteur a approuvé :
    var callId = result.run().pause().pendingToolCalls().get(0).call().id();
    result = agent.continueRun(new AgentSdk.ContinueOptions(
        result, client, null, null, null, null, null, null, null, null, null,
        List.of(new AgentSdk.ToolDecision(callId)), List.of(), List.of()));
}
```

```rust Rust theme={null}
use phaseo_agent::{
    create_agent, AgentDefinition, ContinueOptions, RunOptions, Tool, ToolDecision,
};
use serde_json::json;

let deploy = Tool::new(
    "deploy",
    "Deploy the selected release",
    json!({ "type": "object", "properties": { "environment": { "type": "string" } } }),
    |input, _context| Ok(json!({ "environment": input["environment"], "deployed": true })),
)
.require_approval();

let agent = create_agent(AgentDefinition::new("release-agent", "openai/gpt-6-astra").tool(deploy));

let mut result = agent.run(&mut client, RunOptions::new("Ship release 42"))?;
if result.run.status == "waiting_for_human" {
    store.save(&result)?; // montrez les appels d’outils en attente à un relecteur

    // Plus tard, une fois que le relecteur a approuvé :
    let call_id = result.run.pause.as_ref().unwrap().pending_tool_calls[0].call.id.clone();
    let mut options = ContinueOptions::new(result);
    options.approvals = vec![ToolDecision { tool_call_id: call_id, reason: None }];
    result = agent.continue_run(&mut client, options)?;
}
```

[État et approbation](https://phaseo.app/docs/fr/v1/sdk-reference/agent/state-and-approval.md) couvre les rejets, les sorties d’outils manuels et l’enregistrement des exécutions.

## Diffuser dans un terminal

```typescript TypeScript theme={null}
const stream = agent.stream({ input, client });

for await (const delta of stream.getTextStream()) {
  process.stdout.write(delta);
}

const completed = await stream.getResult();
```

```python Python theme={null}
stream = agent.stream(input="Research this topic", client=client)

for delta in stream.text_stream():
    print(delta, end="", flush=True)

completed = stream.result()
```

```go Go theme={null}
stream := agent.Stream(ctx, phaseoagent.RunOptions{Input: prompt, Client: client})
for delta := range stream.Text() {
  fmt.Print(delta)
}
result, err := stream.Result()
```

```csharp C# theme={null}
var stream = agent.Stream(new RunOptions { Input = prompt, Client = client });
await foreach (var delta in stream.TextStream()) Console.Write(delta);
var completed = await stream.GetResult();
```

```php PHP theme={null}
$stream = $agent->stream(input: $prompt, client: $client);
foreach ($stream->textStream() as $delta) { echo $delta; }
$result = $stream->getResult();
```

```ruby Ruby theme={null}
stream = agent.stream(input: prompt, client: client)
stream.text_stream.each { |delta| print delta }
result = stream.result
```

```java Java theme={null}
// Le textStream() de Java n’est rempli qu’après la fin de l’exécution ; affichez donc les deltas depuis onEvent
var options = new AgentSdk.RunOptions(prompt, client, null, null, null, null, null, null,
    event -> { if (event.type().equals("response.output_text.delta")) System.out.print(event.details().get("delta")); },
    null);
var completed = agent.stream(options).getResult();
```

Rust `0.2` n’a pas de streaming ; `run` renvoie le résultat une fois l’exécution terminée. Voir [Streaming](https://phaseo.app/docs/fr/v1/sdk-reference/agent/streaming.md).

## Borner une recherche autonome

Combinez plusieurs limites ; la première atteinte termine l’exécution avec le statut `stopped` et une raison d’arrêt comme `max_cost:1`.

```typescript TypeScript theme={null}
import { maxCost, maxDuration, maxTokensUsed, stepCountIs } from "@phaseo/agent-sdk";

const agent = createAgent({
  id: "researcher",
  model: "openai/gpt-6-astra",
  tools: [search, fetchPage],
  maxSteps: 25,
  stopWhen: [
    stepCountIs(20),
    maxTokensUsed(100_000),
    maxCost(1),
    maxDuration(300_000),
  ],
});
```

```python Python theme={null}
from phaseo_agent import create_agent, max_cost, max_duration, max_tokens_used, step_count_is

agent = create_agent({
    "id": "researcher",
    "model": "openai/gpt-6-astra",
    "tools": [search, fetch_page],
    "max_steps": 25,
    "stop_when": [
        step_count_is(20),
        max_tokens_used(100_000),
        max_cost(1),
        max_duration(300_000),
    ],
})
```

```go Go theme={null}
agent := phaseoagent.CreateAgent(phaseoagent.AgentDefinition{
  ID:    "researcher",
  Model: "openai/gpt-6-astra",
  Tools: []phaseoagent.Tool{search, fetchPage},
  StopWhen: []phaseoagent.StopCondition{
    phaseoagent.StepCountIs(20),
    phaseoagent.MaxTokensUsed(100_000),
    phaseoagent.MaxCost(1.00),
    phaseoagent.MaxDuration(5 * time.Minute),
  },
  MaxSteps: 25,
})
```

```csharp C# theme={null}
var agent = AgentSdk.CreateAgent(new AgentDefinition
{
    Id = "researcher",
    Model = "openai/gpt-6-astra",
    Tools = new[] { search, fetchPage },
    StopWhen = new[]
    {
        AgentSdk.StepCountIs(20),
        AgentSdk.MaxTokensUsed(100_000),
        AgentSdk.MaxCost(1.00),
        AgentSdk.MaxDuration(TimeSpan.FromMinutes(5)),
    },
    MaxSteps = 25,
});
```

```php PHP theme={null}
$agent = AgentSdk::createAgent(new AgentDefinition(
    id: "researcher",
    model: "openai/gpt-6-astra",
    tools: [$search, $fetchPage],
    maxSteps: 25,
    stopWhen: [
        AgentSdk::stepCountIs(20),
        AgentSdk::maxTokensUsed(100000),
        AgentSdk::maxCost(1.00),
        AgentSdk::maxDuration(300000),
    ],
));
```

```ruby Ruby theme={null}
agent = PhaseoAgentSdk.create_agent(
  id: "researcher",
  model: "openai/gpt-6-astra",
  tools: [search, fetch_page],
  max_steps: 25,
  stop_when: [
    PhaseoAgentSdk.step_count_is(20),
    PhaseoAgentSdk.max_tokens_used(100_000),
    PhaseoAgentSdk.max_cost(1.00),
    PhaseoAgentSdk.max_duration(300_000)
  ]
)
```

```java Java theme={null}
var agent = AgentSdk.createAgent(new AgentSdk.AgentDefinition(
    "researcher", "openai/gpt-6-astra", null, null, List.of(search, fetchPage), 25,
    null, null, null, null,
    List.of(
        AgentSdk.stepCountIs(20),
        AgentSdk.maxTokensUsed(100_000),
        AgentSdk.maxCost(1.00),
        AgentSdk.maxDuration(Duration.ofMinutes(5))),
    null, null));
```

```rust Rust theme={null}
// Rust 0.2 n’a pas de conditions d’arrêt ; plafonnez plutôt les tours du modèle.
let agent = create_agent(
    AgentDefinition::new("researcher", "openai/gpt-6-astra")
        .tool(search)
        .tool(fetch_page)
        .max_steps(20),
);
```

Le format numérique de la raison d’arrêt suit le langage : `max_cost:1` en Go, C# et PHP, `max_cost:1.0` en Ruby et Java. En Rust, atteindre la limite d’étapes termine l’exécution en `stopped` avec la raison `max_steps:20`. Voir [Conditions d’arrêt](https://phaseo.app/docs/fr/v1/sdk-reference/agent/stop-conditions.md).

## Combiner les fonctionnalités pour des produits courants

| Produit | Combinez |
| - | - |
| Extraction structurée | [Validation de la sortie](https://phaseo.app/docs/fr/v1/sdk-reference/agent/run-controls.md#validate-the-final-output), un format de réponse strict sur le client gateway, des nouvelles tentatives bornées |
| Tri du support | Un `preset` pour le routage, des [outils](https://phaseo.app/docs/fr/v1/sdk-reference/agent/tools.md) de consultation, une sortie structurée pour la classification finale |
| Note de recherche | Recherche gérée via les outils gateway du client gateway, texte [diffusé en streaming](https://phaseo.app/docs/fr/v1/sdk-reference/agent/streaming.md), [conditions d’arrêt](https://phaseo.app/docs/fr/v1/sdk-reference/agent/stop-conditions.md) |
| Revue de code ou assistant de code | Outils de fichiers, événements de progression, [approbation](https://phaseo.app/docs/fr/v1/sdk-reference/agent/state-and-approval.md) avant les modifications |
| Runbook d’exploitation | Outils de statut, escalade manuelle, une exécution enregistrée reprise plus tard |

Le package TypeScript fournit des versions complètes de quatre d’entre eux dans son dossier `examples/` : `research-brief-agent.ts`, `support-triage-agent.ts`, `coding-review-agent.ts` et `parallel-tool-agent.ts` (des outils locaux indépendants exécutés en parallèle).

## Suivre une recette pas à pas

> [card] [Boucle d’agent durable](https://phaseo.app/docs/fr/v1/cookbook/agent-sdk-durable-loop.md)
>
> Persistez une exécution renvoyée et reprenez-la dans une requête ultérieure.

> [card] [Note de recherche](https://phaseo.app/docs/fr/v1/cookbook/agent-sdk-research-brief.md)
>
> Combinez un agent avec une recherche web sourcée.

> [card] [Tri du support](https://phaseo.app/docs/fr/v1/cookbook/agent-sdk-support-triage.md)
>
> Gardez les valeurs par défaut de routage et de prompt dans un préréglage géré.

> [card] [Revue de code](https://phaseo.app/docs/fr/v1/cookbook/agent-sdk-coding-review.md)
>
> Connectez des outils locaux ciblés à un workflow de développement.

> [card] [Outils parallèles](https://phaseo.app/docs/fr/v1/cookbook/agent-sdk-parallel-tools.md)
>
> Répartissez des appels d’outils indépendants sans changer l’ordre des résultats.

> [card] [Extraction structurée (Python)](https://phaseo.app/docs/fr/v1/cookbook/agent-sdk-python-structured-extraction.md)
>
> Extrayez du JSON structuré avec le SDK Agent Python.

> [card] [Runbook d’exploitation (Go)](https://phaseo.app/docs/fr/v1/cookbook/agent-sdk-go-ops-runbook.md)
>
> Construisez un agent de runbook d’exploitation en Go.

> [card] [Tri de tickets (C#)](https://phaseo.app/docs/fr/v1/cookbook/agent-sdk-csharp-ticket-triage.md)
>
> Triez des tickets avec le SDK Agent C#.

> [card] [Revue de contenu (PHP)](https://phaseo.app/docs/fr/v1/cookbook/agent-sdk-php-content-review.md)
>
> Relisez du contenu CMS avec le SDK Agent PHP.

> [card] [Résumé de notes (Ruby)](https://phaseo.app/docs/fr/v1/cookbook/agent-sdk-ruby-rag-notes.md)
>
> Résumez des notes internes avec le SDK Agent Ruby.

Les cinq premières recettes utilisent TypeScript.


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