참고
코필로트 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 | 문자열 | 사용자에게 표시되는 설명(거부/요청) |
| 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)