# Sessions dans le cloud

Les sessions cloud exécutent les tâches Copilot sur l’infrastructure de calcul hébergée par GitHub via Mission Control. Utilisez-les lorsque votre application doit créer une session qui s'exécute à distance au lieu de démarrer une session CLI locale Copilot sur l'ordinateur de l'utilisateur ou votre serveur.

<!-- markdownlint-disable GHD046 GHD005 -->

<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->

## Prerequisites

Avant de créer une session cloud, assurez-vous :

* L’utilisateur a accès à Copilot avec les droits d’accès à l’agent cloud.
* La session peut s’authentifier auprès de GitHub, soit avec un jeton utilisateur, soit avec une identité Copilot CLI connectée.
* Vous pouvez associer la session à un référentiel GitHub. Cela est facultatif dans le type du KIT de développement logiciel (SDK), mais recommandé pour que Mission Control et l’agent cloud disposent d’un contexte de référentiel.
* Les stratégies d’organisation autorisent le contrôle à distance et l’affichage des sessions à partir de surfaces cloud.

## Création d’une session cloud

Définissez l’option create-session `cloud` pour créer une session cloud. Vous pouvez inclure des métadonnées de référentiel pour associer la session cloud à un référentiel GitHub.

<!-- tabs:start -->

### TypeScript

```typescript
import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
await client.start();

const session = await client.createSession({
  onPermissionRequest: async () => ({ kind: "approve-once" }),
  cloud: {
    repository: {
      owner: "github",
      name: "copilot-sdk",
      branch: "main",
    },
  },
});
```

### Python

```python
from copilot import (
    CloudSessionOptions,
    CloudSessionRepository,
    CopilotClient,
    PermissionHandler,
)

client = CopilotClient()
await client.start()

session = await client.create_session(
    on_permission_request=PermissionHandler.approve_all,
    cloud=CloudSessionOptions(
        repository=CloudSessionRepository(
            owner="github",
            name="copilot-sdk",
            branch="main",
        )
    ),
)
```

### Allez

```golang
client := copilot.NewClient(nil)
if err := client.Start(ctx); err != nil {
    return err
}

session, err := client.CreateSession(ctx, &copilot.SessionConfig{
    Cloud: &copilot.CloudSessionOptions{
        Repository: &copilot.CloudSessionRepository{
            Owner:  "github",
            Name:   "copilot-sdk",
            Branch: "main",
        },
    },
    OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
        return &rpc.PermissionDecisionApproveOnce{}, nil
    },
})
_ = session
```

### .NET

```csharp
await using var client = new CopilotClient();

var session = await client.CreateSessionAsync(new SessionConfig
{
    Cloud = new CloudSessionOptions
    {
        Repository = new CloudSessionRepository
        {
            Owner = "github",
            Name = "copilot-sdk",
            Branch = "main",
        },
    },
    OnPermissionRequest = (req, inv) =>
        Task.FromResult(PermissionDecision.ApproveOnce()),
});
```

### Java

```java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;

try (var client = new CopilotClient()) {
    client.start().get();

    var session = client.createSession(
        new SessionConfig()
            .setCloud(new CloudSessionOptions()
                .setRepository(new CloudSessionRepository()
                    .setOwner("github")
                    .setName("copilot-sdk")
                    .setBranch("main")))
            .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
    ).get();
}
```

### Rust

```rust
use std::sync::Arc;
use github_copilot_sdk::{CloudSessionOptions, CloudSessionRepository, SessionConfig};
use github_copilot_sdk::handler::ApproveAllHandler;

let session = client.create_session(
    SessionConfig::default()
        .with_cloud(CloudSessionOptions::with_repository(
            CloudSessionRepository::new("github", "copilot-sdk").with_branch("main"),
        ))
        .with_permission_handler(Arc::new(ApproveAllHandler)),
).await?;
```

<!-- tabs:end -->

## Envoi de la première invite

