メモ
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 | 文字列 | 未定義 | エラーが原因でセッションが終了した場合のエラー メッセージ |
終了の理由
| 理由 | 説明 |
|---|---|
"complete" | セッションが正常に完了しました |
"error" | エラーが原因でセッションが終了しました |
"abort" | ユーザーまたはコードによってセッションが中止されました |
"timeout" | セッションがタイムアウトしました |
"user_exit" | ユーザーがセッションを明示的に終了した |
アウトプット
| フィールド | タイプ | 説明 |
|---|---|---|
suppressOutput | ブーリアン | 最後のセッション出力を抑制する |
cleanupActions | string[] | 実行するクリーンアップ アクションの一覧 |
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`を使用して、セッション中に割り当てられたリソースを解放します。 -
**最小状態を格納します。** セッション データを追跡する場合は、軽量のままにします。 -
**クリーンアップを冪等性にします。** `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)