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

# Hooks de cycle de vie

> Recevez un événement à chaque étape de l’exécution d’un agent pour mettre à jour une interface, écrire des enregistrements d’audit ou alimenter la télémétrie.

Passez un gestionnaire d’événements à une exécution ou à une reprise pour recevoir un événement quand l’exécution démarre, quand chaque tour du modèle commence et se termine, quand chaque outil s’exécute, quand l’exécution se met en pause et quand elle se termine. Utilisez-le pour mettre à jour votre interface, écrire des enregistrements d’audit ou alimenter votre télémétrie existante.

```typescript TypeScript theme={null}
const result = await agent.run({
  input,
  client,
  onEvent(event) {
    console.log(event.type, event.runId);
  },
});
```

```python Python theme={null}
def on_event(event):
    logger.info("%s %s", event["type"], event["run_id"])

result = agent.run(input="Summarise this ticket", client=client, on_event=on_event)
```

```go Go theme={null}
result, err := agent.Run(ctx, phaseoagent.RunOptions{
  Input:  prompt,
  Client: client,
  OnEvent: func(event phaseoagent.AgentEvent) {
    logger.Info("agent event",
      "type", event.Type,
      "run_id", event.RunID,
      "details", event.Details,
    )
  },
})
```

```csharp C# theme={null}
var result = await agent.Run(new RunOptions
{
    Input = prompt,
    Client = client,
    OnEvent = value => logger.LogInformation(
        "{EventType} {RunId} {Details}", value.Type, value.RunId, value.Details),
});
```

```php PHP theme={null}
$result = $agent->run(
    input: $prompt,
    client: $client,
    onEvent: function (array $event) use ($logger): void {
        $logger->info("agent event", $event);
    }
);
```

```ruby Ruby theme={null}
result = agent.run(
  input: prompt,
  client: client,
  on_event: ->(event) { logger.info("agent event #{event.inspect}") }
)
```

```java Java theme={null}
var result = agent.run(new AgentSdk.RunOptions(
    prompt, client, null, null, null, null, null, null,
    event -> logger.info("{} {} {}", event.type(), event.runId(), event.details()),
    null));
```

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

let mut on_event = |event: &AgentEvent| {
    println!("{} run={} details={}", event.event_type, event.run_id, event.details);
};

