メモ
Copilot SDK は現在 テクニカル プレビューです。 機能と可用性は変更される場合があります。
`onPreToolUse` フックは、ツールを実行する**前に**呼び出されます。 これは次の目的で使用されます。
- ツールの実行を承認または拒否する
- ツールの引数を変更する
- ツールのコンテキストを追加する
- 会話からのツール出力を抑制する
フック署名
import type { PreToolUseHookInput, HookInvocation, PreToolUseHookOutput } from "@github/copilot-sdk";
type PreToolUseHandler = (
input: PreToolUseHookInput,
invocation: HookInvocation
) => Promise<PreToolUseHookOutput | null | undefined>;
Python、Go、.NET のフック署名については、 github/copilot-sdk リポジトリを参照してください。
入力
| フィールド | タイプ | 説明 |
|---|---|---|
timestamp | 数値 | フックがトリガーされたときの Unix タイムスタンプ |
cwd | 文字列 | 現在の作業ディレクトリ |
toolName | 文字列 | 呼び出されるツールの名前 |
toolArgs | オブジェクト | ツールに渡される引数 |
アウトプット
`null`または`undefined`を返して、変更なしでツールを実行できるようにします。 それ以外の場合は、次のいずれかのフィールドを持つオブジェクトを返します。
| フィールド | タイプ | 説明 |
|---|---|---|
permissionDecision |
`"allow"`
\|
`"deny"`
\|
`"ask"`
| ツール呼び出しを許可するかどうか |
| permissionDecisionReason | 文字列 | ユーザーに表示される説明 (deny/ask) |
| modifiedArgs | オブジェクト | ツールに渡す引数を変更しました |
| additionalContext | 文字列 | 会話に挿入された追加のコンテキスト |
| suppressOutput | ブーリアン | true、ツールの出力は会話に表示されません |
アクセス許可の決定
| 意思決定 | 行動 |
|---|---|
"allow" | ツールが正常に実行される |
"deny" | ツールがブロックされ、その理由がユーザーに表示される |
"ask" | ユーザーに承認を求めるメッセージが表示される (対話型モード) |
例示
すべてのツールを許可する (ログ記録のみ)
const session = await client.createSession({
hooks: {
onPreToolUse: async (input, invocation) => {
console.log(
`[${invocation.sessionId}] `
+ `Calling ${input.toolName}`
);
console.log(
` Args: ${JSON.stringify(input.toolArgs)}`
);
return { permissionDecision: "allow" };
},
},
});
Python、Go、.NET の例については、 github/copilot-sdk リポジトリを参照してください。
特定のツールをブロックする
const BLOCKED_TOOLS = [
"shell", "bash", "write_file", "delete_file",
];
const session = await client.createSession({
hooks: {
onPreToolUse: async (input) => {
if (BLOCKED_TOOLS.includes(input.toolName)) {
return {
permissionDecision: "deny",
permissionDecisionReason:
`Tool '${input.toolName}' `
+ `is not permitted in this environment`,
};
}
return { permissionDecision: "allow" };
},
},
});
ツールの引数を変更する
const session = await client.createSession({
hooks: {
onPreToolUse: async (input) => {
// Add a default timeout to all shell commands
if (
input.toolName === "shell" && input.toolArgs
) {
const args = input.toolArgs as {
command: string;
timeout?: number;
};
return {
permissionDecision: "allow",
modifiedArgs: {
...args,
timeout: args.timeout ?? 30000,
},
};
}
return { permissionDecision: "allow" };
},
},
});
特定のディレクトリへのファイル アクセスを制限する
const ALLOWED_DIRECTORIES = [
"/home/user/projects", "/tmp",
];
const session = await client.createSession({
hooks: {
onPreToolUse: async (input) => {
if (
input.toolName === "read_file"
|| input.toolName === "write_file"
) {
const args = input.toolArgs as {
path: string;
};
const isAllowed =
ALLOWED_DIRECTORIES.some((dir) =>
args.path.startsWith(dir)
);
if (!isAllowed) {
return {
permissionDecision: "deny",
permissionDecisionReason:
`Access to '${args.path}' `
+ `is not permitted. `
+ `Allowed directories: `
+ ALLOWED_DIRECTORIES.join(", "),
};
}
}
return { permissionDecision: "allow" };
},
},
});
冗長なツール出力を抑制する
const VERBOSE_TOOLS = ["list_directory", "search_files"];
const session = await client.createSession({
hooks: {
onPreToolUse: async (input) => {
return {
permissionDecision: "allow",
suppressOutput: VERBOSE_TOOLS.includes(input.toolName),
};
},
},
});
ツールに基づいてコンテキストを追加する
const session = await client.createSession({
hooks: {
onPreToolUse: async (input) => {
if (input.toolName === "query_database") {
return {
permissionDecision: "allow",
additionalContext:
"Remember: This database uses "
+ "PostgreSQL syntax. "
+ "Always use parameterized queries.",
};
}
return { permissionDecision: "allow" };
},
},
});
ベスト プラクティス
-
**常に決定を返します。** `null`を返す方がツールは使用できますが、`{ permissionDecision: "allow" }`で明示的に指定する方が明確です。 -
**役に立つ拒否の理由を提供します。** 拒否する場合は、ユーザーが何が起こったかを理解する理由を説明します。 -
**引数の変更には注意してください。** 変更された引数で、ツールに必要なスキーマが維持されていることを確認します。 -
**パフォーマンスを検討してください。** 事前ツール フックは、各ツール呼び出しの前に同期的に実行されます。 高速状態を維持してください。 -
** `suppressOutput`を慎重に使用してください。** 出力を抑制すると、モデルに結果が表示されないため、会話の品質に影響する可能性があります。 -
**機密データに注意してください。** ツールの引数と結果には、シークレット、ファイル パス、または個人を特定できる情報が含まれている場合があります。 運用環境では、このデータのログ記録や公開は避けてください。
詳細については、次を参照してください。
-
[AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/quickstart) -
[AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/post-tool-use) -
[AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/error-handling)