Skip to main content

Gancho para uso antes da ferramenta

Use o onPreToolUse gancho para controlar a execução da ferramenta, modificar argumentos e adicionar contexto antes que uma ferramenta seja executada.SDK do Copilot

Quem pode usar esse recurso?

SDK do GitHub Copilot está disponível com todos os Copilot planos.

Observação

SDK do Copilot está atualmente em versão prévia técnica. A funcionalidade e a disponibilidade estão sujeitas a alterações.

O onPreToolUse gancho é chamado antes da execução de uma ferramenta. Use-o para:

  • Aprovar ou negar a execução da ferramenta
  • Modificar argumentos de ferramenta
  • Adicionar contexto para a ferramenta
  • Suprimir a saída da ferramenta da conversa

Assinatura de Hook

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

Para obter assinaturas de hooks em Python, Go e .NET, consulte o github/copilot-sdk repositório.

Entrada

CampoTipoDescrição
timestampnúmeroTimestamp Unix quando o hook foi acionado
cwdcadeiaDiretório de trabalho atual
toolNamecadeiaNome da ferramenta que está sendo chamada
toolArgsobjetoArgumentos passados para a ferramenta

Saída

Retornar null ou undefined para permitir que a ferramenta seja executada sem alterações. Caso contrário, retorne um objeto com qualquer um dos campos a seguir.

CampoTipoDescrição
permissionDecision
          `"allow"`
          \|
          `"deny"`
          \|
          `"ask"`
         | Se deseja permitir a chamada de ferramenta |

| permissionDecisionReason | cadeia | Explicação mostrada ao usuário (para negar/perguntar) | | modifiedArgs | objeto | Argumentos modificados a serem passados para a ferramenta | | additionalContext | cadeia | Contexto extra injetado na conversa | | suppressOutput | boolean | Se for verdadeiro, o resultado da ferramenta não aparecerá na conversa |

Decisões de permissão

DecisãoComportamento
"allow"A ferramenta é executada normalmente
"deny"A ferramenta está bloqueada, motivo mostrado ao usuário
"ask"O usuário é solicitado a aprovar (modo interativo)

Exemplos

Permitir todas as ferramentas (somente registro em log)

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

Para obter exemplos em Python, Go e .NET, consulte o github/copilot-sdk repositório.

Bloquear ferramentas específicas

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

Modificar argumentos de ferramenta

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

Restringir o acesso a arquivos a diretórios específicos

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

Suprimir saída de ferramenta detalhada

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

Adicionar contexto com base na ferramenta

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

Práticas recomendadas

  •         **Sempre retorne uma decisão.** Retornar `null` permite a ferramenta, mas ser explícito com `{ permissionDecision: "allow" }` é mais claro.
    
  •         **Forneça motivos úteis de negação.** Ao negar, explique por que os usuários entendem o que aconteceu.
    
  •         **Tenha cuidado com a modificação do argumento.** Verifique se os argumentos modificados mantêm o esquema esperado para a ferramenta.
    
  •         **Considere o desempenho.** Os ganchos pré-ferramenta são executados de forma síncrona antes de cada chamada de ferramenta. Mantenha-os sempre rápidos.
    
  •         **Use `suppressOutput` criteriosamente.** Suprimir a saída significa que o modelo não verá o resultado, o que pode afetar a qualidade da conversa.
    
  •         **Esteja atento aos dados confidenciais.** Os argumentos e os resultados da ferramenta podem conter segredos, caminhos de arquivo ou informações de identificação pessoal. Evite registrar ou expor esses dados em ambientes de produção.
    

Leitura adicional

  •         [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)