Skip to main content

Hooks du cycle de vie de la session

Utilisez les crochets onSessionStart et onSessionEnd pour initialiser le contexte, libérer les ressources et suivre les métriques de session dans SDK Copilot.

Qui peut utiliser cette fonctionnalité ?

Kit de développement logiciel (SDK) GitHub Copilot est disponible dans tous les forfaits Copilot.

Remarque

SDK Copilot est actuellement en préversion publique. Les fonctionnalités et la disponibilité sont susceptibles de changer.

Les hooks de cycle de vie de session vous permettent de répondre aux événements de début et de fin de session. Utilisez-les pour :

  • Initialiser le contexte lorsque les sessions commencent
  • Nettoyer les ressources lorsque les sessions se terminent
  • Suivre les métriques de session et l'analyse
  • Configurer dynamiquement le comportement de session

Point d'ancrage pour le démarrage de session

Le onSessionStart hook est appelé lorsqu’une session commence, qu’elle soit nouvelle ou reprise.

Signature du hook

import type { SessionStartHookInput, HookInvocation, SessionStartHookOutput } from "@github/copilot-sdk";
type SessionStartHandler = (
  input: SessionStartHookInput,
  invocation: HookInvocation
) => Promise<
  SessionStartHookOutput | null | undefined
>;

Pour obtenir les signatures de hook dans Python, Go et .NET, consultez le github/copilot-sdk référentiel. Pour Java, consultez le github/copilot-sdk-java référentiel.

Input

ChampTypeDescription
timestampnombreHorodatage Unix lorsque le hook a été déclenché
cwdficelleRépertoire de travail actuel
source
          `"startup"`
          \|
          `"resume"`
          \|
          `"new"`
         | Démarrage de la session |

| initialPrompt | chaîne | non définie | Invitation initiale si disponible |

Sortie

ChampTypeDescription
additionalContextficelleContexte à ajouter au démarrage de la session
modifiedConfigobjetRemplacer la configuration de session

Exemples

Ajouter un contexte de projet au début

const session = await client.createSession({
  hooks: {
    onSessionStart: async (
      input, invocation
    ) => {
      console.log(
        `Session ${invocation.sessionId} `
        + `started (${input.source})`
      );

      const projectInfo =
        await detectProjectType(input.cwd);

      return {
        additionalContext:
          `This is a ${projectInfo.type} project.\n`
          + `Main language: `
          + `${projectInfo.language}\n`
          + `Package manager: `
          + `${projectInfo.packageManager}`,
      };
    },
  },
});

Pour obtenir des exemples dans Python, consultez le github/copilot-sdk référentiel. Pour Java, consultez le github/copilot-sdk-java référentiel.

Gérer la reprise de session

const session = await client.createSession({
  hooks: {
    onSessionStart: async (
      input, invocation
    ) => {
      if (input.source === "resume") {
        const previousState =
          await loadSessionState(
            invocation.sessionId
          );

        return {
          additionalContext:
            `Session resumed. Previous context:\n`
            + `- Last topic: `
            + `${previousState.lastTopic}\n`
            + `- Open files: `
            + previousState.openFiles.join(", "),
        };
      }
      return null;
    },
  },
});

Charger les préférences utilisateur

const session = await client.createSession({
  hooks: {
    onSessionStart: async () => {
      const preferences =
        await loadUserPreferences();

      const contextParts = [];

      if (preferences.language) {
        contextParts.push(
          `Preferred language: `
          + `${preferences.language}`
        );
      }
      if (preferences.codeStyle) {
        contextParts.push(
          `Code style: ${preferences.codeStyle}`
        );
      }
      if (preferences.verbosity === "concise") {
        contextParts.push(
          "Keep responses brief and "
          + "to the point."
        );
      }

      return {
        additionalContext:
          contextParts.join("\n"),
      };
    },
  },
});

Hook de fin de session

Le onSessionEnd hook est appelé lorsqu’une session se termine.

Signature du hook

import {
  HookInvocation,
  SessionEndHookInput,
  SessionEndHookOutput,
} from "@github/copilot-sdk";

type SessionEndHandler = (
  input: SessionEndHookInput,
  invocation: HookInvocation
) => Promise<
  SessionEndHookOutput | null | undefined
>;

Pour obtenir les signatures de hook dans Python, Go et .NET, consultez le github/copilot-sdk référentiel. Pour Java, consultez le github/copilot-sdk-java référentiel.

Input

ChampTypeDescription
timestampnombreHorodatage Unix lorsque le hook a été déclenché
cwdficelleRépertoire de travail actuel
reasonficellePourquoi la session s’est terminée (voir le tableau suivant)
finalMessagechaîne | non définieDernier message de la session
errorchaîne | non définieMessage d’erreur si la session s’est terminée en raison d’une erreur

