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

# Gérer une conversation

> Enchaîner les tours, conserver la session, reprendre après une coupure et enregistrer le résultat.

**Créez une session par conversation, pas une session par question.** Elle garde l'état côté serveur et reste attachée à la version du domaine publiée au moment de sa création.

## Le cycle avec le SDK

| Moment | Python | TypeScript | Résultat |
| - | - | - | - |
| Démarrer | `client.start_session()` | `client.startSession()` | Un handle de session. |
| Première question | `session.next()` | `session.next()` | Une décision et ses candidates. |
| Réponse reçue | `session.answer(...)` | `session.answer(...)` | La réponse enregistrée et la décision suivante. |
| Information externe | `session.apply_events(...)` | `session.applyEvents(...)` | L'état actualisé, sans nouveau tour. |
| Relire | `session.refresh()` | `session.refresh()` | Le dernier état et la décision en attente. |
| Résultat métier connu | `session.submit_feedback(...)` | `session.submitFeedback(...)` | Le résultat enregistré. |

Les appels TypeScript utilisent `await`. Python propose aussi `AsyncZelinqaClient` avec `async with` et `await`. Voir le [démarrage complet](/fr/quickstart/overview).

## Reprendre après une coupure

Enregistrez `session.id` dans votre backend dès la création. Les exemples suivants supposent un `client` configuré et la variable `saved_session_id` ou `savedSessionId` relue depuis votre stockage.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    session = client.resume_session(saved_session_id)
    pending = session.pending_decision
    if pending is not None:
        print(pending.candidates[0].text)
    ```
  </Tab>

  <Tab title="TypeScript">
    ```ts theme={null}
    const session = await client.resumeSession(savedSessionId);
    const pending = session.pendingDecision;
    if (pending !== null) {
      console.log(pending.candidates[0]?.text);
    }
    ```
  </Tab>
</Tabs>

**Présentez la question en attente avant d'envoyer une nouvelle réponse.** Après une coupure réseau, vérifiez si la réponse précédente a déjà été enregistrée ; ne la rejouez pas à l'aveugle.

Le SDK conserve `state_version`, `decision_id` et `question_id` pour les appels métier. La version d'état évolue avec la session : ce n'est pas la version publiée du domaine.

<Warning>Utilisez un handle séquentiellement. Deux écritures simultanées sur la même session peuvent produire un conflit ; relisez alors l'état et réconciliez la réponse. Les SDK ne masquent pas les conflits métier.</Warning>

## Continuer ou terminer

* `action: "ask"` : une question est disponible.
* `warnings` peut indiquer `objective_achieved` ou `max_turns_reached` : votre application décide de conclure ou de continuer.
* `action: "stop"` : aucune question n'est disponible ; n'attendez pas de candidate.

Ne confondez pas progression calculée et résultat réel. Enregistrez un feedback de succès seulement si le résultat métier a réellement eu lieu.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    receipt = session.submit_feedback(result="success", label="appointment_booked")
    ```
  </Tab>

  <Tab title="TypeScript">
    ```ts theme={null}
    const receipt = await session.submitFeedback({
      result: "success",
      label: "appointment_booked",
    });
    ```
  </Tab>
</Tabs>

Avec le MCP, les mêmes étapes passent par les [outils de conversation](/fr/integrations/mcp). La [référence API](/fr/api-reference/auth-concurrency) détaille la concurrence et l'idempotence pour les intégrations HTTP directes.


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