let result = agent.run_with_events(
    &mut client,
    RunOptions::new("Check project health"),
    Some(&mut on_event),
)?;
```

## Où placer le gestionnaire et ce qu’il reçoit

| Langage | Gestionnaire | Forme de l’événement |
| - | - | - |
| TypeScript | `onEvent` dans les options d’exécution et de reprise | Objet avec `type`, `runId`, `agentId`, `timestamp`, plus les champs de l’événement en camelCase (`stepIndex`, `toolCallId`) |
| Python | `on_event` sur `run()`, `stream()` ou une reprise | Dict avec `type`, `run_id`, `agent_id`, `timestamp`, `status`, plus les clés de l’événement |
| Go | `OnEvent` sur `RunOptions` ou `ContinueOptions` | `AgentEvent` avec `Type`, `RunID`, `AgentID`, `Timestamp`, `Status`, `Details` |
| C# | `OnEvent` sur `RunOptions` ou `ContinueOptions` | `AgentEvent` avec `Type`, `RunId`, `AgentId`, `Timestamp`, `Status`, `Details` |
| PHP | Callable `onEvent` sur `run()` ou `continueRun()` | Tableau avec `type`, `run_id`, `agent_id`, `timestamp`, `status`, et les clés de l’événement fusionnées au premier niveau |
| Ruby | `on_event:` sur `run` ou `continue_run` | Hash avec `:type`, `:run_id`, `:agent_id`, `:timestamp`, `:status`, et les clés de l’événement fusionnées sous forme de symboles |
| Java | `Consumer<AgentEvent>` comme argument `onEvent` de `RunOptions` ou `ContinueOptions` | `AgentEvent` avec `type()`, `runId()`, `agentId()`, `timestamp()`, `status()`, `details()` |
| Rust | Callback passé à `run_with_events` ou `continue_with_events` | `&AgentEvent` avec `event_type`, `run_id`, `agent_id`, `timestamp_ms`, `details` (JSON) |

## Événements émis par le runtime

Les clés de détail sont listées ci-dessous en snake\_case ; TypeScript utilise la forme camelCase.

| Événement | Quand | Détails | Langages |
| - | - | - | - |
| `run.started` | Une exécution commence | Aucun | Tous |
| `run.resumed` | Une reprise commence | `previous_status` | Tous |
| `step.started` | Un tour du modèle commence | `step_index` | Tous sauf Rust |
| `model.requested` | Chaque tentative auprès du modèle, nouvelles tentatives comprises | `step_index`, `attempt`, `model` | Tous sauf Rust |
| `model.retrying` | Avant une nouvelle tentative | | TypeScript |
| `model.completed` | Le modèle a répondu | `step_index`, `attempt`, `request_id`, `model` | Tous sauf Rust |
| `model.failed` | Une requête au modèle a échoué | | TypeScript |
| `tool.started` | Un outil commence | `tool_call_id`, `tool_name` | Tous |
| `tool.preliminary_result` | L’outil a signalé sa progression | `tool_call_id`, `tool_name`, `result` | Tous sauf Rust |
| `tool.completed` | Un outil a renvoyé un résultat | `tool_call_id`, `tool_name`, `output` | Tous |
| `tool.failed` | Un outil a échoué (le déclencheur diffère ; voir [Événements et erreurs](https://phaseo.app/docs/fr/v1/sdk-reference/agent/events-and-errors.md#which-events-fire-when-something-fails)) | `tool_call_id`, `tool_name`, `error` | Tous sauf Rust |
| `step.completed`, `step.failed`, `step.cancelled` | Une étape se termine | `step_index` | TypeScript |
| `checkpoint.saved` | Une étape s’est terminée | `step_index` | Tous sauf Rust |
| `history.repaired` | Une reprise a répondu à des appels d’outils restés sans résultat | | TypeScript |
| `run.waiting_for_human` | L’exécution s’est mise en pause | `step_index`, `pause` | Tous sauf Rust |
| `run.completed` | Le modèle a donné une réponse finale | `output` | Tous |
| `run.stopped` | Une condition d’arrêt a mis fin à l’exécution (TypeScript) ou la limite d’étapes a été atteinte (Rust) | `stop_reason` (TypeScript), `reason` (Rust) | TypeScript, Rust |
| `run.cancelled` | L’exécution a été annulée | | TypeScript |
| `run.failed` | L’exécution a échoué (le déclencheur diffère ; voir [Événements et erreurs](https://phaseo.app/docs/fr/v1/sdk-reference/agent/events-and-errors.md#which-events-fire-when-something-fails)) | `error` | Tous sauf Rust |
| `response.output_text.delta`, `response.reasoning.delta`, `response.item` et les autres événements `response.*` | Exécutions en streaming uniquement | | Tous sauf Rust |

Rust `0.2` utilise ses propres noms pour certains événements :

| Événement Rust | Équivalent | Détails |
| - | - | - |
| `model.request.started` | `step.started` et `model.requested`, envoyés une fois par étape et non par tentative | `step_index` |
| `model.response.completed` | `model.completed` | `step_index`, `attempts` |
| `tool.started`, `tool.completed` | Les mêmes événements | `tool_call_id`, `name` ; `tool.completed` ajoute `is_error` |
| `run.paused` | `run.waiting_for_human` | Aucun |
| `run.stopped` | Envoyé quand la limite d’étapes est atteinte | `reason` |

Une exécution qui se termine sur une [condition d’arrêt](https://phaseo.app/docs/fr/v1/sdk-reference/agent/stop-conditions.md) envoie `run.stopped` en TypeScript et aucun événement terminal en Python, Go, C#, PHP, Ruby ou Java ; lisez plutôt le statut de l’exécution. En TypeScript, `step.completed` est envoyé après l’enregistrement du point de reprise de l’étape ; les consommateurs de persistance et de télémétrie peuvent donc le traiter comme une frontière stable.

## Événements de flux

Avec le streaming, les mêmes événements de cycle de vie arrivent en même temps que les événements `response.*` du modèle. En TypeScript, Python, Go, C# et Java, le gestionnaire les reçoit ; en PHP et Ruby, ils apparaissent aussi dans `fullStream()` / `full_stream`. Rust n’a pas de streaming. [Streaming](https://phaseo.app/docs/fr/v1/sdk-reference/agent/streaming.md) décrit les consommateurs de flux.

## Garder les gestionnaires rapides

Le runtime attend le gestionnaire avant de continuer : rendez donc la main rapidement et déplacez le stockage lent ou le travail réseau dans une file d’attente. Masquez les entrées et sorties d’outils sensibles avant que les événements ne quittent votre processus.

| Langage | Exécution du gestionnaire |
| - | - |
| TypeScript | Attendu avant que l’exécution continue |
| Python | Appelé de façon synchrone |
| Go | En ligne ; les outils concurrents l’appellent depuis plusieurs goroutines, rendez-le donc sûr pour un usage concurrent |
| C# | En ligne ; les outils concurrents l’appellent depuis plusieurs tâches, rendez-le donc thread-safe |
| PHP | En ligne |
| Ruby | En ligne ; les outils concurrents l’appellent depuis leurs threads, rendez-le donc thread-safe |
| Java | En ligne ; les outils concurrents l’appellent depuis les threads du pool, rendez-le donc thread-safe |
| Rust | Sur le thread de l’exécution |

## Choisir les événements pour une interface produit

Utilisez `response.output_text.delta` pour le texte de réponse en direct, les événements d’outils pour les cartes d’appels d’outils et les indicateurs de progression, `run.waiting_for_human` (Rust : `run.paused`) pour afficher les contrôles d’approbation ou de saisie, et les événements terminaux d’exécution pour fermer les états de chargement. Pour garder une trace locale d’exécutions complètes pendant le développement, utilisez [DevTools](https://phaseo.app/docs/fr/v1/sdk-reference/agent/devtools.md).


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