Skip to main content
Select language: current language is French
Rechercher ou demander à Copilot
Ouvrir le menu

Hook exécuté avant l’utilisation d’un outil

Utilisez le hook onPreToolUse pour contrôler l’exécution de l’outil, modifier les arguments et ajouter du contexte avant l’exécution d’un outil Kit de développement logiciel (SDK) Copilot.

Qui peut utiliser cette fonctionnalité ?

SDK GitHub Copilot est disponible dans tous les forfaits Copilot.

Dans cet article

Remarque

Copilot SDK is currently in public preview. Functionality and availability are subject to change.

The onPreToolUse hook is called before a tool executes. Use it to:

  • Approve or deny tool execution
  • Modify tool arguments
  • Add context for the tool
  • Suppress tool output from the conversation

Hook signature

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

For hook signatures in Python, Go, and .NET, see the github/copilot-sdk repository. For Java, see the github/copilot-sdk-java repository.

Input

FieldTypeDescription
timestampnumberUnix timestamp when the hook was triggered
cwdstringCurrent working directory
toolNamestringName of the tool being called
toolArgsobjectArguments passed to the tool

Output

Return null or undefined to allow the tool to execute with no changes. Otherwise, return an object with any of the following fields.

FieldTypeDescription
permissionDecision"allow" | "deny" | "ask"Whether to allow the tool call
permissionDecisionReasonstringExplanation shown to user (for deny/ask)
modifiedArgsobjectModified arguments to pass to the tool
additionalContextstringExtra context injected into the conversation
suppressOutputbooleanIf true, tool output won't appear in conversation

Permission decisions

DecisionBehavior
"allow"Tool executes normally
"deny"Tool is blocked, reason shown to user
"ask"User is prompted to approve (interactive mode)

Examples

Allow all tools (logging only)

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

For examples in Python, Go, and .NET, see the github/copilot-sdk repository. For Java, see the github/copilot-sdk-java repository.

Block specific tools

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

Modify tool arguments

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

Restrict file access to specific directories

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

Suppress verbose tool output

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

Add context based on tool

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

Best practices

  • Always return a decision. Returning null allows the tool, but being explicit with { permissionDecision: "allow" } is clearer.
  • Provide helpful denial reasons. When denying, explain why so users understand what happened.
  • Be careful with argument modification. Ensure modified arguments maintain the expected schema for the tool.
  • Consider performance. Pre-tool hooks run synchronously before each tool call. Keep them fast.
  • Use suppressOutput judiciously. Suppressing output means the model won't see the result, which may affect conversation quality.
  • Be mindful of sensitive data. Tool arguments and results may contain secrets, file paths, or personally identifiable information. Avoid logging or exposing this data in production environments.

Further reading

Morty Proxy This is a proxified and sanitized view of the page, visit original site.