Skip to main content

Persistencia de sesión en el SDK de Copilot

Pausar, reanudar y gestionar SDK de Copilot sesiones entre los reinicios y las implementaciones.

¿Quién puede utilizar esta característica?

SDK de GitHub Copilot está disponible con todos los Copilot planes.

Nota:

SDK de Copilot actualmente está en versión preliminar pública. La funcionalidad y la disponibilidad están sujetas a cambios.

Al crear una sesión, SDK de Copilot mantiene el historial de conversaciones, el estado de la herramienta y el contexto de planificación. De forma predeterminada, este estado reside en la memoria y desaparece cuando finaliza la sesión. Con la persistencia habilitada, puede reanudar las sesiones entre reinicios, migraciones de contenedor o incluso instancias de cliente diferentes. Para obtener información general visual sobre el ciclo de vida del estado de sesión, consulte el github/copilot-sdk repositorio.

Estado¿Qué ocurre?
Crear
sessionId asignado
ActivoEnviar avisos, llamadas a herramientas, respuestas
En pausaEstado guardado en el disco
ReanudarEstado cargado desde el disco

Inicio rápido: creación de una sesión reanudable

La clave para las sesiones reanudables es proporcionar tu propio sessionId (otros SDK pueden usar session_id). Sin uno, el SDK genera un identificador aleatorio y la sesión no se puede reanudar más adelante.

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 obtener ejemplos en Python, Go y C#, consulte el github/copilot-sdk repositorio. Para Java, consulte el github/copilot-sdk-java repositorio.

Reanudación de una sesión

Puede reanudar una sesión desde donde finalizó (minutos, horas o incluso días posteriores). Para obtener información general visual sobre la reanudación de la sesión entre clientes, consulte el github/copilot-sdk repositorio.

// 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 obtener ejemplos en Python, Go y C#, consulte el github/copilot-sdk repositorio. Para Java, consulte el github/copilot-sdk-java repositorio.

Opciones de reanudación

Al reanudar una sesión, puede volver a configurar muchas opciones de configuración. Esto resulta útil cuando necesita cambiar el modelo, actualizar configuraciones de herramientas o modificar el comportamiento.

OpciónDescripción
modelCambiar el modelo de la sesión reanudada
systemMessageAnular o ampliar el mensaje del sistema
availableToolsRestringir qué herramientas están disponibles
excludedToolsDeshabilitar herramientas específicas
providerVolver a proporcionar las credenciales BYOK (necesarias para las sesiones BYOK)
reasoningEffortAjuste del nivel de esfuerzo de razonamiento
streamingHabilitar o deshabilitar las respuestas de streaming
workingDirectoryCambiar el directorio de trabajo
configDirInvalidar el directorio de configuración
mcpServersConfiguración de servidores MCP
customAgentsConfiguración de agentes personalizados
agentSelección previa de un agente personalizado por nombre
skillDirectoriesDirectorios para cargar habilidades desde
disabledSkillsHabilidades para desactivar
infiniteSessionsConfiguración del comportamiento infinito de la sesión

Ejemplo: Cambio de modelo en el currículum

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

Uso de BYOK con sesiones reanudadas

Al usar sus propias claves de API, debe volver a proporcionar la configuración del proveedor al reanudar la sesión. Las claves de API nunca se conservan en el disco por motivos de seguridad.

// 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",
  },
});

¿Qué se vuelve persistente?

El estado de sesión se guarda en ~/.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
Datos¿Continúa?Notas
Historial de conversaciones
✅ SíHilo de mensajes completo
Resultados de la llamada a la herramienta
✅ SíAlmacenado en caché para el contexto
Estado de planificación del agente
✅ Síarchivo plan.md
Artefactos de sesión
✅ SíEn files/ el directorio
Claves de proveedor o API
❌ NoSeguridad: debe proporcionarse nuevamente
Estado de la herramienta en memoria
❌ NoLas herramientas no deben tener estado

Procedimientos recomendados de identificador de sesión

Elija identificadores de sesión que codifiquen la propiedad y el propósito. Esto facilita mucho la auditoría y la limpieza.

ModeloEjemploCaso de uso
abc123
Identificadores aleatoriosDifícil de auditar, sin información de propiedad
user-{userId}-{taskId}
user-alice-pr-review-42Aplicaciones multiusuario
tenant-{tenantId}-{workflow}
tenant-acme-onboardingSaaS multicliente
{userId}-{taskId}-{timestamp}
alice-deploy-1706932800Limpieza basada en tiempo

Ventajas de los identificadores estructurados:

  • Fácil de auditar: "Mostrar todas las sesiones para el usuario alice"
  • Fácil de limpiar: "Eliminar todas las sesiones anteriores a X"
  • Control de acceso automatizado: extraer el identificador de usuario desde el identificador de sesión

