Skip to main content

Persistência de sessão no SDK do Copilot

Pausar, retomar e gerenciar SDK do Copilot sessões durante reinicializações e implantações.

Quem pode usar esse recurso?

SDK do GitHub Copilot está disponível com todos os Copilot planos.

Observação

          SDK do Copilot está atualmente em versão prévia técnica. A funcionalidade e a disponibilidade estão sujeitas a alterações.

Quando você cria uma sessão, SDK do Copilot mantém o histórico da conversa, o estado da ferramenta e o contexto de planejamento. Por padrão, esse estado reside na memória e desaparece quando a sessão termina. Com a persistência habilitada, você pode retomar sessões entre reinicializações, migrações de contêiner ou até mesmo instâncias de cliente diferentes. Para obter uma visão geral visual do ciclo de vida do estado da sessão, consulte o github/copilot-sdk repositório.

StateO que acontece
          **Create** | 
          `sessionId` Atribuído |

| Ativo | Enviar prompts, chamadas de ferramenta, respostas | | Pausado | Estado salvo em disco | | Retomar | Estado carregado do disco |

Início rápido: criando uma sessão retomável

A chave para sessões retomáveis é fornecer o seu próprio sessionId (outros SDKs podem usar session_id). Sem um, o SDK gera uma ID aleatória e a sessão não pode ser retomada mais tarde.

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

const client = new CopilotClient();

// Create a session with a meaningful ID
const session = await client.createSession({
  sessionId: "user-123-task-456",
  model: "gpt-5.2-codex",
});

// Do some work...
await session.sendAndWait({ prompt: "Analyze my codebase" });

// Session state is automatically persisted
// You can safely close the client

Para obter exemplos em Python, Go e C#, consulte o github/copilot-sdkrepositório.

Retomando uma sessão

Você pode retomar uma sessão de onde ela terminou (minutos, horas ou até dias depois). Para obter uma visão geral visual da retomada de sessões entre diferentes clientes, consulte o github/copilot-sdk repositório.

// Resume from a different client instance (or after restart)
const session = await client.resumeSession("user-123-task-456");

// Continue where you left off
await session.sendAndWait({ prompt: "What did we discuss earlier?" });

Para obter exemplos em Python, Go e C#, consulte o github/copilot-sdk repositório.

Opções de retomada

Ao retomar uma sessão, opcionalmente, você pode reconfigurar muitas configurações. Isso é útil quando você precisa alterar o modelo, atualizar as configurações da ferramenta ou modificar o comportamento.

OpçãoDescrição
modelAlterar o modelo da sessão retomada
systemMessageSubstituir ou estender o prompt do sistema
availableToolsRestringir quais ferramentas estão disponíveis
excludedToolsDesabilitar ferramentas específicas
providerFornecer novamente as credenciais BYOK (necessárias para sessões BYOK)
reasoningEffortAjustar o nível de esforço de raciocínio
streamingHabilitar/desabilitar respostas de streaming
workingDirectoryAlterar o diretório de trabalho
configDirSobrescrever diretório de configuração
mcpServersConfigurar servidores MCP
customAgentsConfigurar agentes personalizados
agentPré-selecionar um agente personalizado pelo nome
skillDirectoriesDiretórios para carregar habilidades de
disabledSkillsHabilidades para desabilitar
infiniteSessionsConfigurar o comportamento de sessão infinita

Exemplo: Alterando o modelo do currículo

// Resume with a different model
const session = await client.resumeSession("user-123-task-456", {
  model: "claude-sonnet-4",  // Switch to a different model
  reasoningEffort: "high",   // Increase reasoning effort
});

Usando BYOK com sessões retomadas

Ao usar suas próprias chaves de API, você deve fornecer novamente a configuração do provedor ao retomar. As chaves de API nunca são mantidas no disco por motivos de segurança.

// Original session with BYOK
const session = await client.createSession({
  sessionId: "user-123-task-456",
  model: "gpt-5.2-codex",
  provider: {
    type: "azure",
    endpoint: "https://my-resource.openai.azure.com",
    apiKey: process.env.AZURE_OPENAI_KEY,
    deploymentId: "my-gpt-deployment",
  },
});

// When resuming, you MUST re-provide the provider config
const resumed = await client.resumeSession("user-123-task-456", {
  provider: {
    type: "azure",
    endpoint: "https://my-resource.openai.azure.com",
    apiKey: process.env.AZURE_OPENAI_KEY,  // Required again
    deploymentId: "my-gpt-deployment",
  },
});

O que é persistente

O estado da sessão é salvo em ~/.copilot/session-state/{sessionId}/:

