참고
코필로트 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)