Raisons de fin

ReasonDescription
"complete"Session terminée normalement
"error"Session terminée en raison d’une erreur
"abort"La session a été abandonnée par l’utilisateur ou le code
"timeout"La session a expiré
"user_exit"L’utilisateur a explicitement terminé la session

Sortie

ChampTypeDescription
suppressOutputbooléen**
Masquer la sortie finale de session
cleanupActionschaîne de caractères[]Liste des actions de nettoyage à effectuer
sessionSummaryficelleRésumé de la session pour la journalisation des événements et les analyses

Exemples

Suivre les métriques de session

const sessionStartTimes =
  new Map<string, number>();

const session = await client.createSession({
  hooks: {
    onSessionStart: async (
      input, invocation
    ) => {
      sessionStartTimes.set(
        invocation.sessionId, input.timestamp
      );
      return null;
    },
    onSessionEnd: async (
      input, invocation
    ) => {
      const startTime = sessionStartTimes.get(
        invocation.sessionId
      );
      const duration = startTime
        ? input.timestamp - startTime
        : 0;

      await recordMetrics({
        sessionId: invocation.sessionId,
        duration,
        endReason: input.reason,
      });

      sessionStartTimes.delete(
        invocation.sessionId
      );
      return null;
    },
  },
});

Pour obtenir des exemples dans Python, consultez le github/copilot-sdk référentiel. Pour Java, consultez le github/copilot-sdk-java référentiel.

Nettoyer les ressources

const sessionResources =
  new Map<string, { tempFiles: string[] }>();

const session = await client.createSession({
  hooks: {
    onSessionStart: async (
      input, invocation
    ) => {
      sessionResources.set(
        invocation.sessionId,
        { tempFiles: [] }
      );
      return null;
    },
    onSessionEnd: async (
      input, invocation
    ) => {
      const resources =
        sessionResources.get(
          invocation.sessionId
        );

      if (resources) {
        for (const file
          of resources.tempFiles) {
          await fs.unlink(file).catch(() => {});
        }
        sessionResources.delete(
          invocation.sessionId
        );
      }

      console.log(
        `Session ${invocation.sessionId} `
        + `ended: ${input.reason}`
      );
      return null;
    },
  },
});

Enregistrer l’état de session pour reprendre

const session = await client.createSession({
  hooks: {
    onSessionEnd: async (input, invocation) => {
      if (input.reason !== "error") {
        // Save state for potential resume
        await saveSessionState(invocation.sessionId, {
          endTime: input.timestamp,
          cwd: input.cwd,
          reason: input.reason,
        });
      }
      return null;
    },
  },
});

Résumé de la session de journalisation

const sessionData: Record<
  string,
  { prompts: number; tools: number;
    startTime: number }
> = {};

const session = await client.createSession({
  hooks: {
    onSessionStart: async (
      input, invocation
    ) => {
      sessionData[invocation.sessionId] = {
        prompts: 0,
        tools: 0,
        startTime: input.timestamp,
      };
      return null;
    },
    onUserPromptSubmitted: async (
      _, invocation
    ) => {
      sessionData[
        invocation.sessionId
      ].prompts++;
      return null;
    },
    onPreToolUse: async (_, invocation) => {
      sessionData[
        invocation.sessionId
      ].tools++;
      return { permissionDecision: "allow" };
    },
    onSessionEnd: async (
      input, invocation
    ) => {
      const data =
        sessionData[invocation.sessionId];
      const durationSec =
        (input.timestamp - data.startTime)
        / 1000;
      console.log(
        `Session Summary:\n`
        + `  ID: ${invocation.sessionId}\n`
        + `  Duration: ${durationSec}s\n`
        + `  Prompts: ${data.prompts}\n`
        + `  Tool calls: ${data.tools}\n`
        + `  End reason: ${input.reason}`
      );

      delete sessionData[
        invocation.sessionId
      ];
      return null;
    },
  },
});

Bonnes pratiques

  •           **Gardez `onSessionStart` rapide.** Les utilisateurs attendent que la session soit prête.
    
  •           **Gérez toutes les raisons de fin.** Ne partez pas du principe que les sessions ne finissent pas correctement ; gérez les erreurs et les interruptions.
    
  • Nettoyer les ressources. Permet onSessionEnd de libérer toutes les ressources allouées pendant la session.
  •           **Conservez un état minimal.** Si vous suivez les données de session, maintenez-les légères.
    
  • Rendre le nettoyage idempotent. onSessionEnd peut ne pas être appelé si le processus se bloque.

Lectures complémentaires