Les sessions cloud s'initialisent en deux phases : `createSession` se résout dès que Mission Control a réservé une tâche, mais le Worker distant `copilot-agent` met une ou deux secondes supplémentaires à se connecter et à émettre `session.start`. Si vous appelez `session.send` avant cela, le `RemoteSession.send` du runtime génère une exception `"Remote session is still starting"`. Toutefois, le wrapper de schéma est de type fire-and-forget et **ignore silencieusement l'erreur** tout en renvoyant un nouveau `messageId` à votre code. L'invite est abandonnée sur le serveur et n'atteint jamais le Worker.

Pour envoyer de manière fiable, s’abonner aux événements **avant** d’envoyer et attendre le premier événement `session.start` dont la valeur de `producer` est `"copilot-agent"` :

<!-- docs-validate: skip -->

```typescript
import { CopilotClient, type CopilotSession } from "@github/copilot-sdk";

const client = new CopilotClient();
await client.start();

const session: CopilotSession = await client.createSession({
  streaming: true, // required for assistant.message_delta to fire
  cloud: { repository: { owner: "github", name: "copilot-sdk" } },
  onPermissionRequest: async () => ({ kind: "approve-once" }),
});

// Subscribe BEFORE sending so you don't miss the start event.
const ready = new Promise<void>((resolve) => {
  const off = session.on("session.start", (event) => {
    if (event.data?.producer === "copilot-agent") {
      off();
      resolve();
    }
  });
});

await ready;
await session.send({ prompt: "Summarize the README" });
```

Quelques remarques :

* Définissez `streaming: true` sur `createSession` afin que le runtime génère des événements `assistant.message_delta`. Sans cela, le seul signal de l’assistant que vous obtenez est le final `assistant.message` , bien pour l’utilisation par lots, mais la conversation sera figée si vous affichez une interface utilisateur en direct. Consultez « [Événements de session de streaming](/fr/copilot/how-tos/copilot-sdk/features/streaming-events) ».
* Seul le **premier**`session.send` est sensible à cette condition de concurrence. Les envois suivants sur la même session fonctionnent normalement, car le runtime conserve `hasSessionStarted` la valeur définie pour la durée de la session.
* Appliquez un délai d’expiration (par exemple, 60 s) autour de la `ready` promesse afin qu’un provisionnement de Mission Control bloqué ne bloque pas votre application pour toujours.
* Le même modèle fonctionne dans chaque langue du Kit de développement logiciel (SDK) : s’abonner à `session.start`, vérifier `producer === "copilot-agent"`, puis appeler `send`.

## Accès à l’URL du contrôle de mission

Les sessions cloud sont intrinsèquement distantes : une fois que le worker se connecte, Mission Control publie la session à `https://github.com/copilot/tasks/{sessionId}` et le runtime émet un `session.info` événement avec l’URL. Vous n’avez **pas** besoin d’appeler `remote.enable()` cette API uniquement pour promouvoir une session locale vers Mission Control.

Récupérez l’URL en vous abonnant à `session.info` et en filtrant par `infoType: "remote"` :

<!-- docs-validate: skip -->

```typescript
session.on("session.info", (event) => {
  if (event.data?.infoType === "remote" && event.data.url) {
    console.log("Open from web or mobile:", event.data.url);
    // For example, surface in your UI as a shareable link or QR code.
  }
});
```

L’événement se déclenche peu après `session.start`. Si votre moteur de rendu est monté une fois l'événement déjà déclenché, conservez l'URL avec l'enregistrement de session dans l'état de votre application et réhydratez-la lors du remontage ; le runtime ne réémet pas `session.info` de lui-même.

Pour obtenir le même comportement avec les sessions locales promues via `remote: true`, consultez [Sessions à distance](/fr/copilot/how-tos/copilot-sdk/features/remote-sessions).

## Association de référentiels

L’objet `cloud.repository` associe la session cloud à un référentiel GitHub :