~/.copilot/session-state/
└── user-123-task-456/
    ├── checkpoints/           # Conversation history snapshots
    │   ├── 001.json          # Initial state
    │   ├── 002.json          # After first interaction
    │   └── ...               # Incremental checkpoints
    ├── plan.md               # Agent's planning state (if any)
    └── files/                # Session artifacts
        ├── analysis.md       # Files the agent created
        └── notes.txt         # Working documents
DadosPersistiu?Observações
Histórico de conversas
          ✅ Sim | Thread de mensagem completo |

| Resultados da chamada de ferramenta | ✅ Sim | Armazenado em cache para contexto | | Estado de planejamento do agente | ✅ Sim | Arquivo plan.md | | Artefatos de sessão | ✅ Sim | No files/ diretório | | Chaves de provedor/API | ❌ Não | Segurança: deve restabelecer | | Estado da ferramenta na memória | ❌ Não | As ferramentas devem ser sem estado |

Práticas recomendadas de ID de sessão

Escolha IDs de sessão que codificam a propriedade e a finalidade. Isso facilita muito a auditoria e a limpeza.

PadrãoExemploCaso de uso
          ❌
          `abc123`
         | IDs aleatórias | Difícil de auditar, sem informações de propriedade |

| ✅ user-{userId}-{taskId} | user-alice-pr-review-42 | Aplicativos multiusuários | | ✅ tenant-{tenantId}-{workflow} | tenant-acme-onboarding | SaaS multilocatário | | ✅ {userId}-{taskId}-{timestamp} | alice-deploy-1706932800 | Limpeza baseada em tempo |

Benefícios das IDs estruturadas:

  • Fácil de auditar: "Mostrar todas as sessões para o usuário alice"
  • Fácil de limpar: "Excluir todas as sessões mais antigas que X"
  • Controle de acesso integrado: analisar a ID do usuário a partir da ID da sessão

Exemplo: Gerando IDs de sessão

function createSessionId(userId: string, taskType: string): string {
  const timestamp = Date.now();
  return `${userId}-${taskType}-${timestamp}`;
}

const sessionId = createSessionId("alice", "code-review");
// → "alice-code-review-1706932800000"

Para obter um exemplo em Python, consulte o github/copilot-sdk repositório.

Gerenciando o ciclo de vida da sessão

Listando sessões ativas

// List all sessions
const sessions = await client.listSessions();
console.log(`Found ${sessions.length} sessions`);

for (const session of sessions) {
  console.log(`- ${session.sessionId} (created: ${session.createdAt})`);
}

// Filter sessions by repository
const repoSessions = await client.listSessions({ repository: "owner/repo" });

Limpar sessões antigas

async function cleanupExpiredSessions(maxAgeMs: number) {
  const sessions = await client.listSessions();
  const now = Date.now();
  
  for (const session of sessions) {
    const age = now - new Date(session.createdAt).getTime();
    if (age > maxAgeMs) {
      await client.deleteSession(session.sessionId);
      console.log(`Deleted expired session: ${session.sessionId}`);
    }
  }
}

// Clean up sessions older than 24 hours
await cleanupExpiredSessions(24 * 60 * 60 * 1000);

Desconectando de uma sessão

Quando uma tarefa é concluída, desconecte-se da sessão explicitamente em vez de aguardar o time-out. Isso libera recursos na memória, mas preserva os dados de sessão no disco, portanto, a sessão ainda pode ser retomada mais tarde:

try {
  // Do work...
  await session.sendAndWait({ prompt: "Complete the task" });
  
  // Task complete — release in-memory resources (session can be resumed later)
  await session.disconnect();
} catch (error) {
  // Clean up even on error
  await session.disconnect();
  throw error;
}

Cada SDK fornece padrões de limpeza automática idiomática:

LinguagemPadrãoExemplo
          **TypeScript** | `Symbol.asyncDispose` | `await using session = await client.createSession(config);` |

| Python | async with gerenciador de contexto | async with await client.create_session(config) as session: | | C# | IAsyncDisposable | await using var session = await client.CreateSessionAsync(config); | | | defer | defer session.Disconnect() |

Observação

          `destroy()` foi substituído por `disconnect()` e será removido em uma versão futura. O código existente que usa `destroy()` continuará funcionando, mas deve ser migrado.

Excluindo permanentemente uma sessão

Para remover permanentemente uma sessão e todos os seus dados do disco (histórico de conversa, estado de planejamento, artefatos), use deleteSession. Isso é irreversível: a sessão não pode ser retomada após a exclusão:

// Permanently remove session data
await client.deleteSession("user-123-task-456");

Dica

          `disconnect()` libera recursos na memória, mas mantém os dados de sessão no disco para retomada posterior. 
          `deleteSession()` remove permanentemente tudo, incluindo arquivos em disco.

Limpeza automática: tempo de inatividade

O SDK tem um tempo limite ocioso interno de 30 minutos. As sessões sem atividade são limpas automaticamente. Para obter uma visão geral visual do fluxo de tempo limite ocioso, consulte o github/copilot-sdk repositório.

