Skip to main content

Session Lifecycle Hooks

Mit Sitzungslebenszyklus-Hooks können Sie auf Start- und Endereignisse der Sitzung reagieren. Verwenden Sie sie für:

  • Initialisieren des Kontexts, wenn Sitzungen beginnen
  • Bereinigen von Ressourcen beim Beenden von Sitzungen
  • Sitzungsmetriken und Analysen nachverfolgen
  • Dynamisches Konfigurieren des Sitzungsverhaltens

Sitzungsstart-Hook {#session-start}

Der onSessionStart Hook wird aufgerufen, wenn eine Sitzung beginnt (neu oder fortgesetzt).

Hook-Signatur

Codesprachen navigation

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

Eingabe

FeldTypBeschreibung
timestampnumberUnix-Zeitstempel, zu dem der Hook ausgelöst wurde
cwdstringAktuelles Arbeitsverzeichnis
source
"startup"
|
"resume"
|
"new"
Wie die Sitzung gestartet wurde
initialPromptZeichenfolge | undefiniertDie anfängliche Eingabeaufforderung, falls angegeben

Output

FeldTypBeschreibung
additionalContextstringKontext zum Hinzufügen am Sitzungsstart
modifiedConfigObjektSitzungskonfiguration außer Kraft setzen

Beispiele

Projektkontext zu Beginn hinzufügen

Codesprachen navigation

TypeScript
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.
Main language: ${projectInfo.language}
Package manager: ${projectInfo.packageManager}
        `.trim(),
      };
    },
  },
});

Verwaltung der Sitzungswiederaufnahme

const session = await client.createSession({
  hooks: {
    onSessionStart: async (input, invocation) => {
      if (input.source === "resume") {
        // Load previous session state
        const previousState = await loadSessionState(invocation.sessionId);
        
        return {
          additionalContext: `
Session resumed. Previous context:
- Last topic: ${previousState.lastTopic}
- Open files: ${previousState.openFiles.join(", ")}
          `.trim(),
        };
      }
      return null;
    },
  },
});

Laden von Benutzereinstellungen

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 für das Sitzungsende {#session-end}

Der onSessionEnd Hook wird aufgerufen, wenn eine Sitzung endet.

Hook-Signatur

Codesprachen navigation

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

Eingabe

FeldTypBeschreibung
timestampnumberUnix-Zeitstempel, zu dem der Hook ausgelöst wurde
cwdstringAktuelles Arbeitsverzeichnis
reasonstringWarum die Sitzung beendet wurde (siehe unten)
finalMessageZeichenfolge | undefiniertDie letzte Nachricht aus der Sitzung
errorZeichenfolge | undefiniertFehlermeldung, wenn die Sitzung aufgrund eines Fehlers beendet wurde

Endgründe

GrundBeschreibung
"complete"Die Sitzung wurde normal abgeschlossen.
"error"Sitzung aufgrund eines Fehlers beendet
"abort"Die Sitzung wurde durch den Benutzer oder durch Code abgebrochen.
"timeout"Timeout für die Sitzung
"user_exit"Der Benutzer hat die Sitzung explizit beendet.

Output

FeldTypBeschreibung
suppressOutputbooleanEndgültige Sitzungsausgabe unterdrücken
cleanupActionsstring[]Liste der auszuführenden Bereinigungsaktionen
sessionSummarystringZusammenfassung der Sitzung für Protokollierung/Analyse

Beispiele

Nachverfolgen von Sitzungsmetriken

Codesprachen navigation

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

Bereinigen von Ressourcen

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) {
        // Clean up temp files
        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;
    },
  },
});

Sitzungsstatus zum Fortsetzen speichern

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

Protokollsitzungszusammenfassung

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];
      console.log(`
Session Summary:
  ID: ${invocation.sessionId}
  Duration: ${(input.timestamp - data.startTime) / 1000}s
  Prompts: ${data.prompts}
  Tool calls: ${data.tools}
  End reason: ${input.reason}
      `.trim());
      
      delete sessionData[invocation.sessionId];
      return null;
    },
  },
});

Bewährte Methoden

  1. Sorgen Sie dafür, dass onSessionStart schnell bleibt – Die Benutzer warten darauf, dass die Sitzung einsatzbereit ist.

  2. Berücksichtigen Sie alle Gründe für die Beendigung – Gehen Sie nicht davon aus, dass Sitzungen immer ordnungsgemäß beendet werden; behandeln Sie auch Fehler und Abbrüche.

  3. Ressourcen freigeben – Verwenden Sie onSessionEnd, um alle während der Sitzung zugewiesenen Ressourcen freizugeben.

  4. Speichern Sie so wenig Status wie möglich - Wenn Sie Sitzungsdaten verfolgen, halten Sie sie so schlank wie möglich.

  5.           **Machen Sie die Bereinigung idempotent** - `onSessionEnd` wird möglicherweise nicht aufgerufen, wenn der Prozess abstürzt.
    

Siehe auch