| Champ    | Obligatoire | Description                                                                                                                                                |
| -------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `owner`  | Yes         | Propriétaire ou organisation du référentiel.                                                                                                               |
| `name`   | Yes         | Nom du référentiel.                                                                                                                                        |
| `branch` | No          | Branche à utiliser pour le contexte du référentiel. Omettez-le pour laisser le runtime choisir la branche par défaut ou le contexte de référentiel actuel. |

L’association de référentiel est facultative dans le type du KIT de développement logiciel (SDK), mais incluez-la chaque fois que votre application connaît le référentiel cible. Il permet à Mission Control d’afficher la session dans le contexte approprié et de donner à l’agent cloud un point de départ plus clair.

Utilisez `branch` quand le travail doit commencer à partir d’une branche spécifique. Si votre application crée des sessions à partir de pull requests, de flux de triage des tickets ou de workflows de déploiement, transmettez la branche correspondant à la tâche affichée à l’utilisateur.

## Reprise d’une session cloud

L’option `cloud` s’applique uniquement lors de la création d’une session. Pour reprendre une session cloud existante, utilisez l’API de reprise standard pour le langage sdk :

```typescript
const session = await client.resumeSession("session-id", {
  onPermissionRequest: async () => ({ kind: "approve-once" }),
});
```

Ne transmettez plus `cloud` lors de la reprise. Les métadonnées de session enregistrées déterminent que la session est sauvegardée dans le cloud et reprend le chemin normal de reprise de session.

## Politiques et droits de l’organisation

La création de session cloud peut échouer lorsque l’utilisateur ou l’organisation n’a pas droit à l’exécution de l’agent cloud ou lorsque les stratégies au niveau de l’organisation bloquent le flux. En particulier, les règles de sandbox cloud peuvent empêcher les clients de créer la tâche dans le cloud.

Lorsque cela se produit, le runtime signale une raison d’échec `"policy_blocked"` de la création de tâches cloud. Traitez-le comme un résultat d’autorisation ou de stratégie, et non comme une défaillance temporaire de l’infrastructure.

Dans TypeScript, vérifiez la raison avant de réessayer :

```typescript
try {
  await client.createSession({ cloud: { repository } });
} catch (error) {
  if ((error as { reason?: string }).reason === "policy_blocked") {
    // Show an admin-facing message or link to org policy settings.
  }
  throw error;
}
```

Dans les langages où les erreurs du Kit de développement logiciel (SDK) sont représentées différemment, inspectez la raison ou le code d’erreur exposés et gérez `"policy_blocked"` explicitement. Une nouvelle tentative sans modification de stratégie n’est pas censée réussir.

## ID d’intégration et routage

Les sessions cloud sont marquées avec un en-tête `Copilot-Integration-Id` dérivé de la variable d’environnement `GITHUB_COPILOT_INTEGRATION_ID`. Cet ID d’intégration est utilisé par Mission Control pour le routage, l’attribution et le comportement spécifique à l’intégration.

Pour obtenir des conseils sur le serveur multi-utilisateur et des détails complets de l’ID d’intégration, consultez [Multilocataire et déploiements de serveurs](/fr/copilot/how-tos/copilot-sdk/setup/multi-tenancy).

Mission Control achemine les sessions cloud créées par le SDK vers l'agent `copilot-developer-sandbox`. Le nom est un identifiant de routage interne pour l’agent du cloud et ne signifie pas que la session utilise le bac à sable Windows local.

## Avancé: `COPILOT_MC_BASE_URL`

Par défaut, le runtime déduit l’URL de base de Mission Control à partir de l’URL de l’API Copilot configurée. Définissez `COPILOT_MC_BASE_URL` uniquement lorsque vous devez remplacer le point de terminaison Mission Control.

Cela peut être nécessaire pour les déploiements de GitHub Enterprise Server. Confirmez la valeur et l’état de support corrects avec votre représentant GitHub avant de vous appuyer sur celui-ci en production.

```shell
COPILOT_MC_BASE_URL="https://example.com/agents"
```

## Sessions cloud et sessions distantes