Ouça os eventos ociosos para saber quando o trabalho é concluído:

session.on("session.idle", (event) => {
  console.log(`Session idle for ${event.idleDurationMs}ms`);
});

Padrões de implantação

Melhor para: isolamento forte, ambientes multitenant, sessões dinâmicas do Azure. Para obter um diagrama visual, consulte o github/copilot-sdk repositório.

Benefits:

  • Isolamento completo
  • Segurança simples
  • Dimensionamento fácil

Padrão 2: servidor da CLI compartilhada (eficiente em recursos)

Melhor para: ferramentas internas, ambientes confiáveis, configurações restritas a recursos. Para obter um diagrama visual, consulte o github/copilot-sdk repositório.

Requisitos:

  • IDs de sessão exclusivas por usuário
  • Controle de acesso no nível do aplicativo
  • Validação da ID da sessão antes das operações
// Application-level access control for shared CLI
async function resumeSessionWithAuth(
  client: CopilotClient,
  sessionId: string,
  currentUserId: string
): Promise<Session> {
  // Parse user from session ID
  const [sessionUserId] = sessionId.split("-");
  
  if (sessionUserId !== currentUserId) {
    throw new Error("Access denied: session belongs to another user");
  }
  
  return client.resumeSession(sessionId);
}

Sessões dinâmicas do Azure

Para implantações sem servidor/contêiner em que os contêineres podem reiniciar ou migrar, o diretório de estado da sessão deve ser montado no armazenamento persistente:

# Azure Container Instance example
containers:
  - name: copilot-agent
    image: my-agent:latest
    volumeMounts:
      - name: session-storage
        mountPath: /home/app/.copilot/session-state

volumes:
  - name: session-storage
    azureFile:
      shareName: copilot-sessions
      storageAccountName: myaccount

Para obter um diagrama visual da persistência de reinicialização do contêiner, consulte o github/copilot-sdk repositório.

Sessões infinitas para fluxos de trabalho de execução longa

Para fluxos de trabalho que podem exceder os limites de contexto, habilite sessões infinitas com compactação automática:

const session = await client.createSession({
  sessionId: "long-workflow-123",
  infiniteSessions: {
    enabled: true,
    backgroundCompactionThreshold: 0.80,  // Start compaction at 80% context
    bufferExhaustionThreshold: 0.95,      // Block at 95% if needed
  },
});

Observação

Os limites são taxas de utilização de contexto (0,0 a 1,0), não contagens absolutas de token.

Limitações e considerações

LimitationDescriçãoAtenuação
          **Autenticação de BYOK** | As chaves de API não são mantidas | Armazene chaves no gerenciador de segredos; fornecer no currículo |

| Armazenamento gravável | ~/.copilot/session-state/ deve ser gravável | Montar volume persistente em contêineres | | Nenhum bloqueio de sessão | O acesso simultâneo à mesma sessão é indefinido | Implementar bloqueio ou fila no nível do aplicativo | | O estado da ferramenta não persistiu | O estado da ferramenta na memória é perdido | Ferramentas de design para serem sem estado ou persistirem seu próprio estado |

Manipulando o acesso simultâneo

O SDK não fornece bloqueio de sessão interno. Se vários clientes puderem acessar a mesma sessão, você deverá garantir que cada sessão esteja bloqueada para impedir o sequestro:

// Option 1: Application-level locking with Redis
import Redis from "ioredis";

const redis = new Redis();

async function withSessionLock<T>(
  sessionId: string,
  fn: () => Promise<T>
): Promise<T> {
  const lockKey = `session-lock:${sessionId}`;
  const acquired = await redis.set(lockKey, "locked", "NX", "EX", 300);
  
  if (!acquired) {
    throw new Error("Session is in use by another client");
  }
  
  try {
    return await fn();
  } finally {
    await redis.del(lockKey);
  }
}

// Usage
await withSessionLock("user-123-task-456", async () => {
  const session = await client.resumeSession("user-123-task-456");
  await session.sendAndWait({ prompt: "Continue the task" });
});

Resumo

CaracterísticaComo usar
          **Criar sessão retomável** | Forneça seu próprio `sessionId` |

| Retomar sessão | client.resumeSession(sessionId) | | Resumo BYOK | Fornecer novamente provider a configuração | | Listar sessões | client.listSessions(filter?) | | Desconectar-se da sessão ativa | session.disconnect()— libera recursos na memória; os dados de sessão no disco são preservados para retomada | | Excluir sessão permanentemente | client.deleteSession(sessionId)— remove permanentemente todos os dados de sessão do disco; não pode ser retomado | | Implantação em contêineres | Montar ~/.copilot/session-state/ no armazenamento persistente |