Skip to main content

Облачные сессии

Проводите сессии Copilot на вычислениях, размещённых на GitHub, через Центр управления полетами вместо локальных сессий CLI.

Необходимые условия

Перед созданием облачной сессии убедитесь:

  • Пользователь имеет доступ к Copilot с правом облачного агента.
  • Сессия может аутентифицироваться в GitHub либо с помощью пользовательского токена, либо с авторизованной идентификацией Copilot CLI.
  • Сессию можно связать с репозиторием GitHub. Это опционально для типа SDK, но рекомендуется для того, чтобы Центр управления полетами и облачный агент имели контекст репозитория.
  • Политики организации позволяют проводить удалённое управление и просмотр сессий с облачных поверхностей.

Создание облачной сессии

Настройте опцию создания сессии cloud в облаке. Вы можете включить метаданные репозитория, чтобы связать облачную сессию с репозиторием 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",
        )
    ),
)

Go

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

Отправка первого запроса

Облачные сессии инициализируются в две фазы: createSession разрешаются сразу после того, как Центр управления полётом зарезервировал задачу, но удалённый copilot-agent сотрудник подключается ещё секунду или две, чтобы подключиться и излучить session.start. Если звонить session.send раньше, время выполнения RemoteSession.send срабатывает "Remote session is still starting" — но обёртка схемы работает с режимом «отстрелить и забыть» и молча проглатывает ошибку , при этом возвращая свежую messageId версию в ваш код. Запрос сбрасывается на сервере и никогда не доходит до работника.

Чтобы отправлять надёжно, подпишитесь на события перед отправкой и ждите первое session.start событие, котороеproducer:"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" });

Несколько примечаний:

  • Сделайте streaming: true так createSession , чтобы время исполнения assistant.message_delta событий. Без него единственный сигнал помощника — это финальный assistant.message сигнал — это нормально для пакетного использования, но чат будет выглядеть застывшим, если вы рендерите живой интерфейс. См . раздел AUTOTITLE.
  • Только перваяsession.send чувствительна к этой расе. Последующие отправки на одну и ту же сессию работают нормально, потому что время выполнения остаётся hasSessionStarted установленным на протяжении всей сессии.
  • Введите тайм-аут (например, 60 секунд) вокруг обещания ready , чтобы зависшая настройка Центра управления полётом не зависала в приложении навсегда.
  • Та же схема работает во всех SDK-языках — подписаться на session.start, проверить producer === "copilot-agent", затем вызвать send.

Доступ к URL Управления полётом

Облачные сессии по своей сути удалены: после подключения сотрудника Центр управления публикует сессию на Mission Control https://github.com/copilot/tasks/{sessionId} , и время выполнения генерирует session.info событие с URL. Вам не нужно звонить remote.enable() — этот API предназначен только для продвижения локальной сессии в Центр управления полётами.

Захватите URL, подписавшись на session.info и отфильтровав по 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.
  }
});

Событие запускается вскоре после session.startэтого. Если ваш рендерер монтируется после того, как событие уже сработало, сохраняйте URL вместе с записью сессии в состоянии приложения и восстанавливайтесь при повторном подключении — время выполнения не session.info повторяет работу самостоятельно.

О той же проводке в локальных сессиях, продвигаемых через remote: true, см. AUTOTITLE.

Ассоциация хранилищ

Объект cloud.repository связывает облачную сессию с репозиторием GitHub:

ПолеОбязательныйDescription
ownerДаВладелец репозитория или организация.
nameДаИмя репозитория.
branchНетВетка для контекста репозитория. Опустите его, чтобы время выполнения выбрало стандартную ветку или текущий контекст репозитория.

Ассоциация репозитория необязательна в типе SDK, но включайте её, когда ваше приложение знает целевой репозиторий. Это помогает Центру управления миссией отображать сессию в нужном контексте и даёт облачному агенту более чёткую отправную точку.

Используйте branch тогда, когда работа должна начинаться с определённой ветви. Если ваше приложение создаёт сессии из pull request, процессов сортировки или процессов развертывания, передайте ветку, которая соответствует видимой задаче.

Возобновление облачной сессии

Эта cloud опция применяется только при создании новой сессии. Чтобы возобновить существующую облачную сессию, используйте стандартный API resume для языка 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" }),
});

