Skip to main content

세션 수명 주기 후크

          `onSessionStart` 및 `onSessionEnd` 후크를 사용하여 컨텍스트를 초기화하고, 리소스를 정리하고, 세션 메트릭을 추적합니다코필로트 SDK.

누가 이 기능을 사용할 수 있나요?

GitHub Copilot SDK 는 모든 Copilot 계획에서 사용할 수 있습니다.

참고

코필로트 SDK가 현재 기술 미리 보기에 있습니다. 기능 및 가용성은 변경될 수 있습니다.

세션 수명 주기 후크를 사용하면 세션 시작 및 종료 이벤트에 응답할 수 있습니다. 이를 사용하여 다음을 수행합니다.

  • 세션이 시작될 때 컨텍스트 초기화
  • 세션이 종료되면 리소스 정리
  • 세션 메트릭 및 분석 추적
  • 동적으로 세션 동작 구성

세션 시작 후크

          `onSessionStart` 새 세션이든 다시 시작하든 세션이 시작될 때 후크가 호출됩니다.

후크 서명

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

Python, Go 및 .NET의 후크 서명은 리포지토리를github/copilot-sdk 참조하세요.

입력

분야유형설명
timestamp숫자후크가 트리거될 때의 Unix 타임스탬프
cwd문자열현재 작업 디렉터리
source
          `"startup"`
          \|
          `"resume"`
          \|
          `"new"`
         | 세션이 시작된 방법 |

| initialPrompt | 정의되지 않은 문자열 | | 제공된 경우 초기 프롬프트 |

출력

분야유형설명
additionalContext문자열세션 시작 시 추가할 컨텍스트
modifiedConfig객체세션 구성 재정의

예제

시작 시 프로젝트 컨텍스트 추가

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

Python의 예제는 리포지토리를github/copilot-sdk 참조하세요.

세션 다시 시작 처리

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

사용자 기본 설정 로드

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

세션 끝 후크

세션이 onSessionEnd 종료되면 후크가 호출됩니다.

후크 서명

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

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

Python, Go 및 .NET의 후크 서명은 리포지토리를github/copilot-sdk 참조하세요.

입력

분야유형설명
timestamp숫자후크가 트리거될 때의 Unix 타임스탬프
cwd문자열현재 작업 디렉터리
reason문자열세션이 종료된 이유(다음 표 참조)
finalMessage정의되지 않은 문자열 |세션의 마지막 메시지
error정의되지 않은 문자열 |오류로 인해 세션이 종료된 경우 오류 메시지

종료 이유

Reason설명
"complete"세션이 정상적으로 완료됨
"error"오류로 인해 세션이 종료됨
"abort"사용자 또는 코드에 의해 세션이 중단되었습니다.
"timeout"세션 시간이 초과됨
"user_exit"사용자가 세션을 명시적으로 종료했습니다.

출력

분야유형설명
suppressOutput부울최종 세션 출력 표시 안 함
cleanupActions문자열[]수행할 정리 작업 목록
sessionSummary문자열로깅/분석을 위한 세션 요약

예제

세션 메트릭 추적

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

Python의 예제는 리포지토리를github/copilot-sdk 참조하세요.

자원을 정리하세요

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

다시 시작에 대한 세션 상태 저장

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

로그 세션 요약

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

모범 사례

  •         **빠르게 유지하십시오 `onSessionStart`.** 사용자가 세션이 준비되기를 기다리고 있습니다.
    
  •         **모든 종료 이유를 처리합니다.** 세션이 완전히 종료된다고 가정하지 마세요. 오류 및 중단을 처리합니다.
    
  •         **리소스를 정리합니다.** 
            `onSessionEnd`를 사용하여 세션 중에 할당된 리소스를 해제합니다.
    
  •         **최소 상태를 저장합니다.** 세션 데이터를 추적하는 경우 간단하게 유지합니다.
    
  •         **정리 작업을 idempotent하게 만듭니다.** 
            `onSessionEnd` 프로세스가 충돌하는 경우 호출되지 않을 수 있습니다.
    

추가 읽기

  •         [AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/quickstart)
    
  •         [AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/error-handling)
    
  •         [AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/user-prompt-submitted)