Skip to main content

Gancho previo al uso de la herramienta

Use el mecanismo onPreToolUse para controlar la ejecución de la herramienta, modificar argumentos y agregar contexto antes de que se ejecute una herramienta en SDK de Copilot.

¿Quién puede utilizar esta característica?

SDK de GitHub Copilot está disponible con todos los Copilot planes.

Nota:

SDK de Copilot actualmente está en Versión preliminar técnica. La funcionalidad y la disponibilidad están sujetas a cambios.

Se llama al onPreToolUse gancho antes de que se ejecute una herramienta. Utilícelo para:

  • Aprobación o denegación de la ejecución de la herramienta
  • Modificación de argumentos de herramienta
  • Adición de contexto para la herramienta
  • Suprimir la salida de la herramienta de la conversación

Firma de hook

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

Para obtener firmas de enlace en Python, Go y .NET, consulte el github/copilot-sdk repositorio.

Entrada

CampoTipoDescripción
timestampnúmeroMarca de tiempo de Unix cuando se desencadenó el enlace
cwdcuerda / cadenaDirectorio de trabajo actual
toolNamecuerda / cadenaNombre de la herramienta invocada
toolArgsobjetoArgumentos pasados a la herramienta

Salida

Devuelve null o undefined permite que la herramienta se ejecute sin cambios. De lo contrario, devuelve un objeto con cualquiera de los campos siguientes.

CampoTipoDescripción
permissionDecision
          `"allow"`
          \|
          `"deny"`
          \|
          `"ask"`
         | Indica si se va a permitir la llamada a la herramienta |

| permissionDecisionReason | cuerda / cadena | Explicación que se muestra al usuario (para denegar o pedir) | | modifiedArgs | objeto | Argumentos modificados para pasar a la herramienta | | additionalContext | cuerda / cadena | Contexto adicional insertado en la conversación | | suppressOutput | boolean | Si es verdadero, la salida de la herramienta no aparecerá en la conversación. |

Decisiones de permisos

DecisiónComportamiento
"allow"La herramienta se ejecuta normalmente
"deny"La herramienta está bloqueada, motivo que se muestra al usuario
"ask"Se pide al usuario que apruebe (modo interactivo)

Ejemplos

Permitir todas las herramientas (solo registro)

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 obtener ejemplos en Python, Go y .NET, consulte el github/copilot-sdk repositorio.

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

Modificación de argumentos de herramienta

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

Restricción del acceso a archivos a directorios 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" };
    },
  },
});

Supresión de la salida detallada de la herramienta

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

Añadir contexto según la herramienta

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

procedimientos recomendados

  • Siempre devolver una decisión. Devolver null permite la herramienta, pero ser explícito con { permissionDecision: "allow" } es más claro.
  •         **Proporcione razones de denegación útiles.** Al denegar, explique por qué para que los usuarios comprendan lo que ha ocurrido.
    
  •         **Tenga cuidado con la modificación de argumentos.** Asegúrese de que los argumentos modificados mantienen el esquema esperado para la herramienta.
    
  •         **Considere el rendimiento.** Los ganchos previos a la herramienta se ejecutan sincrónicamente antes de cada llamada de herramienta. Manténgalos ágiles.
    
  •         **Usa `suppressOutput` con criterio.** Suprimir la salida significa que el modelo no verá el resultado, lo que puede afectar a la calidad de la conversación.
    
  •         **Tenga en cuenta la información confidencial.** Los argumentos y los resultados de la herramienta pueden contener secretos, rutas de acceso de archivo o información de identificación personal. Evite registrar o exponer estos datos en entornos de producción.
    

Lectura 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)