# Sessões de nuvem

As sessões de nuvem executam o trabalho do Copilot em recursos computacionais hospedados no GitHub por meio do Mission Control. Use-os quando seu aplicativo deve criar uma sessão que seja executada remotamente em vez de iniciar uma sessão da CLI de Copilot local no computador do usuário ou no servidor.

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

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

## Pré-requisitos

Antes de criar uma sessão na nuvem, verifique se:

* O usuário tem acesso Copilot com direito de agente de nuvem.
* A sessão pode autenticar no GitHub, seja com um token de usuário ou com uma identidade da CLI do Copilot com login feito.
* Você pode associar a sessão a um repositório GitHub. Isso é opcional no tipo SDK, mas recomendado para que o Controle de Missão e o agente de nuvem tenham contexto de repositório.
* As políticas da organização permitem o controle remoto e a visualização de sessões a partir de superfícies na nuvem.

## Criando uma sessão de nuvem

Defina a opção create-session `cloud` para criar uma sessão de nuvem. Você pode incluir metadados do repositório para associar a sessão de nuvem a um repositório 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 -->

## Enviando o primeiro prompt

As sessões na nuvem são inicializadas em duas fases: `createSession` é resolvida assim que o Mission Control reserva uma tarefa, mas o worker remoto `copilot-agent` leva mais um ou dois segundos para se conectar e emitir `session.start`. Se você chamar `session.send` antes disso, o runtime `RemoteSession.send` lança `"Remote session is still starting"` — mas o wrapper de esquema é do tipo "disparar e esquecer" e **silenciosamente ignora o erro** enquanto ainda retorna um novo `messageId` para o seu código. O prompt é enviado para o servidor e nunca chega ao worker.

Para enviar de forma confiável, inscreva-se nos eventos **antes** de enviar e aguarde o primeiro evento `session.start` cujo `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" });
```

Algumas notas:

* Defina `streaming: true` em `createSession` para que o runtime emita eventos `assistant.message_delta`. Sem ele, o único sinal do assistente que você recebe é o `assistant.message` final — o que serve para uso em lote, mas o chat parecerá congelado se você estiver renderizando uma interface em tempo real. Consulte [Eventos de sessão de streaming](/pt/copilot/how-tos/copilot-sdk/features/streaming-events).
* Apenas o **primeiro**`session.send` é sensível a essa condição de corrida. Os envios subsequentes na mesma sessão funcionam normalmente porque o runtime mantém `hasSessionStarted` definido durante toda a sessão.
* Aplique um tempo limite (por exemplo, 60 s) em torno da promessa `ready` para que um provisionamento do Mission Control travado não congele seu aplicativo indefinidamente.
* O mesmo padrão funciona em todas as linguagens de SDK — inscreva-se em `session.start`, verifique `producer === "copilot-agent"` e, em seguida, chame `send`.

## Acessando a URL de Controle de Missão

As sessões em nuvem são inerentemente remotas: assim que o worker se conecta, o Mission Control publica a sessão em `https://github.com/copilot/tasks/{sessionId}`, e o runtime emite um evento `session.info` com a URL. Você **não** precisa invocar `remote.enable()` — essa API é apenas para promover uma sessão local para o Mission Control.

Capture a URL inscrevendo-se em `session.info` e filtrando por `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.
  }
});
```

O evento é disparado logo após `session.start`. Se o seu renderizador for montado depois que o evento já tiver sido disparado, persista a URL junto com o registro da sessão no estado do seu aplicativo e reidrate-a na remontagem — o runtime não reemite `session.info` por conta própria.

Para a mesma configuração em sessões locais promovidas via `remote: true`, consulte [Sessões remotas](/pt/copilot/how-tos/copilot-sdk/features/remote-sessions).

## Associação de repositório

O objeto `cloud.repository` associa a sessão de nuvem a um repositório GitHub:

| Campo    | Obrigatório | Descrição                                                                                                                                                             |
| -------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `owner`  | Yes         | Proprietário ou organização do repositório.                                                                                                                           |
| `name`   | Yes         | Nome do repositório.                                                                                                                                                  |
| `branch` | No          | Ramificação a ser usada no contexto do repositório. Omita isso para permitir que o tempo de execução escolha a ramificação padrão ou o contexto atual do repositório. |

A associação de repositório é opcional no tipo SDK, mas inclua-a sempre que o aplicativo souber o repositório de destino. Ele ajuda o Controle de Missão a exibir a sessão no contexto certo e fornece ao agente de nuvem um ponto de partida mais claro.

Use `branch` quando o trabalho deve ser iniciado a partir de uma ramificação específica. Se o seu aplicativo estiver criando sessões a partir de pull requests, fluxos de triagem de problemas ou fluxos de trabalho de implantação, passe a ramificação que corresponde à tarefa visível ao usuário.

## Retomando uma sessão de nuvem

A `cloud` opção só se aplica ao criar uma nova sessão. Para retomar uma sessão de nuvem existente, use a API de retomada padrão para o idioma do SDK:

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

Não passe `cloud` novamente ao retomar. Os metadados salvos da sessão determinam que a sessão é respaldada pela nuvem, e a retomada segue o fluxo normal de retomada da sessão.

## Políticas e direitos da organização

A criação de sessão na nuvem pode falhar quando o usuário ou a organização não tem direito à execução do agente de nuvem ou quando as políticas no nível da organização bloqueiam o fluxo. Em particular, as políticas para o sandbox da nuvem podem impedir que os clientes criem a tarefa na nuvem.