Не проходите cloud снова в резюме. Метаданные сохранённой сессии определяют, что сессия поддерживается облаком, и возобновление следует обычному пути возобновления сессии.

Политики и права организации

Создание облачных сессий может провалиться, если пользователь или организация не имеют права на выполнение облачных агентов или если политики на уровне организации блокируют этот поток. В частности, политики для облачных песочниц могут мешать клиентам создавать облачную задачу.

Когда это происходит, среда выполнения сообщает "policy_blocked" о причине отказа создания облачных задач. Рассматривайте это как разрешение или результат политики, а не как временный сбой инфраструктуры.

В TypeScript проверьте причину перед повторной попыткой:

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

В языках, где ошибки SDK представлены по-разному, проверьте поверхностную причину ошибки или код и обрабатывайте "policy_blocked" её явно. Ожидается, что повторная попытка без изменения политики не принесёт успеха.

Идентификатор интеграции и маршрутизация

Облачные сессии имеют заголовок Copilot-Integration-Id, полученный из переменной среды GITHUB_COPILOT_INTEGRATION_ID. Этот идентификатор интеграции используется Центром управления полётами для маршрутизации, атрибуции и поведения, специфичного для интеграции.

Для рекомендаций по многопользовательскому серверу и полной информации об идентификаторе интеграции см. раздел AUTOTITLE.

Центр управления полётами направляет облачные сессии, созданные SDK, к copilot-developer-sandbox агентному слагу. Название является внутренним маршрутизатором для облачного агента и не означает, что сессия использует локальную песочницу Windows.

Продвинутые программы: COPILOT_MC_BASE_URL

По умолчанию среда выполнения выводит базовый URL Управления полётами из настроенного URL API Copilot. Устанавливайте COPILOT_MC_BASE_URL только тогда, когда нужно переобойти конечную точку управления полётами.

Это может потребоваться для развертывания GitHub Enterprise Server. Проверьте правильное значение и статус поддержки с вашим представителем GitHub, прежде чем использовать это в продакшене.

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

Облачные сессии против удалённых сессий

ФункциональностьУдалённые сессииОблачные сессии
Место выполненияЛокальный компьютер или ваш серверВычисления, размещённые на GitHub
Роль в центре управления полётамиОбменивается локальной сессией на GitHub web/mobileСоздаёт и маршрутизирует размещённую сессию
Опция SDK
remote: true на клиенте или сессии
cloud: { ... } На сессии создания
Путь резюмеСтандартное резюмеСтандартное резюме
Отношение песочницы WindowsНе по теме.Не по теме.

Используйте удалённые сессии, когда сессия должна выполняться там, где SDK уже работает, но при этом быть доступной из Центра управления. Используйте облачные сессии, когда сессия должна выполняться на вычислениях, размещённых на GitHub.

Troubleshooting

СимптомВероятно, причинаЧто проверить
Возвращение создания облачных сессий "policy_blocked"Политика организации блокирует удалённое управление или просмотр из облачных потоковПроверьте политики org Copilot и права пользователей
Сессия создаётся без контекста репозитория
cloud.repository был опущенPass owner, name, и по желанию branch
Резюме игнорирует новый cloud вариант
cloud Применяется только к новым сессиямВозобновить существующую сессию в обычном режиме
Путаница с настройками песочницыWindows песочница и облачные сессии — это отдельныеНе используйте SANDBOX=true для облачного выполнения
session.send разрешается с a messageId , но без assistant.* событий, срабатывает, и Центр управления полётом не показывает подсказкиSession.send мчался впереди session.start удалённого сотрудника; время выполнения поглотило запросЖдите первого session.start события producer === "copilot-agent" перед отправкой. См. Отправка первого запроса
Живой интерфейс никогда не обновляется, даже когда облачный работник обрабатывает процесс
streaming не был установлен на createSession, поэтому выпускается только финальный assistant.message сигналЗапусти streaming: true``createSession и перезапусти
Облачная сессия работает, но в вашем интерфейсе не отображается общий URLПриложение никогда не подписывалось session.info на URLПодписывайтесь и session.info фильтруйте infoType === "remote". См. Доступ к URL Управления полётом

См. также