| Capacité                                           | Sessions à distance                              | Sessions dans le cloud            |
| -------------------------------------------------- | ------------------------------------------------ | --------------------------------- |
| Emplacement d’exécution                            | Ordinateur local ou votre serveur                | calcul hébergé par GitHub         |
| Rôle De contrôle de mission                        | Partage une session locale sur GitHub web/mobile | Crée et route la session hébergée |
| Option du Kit de développement logiciel (SDK       |                                                  |                                   |
| `remote: true` sur le client ou la session         |                                                  |                                   |
| `cloud: { ... }` lors de la création d’une session |                                                  |                                   |
| Chemin de reprise                                  | Reprise standard                                 | Reprise standard                  |
| Relation avec Windows Sandbox                      | Sans rapport                                     | Sans rapport                      |

Utilisez des sessions à distance lorsque la session doit s’exécuter là où le runtime du SDK est déjà en cours d’exécution, mais également accessible à partir de Mission Control. Utilisez des sessions cloud quand la session doit s’exécuter sur GitHub calcul hébergé.

## Résolution des problèmes

| Symptôme                                                                                                                                | Cause la plus probable                                                                                | Que vérifier                                                                                                                                                     |
| --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| La création d'une session cloud renvoie `"policy_blocked"`.                                                                             | La stratégie organisationnelle bloque le contrôle ou l’affichage à distance à partir de flux cloud    | Vérifier les stratégies d’organisation Copilot et les droits d’utilisateur                                                                                       |
| Création de session sans contexte de dépôt                                                                                              |                                                                                                       |                                                                                                                                                                  |
| `cloud.repository` a été omis                                                                                                           | Transmettez `owner`, `name`, et éventuellement `branch`                                               |                                                                                                                                                                  |
| La reprise ignore une nouvelle option `cloud`.                                                                                          |                                                                                                       |                                                                                                                                                                  |
| `cloud` s’applique uniquement aux nouvelles sessions                                                                                    | Reprendre la session existante normalement                                                            |                                                                                                                                                                  |
| Confusion avec les paramètres de bac à sable                                                                                            | Windows Sandbox et les sessions cloud sont distincts                                                  | Ne pas utiliser `SANDBOX=true` pour l’exécution du cloud                                                                                                         |
| `session.send` se résout avec un `messageId`, mais aucun événement `assistant.*` n'est émis et Mission Control n'affiche aucune invite. | Le session.send a été exécuté avant `session.start` du Worker distant ; le runtime a ignoré l'invite. | Attendez le premier événement `session.start` avec `producer === "copilot-agent"` avant d’envoyer. Voir [Envoi de la première invite](#sending-the-first-prompt) |
| L’interface en temps réel ne se met jamais à jour, même si le worker cloud est en cours de traitement                                   |                                                                                                       |                                                                                                                                                                  |
| `streaming` n’a pas été défini sur `createSession`, donc seule la finale `assistant.message` est émise                                  | Réglez `streaming: true` sur `createSession`, puis relancez                                           |                                                                                                                                                                  |
| La session cloud fonctionne, mais aucune URL partageable n’apparaît dans votre interface utilisateur                                    | L’application n’a jamais été abonnée à `session.info` pour l’URL                                      | S’abonner à `session.info` et filtrer `infoType === "remote"`. Voir [Accéder à l’URL du contrôle de mission](#accessing-the-mission-control-url)                 |

## Voir également :

* [Sessions à distance](/fr/copilot/how-tos/copilot-sdk/features/remote-sessions) : partager des sessions hébergées localement via Mission Control
* [Événements de session de streaming](/fr/copilot/how-tos/copilot-sdk/features/streaming-events): s’abonner aux `assistant.*` deltas pour le rendu d’interface utilisateur en direct
* [Multilocataire et déploiements de serveurs](/fr/copilot/how-tos/copilot-sdk/setup/multi-tenancy) : ID d’intégration et modèles de déploiement de serveur
* [Authentification](/fr/copilot/how-tos/copilot-sdk/auth) : configurer l’authentification GitHub pour les sessions sdk