Skip to main content

Sessions dans le cloud

Exécutez des sessions Copilot sur un calcul hébergé par GitHub via Mission Control au lieu de sessions CLI locales.

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.

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

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

package main

import (
    "context"

    copilot "github.com/github/copilot-sdk/go"
    "github.com/github/copilot-sdk/go/rpc"
)

func main() {
    _ = run(context.Background())
}

func run(ctx context.Context) error {
    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(_ copilot.PermissionRequest, _ copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
            return &rpc.PermissionDecisionApproveOnce{}, nil
        },
    })
    _ = session
    return err
}
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

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

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

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?;

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 processus distant copilot-agent met encore une à deux secondes à se connecter et à émettre session.start. Si vous appelez session.send avant cela, le RemoteSession.send du runtime lève "Remote session is still starting" — mais le wrapper du schéma est de type fire-and-forget et avale silencieusement l’erreur tout en renvoyant malgré tout un nouveau messageId à votre code. L’invite est supprimé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" :

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 ».
  • Seul le premiersession.send est sensible à cette situation 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" :

session.on("session.info", (event) => {
  if (event.data?.infoType === "remote" && event.data.url) {
    console.log("Open from web or mobile:", event.data.url);
    // e.g. 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 que l’événement a déjà été déclenché, conservez l’URL avec l’enregistrement de session dans l’état de votre application et réhydratez-la au remontage — le runtime ne réémet pas session.info de lui-même.

Pour le même câblage sur les sessions locales promues via remote: true, voir Sessions à distance.

Association de référentiels

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

ChampObligatoireDescription
ownerYesPropriétaire ou organisation du référentiel.
nameYesNom du référentiel.
branchNoBranche à 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 :

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

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

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

Ne transmettez pas cloud à nouveau 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 :

import {
  CopilotClient,
  type CloudSessionRepository,
} from "@github/copilot-sdk";

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

const repository: CloudSessionRepository = {
  owner: "github",
  name: "copilot-sdk",
};

try {
  await client.createSession({
    cloud: { repository },
    onPermissionRequest: async () => ({ kind: "approve-once" }),
  });
} catch (error) {
  if ((error as { reason?: string }).reason === "policy_blocked") {
    // Show an admin-facing message or link to org policy settings.
  }
  throw error;
}
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 Déploiements multilocataires et serveurs.

Mission Control achemine les sessions cloud créées par le Kit de développement logiciel (SDK) vers la slug de 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.

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

Sessions cloud et sessions distantes

CapacitéSessions à distanceSessions dans le cloud
Emplacement d’exécutionOrdinateur local ou votre serveurcalcul hébergé par GitHub
Rôle De contrôle de missionPartage une session locale sur GitHub web/mobileCré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
Reprendre le chemin d’accèsReprise normaleCV standard
Relation avec Windows SandboxSans rapportSans 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ômeCause la plus probableQue vérifier
La création de session dans le cloud renvoie "policy_blocked"La stratégie organisationnelle bloque le contrôle ou l’affichage à distance à partir de flux cloudVé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é omisTransmettez owner, name, et éventuellement branch
Reprendre ignore une nouvelle cloud option
cloud s’applique uniquement aux nouvelles sessionsReprendre la session existante normalement
Confusion avec les paramètres de bac à sableWindows Sandbox et les sessions cloud sont distinctsNe 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 déclenché et Mission Control n’affiche aucune invitesession.send a devancé session.start du worker distant ; l’environnement d’exécution a avalé l’inviteAttendez le premier événement session.start avec producer === "copilot-agent" avant d’envoyer. Voir Envoi de la première invite
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 émiseRéglez streaming: true sur createSession, puis relancez
La session cloud fonctionne, mais aucune URL partageable n’apparaît dans votre interface utilisateurL’application n’a jamais été abonnée à session.info pour l’URLS’abonner à session.info et filtrer infoType === "remote". Voir Accéder à l’URL du contrôle de mission

Voir également :