Quando isso acontece, o runtime relata um `"policy_blocked"` motivo de falha para a criação de tarefas na nuvem. Trate isso como um resultado de autorização ou política, não como uma falha transitória de infraestrutura.

No TypeScript, verifique o motivo antes de tentar novamente:

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

Em idiomas em que os erros do SDK são representados de forma diferente, inspecione o motivo do erro ou o código exibido e manipule `"policy_blocked"` explicitamente. Não se espera que a repetição sem uma alteração de política seja bem-sucedida.

## ID de integração e roteamento

As sessões de nuvem são carimbadas com um cabeçalho `Copilot-Integration-Id` derivado da variável de ambiente `GITHUB_COPILOT_INTEGRATION_ID`. Essa ID de integração é usada pelo Controle de Missão para roteamento, atribuição e comportamento específico de integração.

Para obter orientações sobre servidor multiusuário e detalhes completos do ID de integração, consulte [Multilocação e implantações de servidores](/pt/copilot/how-tos/copilot-sdk/setup/multi-tenancy).

O Mission Control direciona as sessões em nuvem criadas pelo SDK para o slug do agente `copilot-developer-sandbox`. O nome é um identificador interno de roteamento para o agente na nuvem e não significa que a sessão esteja usando o sandbox local do Windows.

## Avançado: `COPILOT_MC_BASE_URL`

Por padrão, o runtime obtém a URL base do Mission Control a partir da URL configurada da API do Copilot. Defina `COPILOT_MC_BASE_URL` somente quando precisar substituir esse endpoint do Mission Control.

Isso pode ser necessário para implantações do GitHub Enterprise Server. Confirme o valor correto e o status de suporte com seu representante GitHub antes de confiar nele na produção.

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

## Sessões de nuvem versus sessões remotas

| Capacidade                             | Sessões remotas                                    | Sessões de nuvem                    |
| -------------------------------------- | -------------------------------------------------- | ----------------------------------- |
| Local de execução                      | Computador local ou servidor                       | computação hospedada no GitHub      |
| Função de Controle de Missão           | Compartilha uma sessão local para GitHub web/móvel | Cria e encaminha a sessão hospedada |
| Opção SDK                              |                                                    |                                     |
| `remote: true` no cliente ou na sessão |                                                    |                                     |
| `cloud: { ... }` ao criar sessão       |                                                    |                                     |
| Retomar o caminho                      | Currículo padrão                                   | Currículo padrão                    |
| Relação com o sandbox do Windows       | Não relacionado                                    | Não relacionado                     |

Use sessões remotas quando a sessão deve ser executada onde o runtime do SDK já está em execução, mas também pode ser acessível a partir do Controle de Missão. Use sessões de nuvem quando a sessão deve ser executada na computação hospedada GitHub.

## Troubleshooting

| Sintoma                                                                                                                                | Causa provável                                                                           | O que verificar                                                                                                                                              |
| -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| A criação de sessão na nuvem retorna `"policy_blocked"`                                                                                | Política de organização bloqueia controle remoto ou exibição de fluxos de nuvem          | Verificar políticas de Copilot da organização e direitos do usuário                                                                                          |
| Sessão criada sem contexto de repositório                                                                                              |                                                                                          |                                                                                                                                                              |
| `cloud.repository` foi omitido                                                                                                         | Passe `owner`, `name`, e opcionalmente `branch`                                          |                                                                                                                                                              |
| Retomar ignora uma nova opção `cloud`                                                                                                  |                                                                                          |                                                                                                                                                              |
| `cloud` aplica-se apenas a novas sessões                                                                                               | Retomar a sessão existente normalmente                                                   |                                                                                                                                                              |
| Confusão em relação às configurações de sandbox                                                                                        | O Windows Sandbox e as sessões na nuvem são separados                                    | Não usar `SANDBOX=true` para execução na nuvem                                                                                                               |
| `session.send` é resolvido com um `messageId`, mas nenhum evento `assistant.*` é disparado e o Mission Control não exibe nenhum prompt | O session.send ultrapassou `session.start` do worker remoto; o runtime absorveu o prompt | Aguarde o primeiro evento `session.start` com `producer === "copilot-agent"` antes de enviar. Consulte [Enviar o primeiro prompt](#sending-the-first-prompt) |
| A interface do usuário em tempo real nunca é atualizada, mesmo que o worker na nuvem esteja processando                                |                                                                                          |                                                                                                                                                              |
| `streaming` não foi definido em `createSession`, portanto apenas o `assistant.message` final é emitido                                 | Configure `streaming: true` em `createSession` e reinicie                                |                                                                                                                                                              |
| A sessão na nuvem funciona, mas nenhuma URL compartilhável aparece na interface do usuário                                             | O aplicativo nunca se inscreveu em `session.info` para a URL                             | Inscreva-se em `session.info` e filtre `infoType === "remote"`. Consulte [como acessar a URL do Controle de Missão](#accessing-the-mission-control-url)      |

## Consulte também

* [Sessões remotas](/pt/copilot/how-tos/copilot-sdk/features/remote-sessions): compartilhar sessões hospedadas localmente por meio do Controle de Missão
* [Eventos de sessão de streaming](/pt/copilot/how-tos/copilot-sdk/features/streaming-events): inscrever-se em `assistant.*` deltas para renderização da interface do usuário em tempo real
* [Multilocação e implantações de servidores](/pt/copilot/how-tos/copilot-sdk/setup/multi-tenancy): IDs de integração e padrões de implantação de servidor
* [Autenticação](/pt/copilot/how-tos/copilot-sdk/auth): configurar GitHub autenticação para sessões do SDK