Ejemplo: Generación de identificadores de sesión

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 obtener un ejemplo en Python, consulte el github/copilot-sdk repositorio. Para Java, consulte el github/copilot-sdk-java repositorio.

Administración del ciclo de vida de la sesión

Enumeración de sesiones activas

// 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" });

Limpieza de sesiones antiguas

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

Desconexión de una sesión

Cuando se complete una tarea, desconecte de la sesión explícitamente en lugar de esperar tiempos de espera. Esto libera recursos en memoria, pero conserva los datos de sesión en el disco, por lo que la sesión todavía se puede reanudar más adelante:

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 proporciona patrones de limpieza automática idiomáticos:

LanguageModeloEjemplo
TypeScriptSymbol.asyncDisposeawait using session = await client.createSession(config);
Python
async with administrador de contextoasync with await client.create_session(config) as session:
C#IAsyncDisposableawait using var session = await client.CreateSessionAsync(config);
Godeferdefer session.Disconnect()
Javatry-with-resourcestry (var session = client.createSession(config).get()) { ... }

Nota:

destroy() se ha reemplazado por disconnect() y se quitará en una versión futura. El código existente que usa destroy() seguirá funcionando, pero se debe migrar.

Eliminación permanente de una sesión

Para quitar permanentemente una sesión y todos sus datos del disco (historial de conversaciones, estado de planeación, artefactos), use deleteSession. Esto es irreversible: la sesión no se puede reanudar después de la eliminación:

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

Sugerencia

disconnect() libera recursos en memoria, pero mantiene los datos de sesión en el disco para la reanudación posterior. deleteSession() quita permanentemente todo, incluidos los archivos en el disco.

Limpieza automática: tiempo de espera por inactividad

El SDK tiene un tiempo de espera de inactividad integrado de 30 minutos. Las sesiones sin actividad se limpian automáticamente. Para obtener una visión general visual sobre el flujo de tiempo de inactividad, consulte el github/copilot-sdk repositorio.

Escuche los eventos de inactividad para saber cuándo finaliza el trabajo.

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

Patrones de implementación

Ideal para: aislamiento seguro, entornos multiinquilino, sesiones dinámicas de Azure. Para ver un diagrama visual, consulte el github/copilot-sdk repositorio.

Ventajas:

  • Aislamiento completo
  • Seguridad sencilla
  • Escalado sencillo

Patrón 2: servidor de la CLI compartido (eficaz para recursos)

Ideal para: herramientas internas, entornos de confianza, configuraciones restringidas a recursos. Para ver un diagrama visual, consulte el github/copilot-sdk repositorio.

Requisitos:

  • Identificadores de sesión únicos por usuario
  • Control de acceso de nivel de aplicación
  • Validación del identificador de sesión antes de las operaciones
// 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);
}

Sesiones dinámicas de Azure

En el caso de las implementaciones sin servidor o contenedor en las que los contenedores pueden reiniciar o migrar, el directorio de estado de sesión debe montarse en almacenamiento 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 ver un diagrama visual de la persistencia del reinicio del contenedor, consulte el github/copilot-sdk repositorio.

Sesiones ilimitadas para flujos de trabajo de larga duración

En el caso de los flujos de trabajo que pueden superar los límites de contexto, habilite sesiones infinitas con compactación 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
  },
});

Nota:

Los umbrales son relaciones de uso de contexto (0,0–1,0), no recuentos absolutos de tokens.

Limitaciones y consideraciones

LimitaciónDescripciónMitigación
Volver a autenticar BYOKLas claves de API no se conservanAlmacene claves en su gestor de secretos; proporciónelas al reanudar
Almacenamiento escribible
~/.copilot/session-state/ debe ser escribibleMonte volumen persistente en contenedores
Sin bloqueo de sesiónEl acceso simultáneo a la misma sesión no está definidoImplementar el bloqueo o la cola a nivel de aplicación
El estado de la herramienta no se conservaSe pierde el estado de la herramienta en memoriaDiseñe herramientas para que sean sin estado o conserven su propio estado.

Control del acceso simultáneo

El SDK no proporciona bloqueo de sesión integrado. Si varios clientes pueden acceder a la misma sesión, debe asegurarse de que cada sesión está bloqueada para evitar el secuestro:

// 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" });
});

Resumen

FeatureCómo usar
Creación de una sesión reanudableProporcione su propio sessionId
Reanudar sesiónclient.resumeSession(sessionId)
Reanudación de BYOKVolver a proporcionar la configuración de provider
Enumerar las sesionesclient.listSessions(filter?)
Desconexión de la sesión activa
session.disconnect()— libera recursos en memoria; se conservan los datos de sesión en el disco para la reanudación
Eliminar sesión permanentemente
client.deleteSession(sessionId)— quita permanentemente todos los datos de sesión del disco; no se puede reanudar
Implementación en contenedoresMontar ~/.copilot/session-state/ a almacenamiento persistente