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

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

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

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

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

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

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

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

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

### Go

```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 -->

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

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

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

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

* Сделайте `streaming: true` так `createSession` , чтобы время исполнения `assistant.message_delta` событий. Без него единственный сигнал помощника — это финальный `assistant.message` сигнал — это нормально для пакетного использования, но чат будет выглядеть застывшим, если вы рендерите живой интерфейс. См [. раздел AUTOTITLE](/ru/copilot/how-tos/copilot-sdk/features/streaming-events).
* Только **первая**`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"`:

<!-- 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.
  }
});
```

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

О той же проводке в локальных сессиях, продвигаемых через `remote: true`, см. [AUTOTITLE.](/ru/copilot/how-tos/copilot-sdk/features/remote-sessions)

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

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

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

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

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

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

Эта `cloud` опция применяется только при создании новой сессии. Чтобы возобновить существующую облачную сессию, используйте стандартный API resume для языка SDK:

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

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

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

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

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

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

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

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

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

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

Для рекомендаций по многопользовательскому серверу и полной информации об идентификаторе интеграции см. [раздел AUTOTITLE](/ru/copilot/how-tos/copilot-sdk/setup/multi-tenancy).

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

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

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

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

```shell
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"` перед отправкой. См. [Отправка первого запроса](#sending-the-first-prompt) |
| Живой интерфейс никогда не обновляется, даже когда облачный работник обрабатывает процесс                                                  |                                                                                                      |                                                                                                                                                 |
| `streaming` не был установлен на `createSession`, поэтому выпускается только финальный `assistant.message` сигнал                          | Запусти `streaming: true``createSession` и перезапусти                                               |                                                                                                                                                 |
| Облачная сессия работает, но в вашем интерфейсе не отображается общий URL                                                                  | Приложение никогда не подписывалось `session.info` на URL                                            | Подписывайтесь и `session.info` фильтруйте `infoType === "remote"`. См. [Доступ к URL Управления полётом](#accessing-the-mission-control-url)   |

## См. также

* [Удалённые сессии](/ru/copilot/how-tos/copilot-sdk/features/remote-sessions): делиться локально размещёнными сессиями через Центр управления полётами
* [АВТОТИТРЫ](/ru/copilot/how-tos/copilot-sdk/features/streaming-events): подписывайтесь на `assistant.*` дельты для живого рендеринга UI
* [Мультиарендные и серверные развертывания](/ru/copilot/how-tos/copilot-sdk/setup/multi-tenancy): идентификаторы интеграции и шаблоны развертывания серверов
* [Проверка подлинности](/ru/copilot/how-tos/copilot-sdk/auth): настраивать GitHub аутентификацию для сессий SDK