Skip to main content

Крючок для использования до использования инструмента

Используйте onPreToolUse крючок для управления выполнением инструмента, изменения аргументов и добавления контекста перед запуском инструмента в Второй пилот SDK.

Кто может использовать эту функцию?

GitHub Copilot SDK Доступна со всеми Copilot тарифными планами.

Примечание.

Второй пилот SDK в настоящее время находится в Technical Preview. Функциональность и доступность могут меняться.

          `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 | булевый | Если это правда, то результат инструмента не будет отображаться в разговоре |

Решения по разрешению

РешениеПоведение
"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)