Skip to main content

Сессионные хуки

Крючки позволяют перехватывать и настраивать поведение сессий Copilot в ключевые моменты жизненного цикла разговора. Используйте крючки, чтобы:

  • Выполнение инструментов управления — одобрение, отклонение или изменение вызовов инструментов
  • Преобразование результатов — модифицировать выходы инструментов до их обработки
  • Добавить контекст — ввести дополнительную информацию при начале сессии
  • Обработка ошибок — реализация пользовательской обработки ошибок
  • Аудит и журнал — отслеживайте все взаимодействия для соответствия требованиям

Доступные крючки

ХукТриггерВариант использования
Крючок для использования до использования инструментаДо запуска инструментаКонтроль разрешений, проверка аргументов
Крючок после использования инструментаПосле запуска инструмента (только успех)Преобразование результата, логирование
Крючок после использования инструментаПосле выполнения инструмента, результат которого оказался неудачнымИнжекция повторных инструкций, сбои журнала
Хук, присланный пользовательским запросомКогда пользователь отправляет сообщениеИзменение подсказок, фильтрация
Крючки жизненного цикла сессииНачало сессииДобавьте контекст, настройте сессию
Крючки жизненного цикла сессииСессия завершенаОчистка, аналитика
Крюк для обработки ошибокОшибка возникаетОбработка пользовательских ошибок

Быстрый старт

TypeScript
import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();

const session = await client.createSession({
  hooks: {
    onPreToolUse: async (input) => {
      console.log(`Tool called: ${input.toolName}`);
      // Allow all tools
      return { permissionDecision: "allow" };
    },
    onPostToolUse: async (input) => {
      console.log(`Tool result: ${JSON.stringify(input.toolResult)}`);
      return null; // No modifications
    },
    onSessionStart: async (input) => {
      return { additionalContext: "User prefers concise answers." };
    },
  },
});
Python
from copilot import CopilotClient
from copilot.session import PermissionHandler

async def main():
    client = CopilotClient()
    await client.start()

    async def on_pre_tool_use(input_data, invocation):
        print(f"Tool called: {input_data['toolName']}")
        return {"permissionDecision": "allow"}

    async def on_post_tool_use(input_data, invocation):
        print(f"Tool result: {input_data['toolResult']}")
        return None

    async def on_session_start(input_data, invocation):
        return {"additionalContext": "User prefers concise answers."}

    session = await client.create_session(on_permission_request=PermissionHandler.approve_all, hooks={
            "on_pre_tool_use": on_pre_tool_use,
            "on_post_tool_use": on_post_tool_use,
            "on_session_start": on_session_start,
        })
Go
package main

import (
    "context"
    "fmt"
    copilot "github.com/github/copilot-sdk/go"
)

func main() {
    client := copilot.NewClient(nil)

    session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{
        Hooks: &copilot.SessionHooks{
            OnPreToolUse: func(input copilot.PreToolUseHookInput, inv copilot.HookInvocation) (*copilot.PreToolUseHookOutput, error) {
                fmt.Printf("Tool called: %s\n", input.ToolName)
                return &copilot.PreToolUseHookOutput{
                    PermissionDecision: "allow",
                }, nil
            },
            OnPostToolUse: func(input copilot.PostToolUseHookInput, inv copilot.HookInvocation) (*copilot.PostToolUseHookOutput, error) {
                fmt.Printf("Tool result: %v\n", input.ToolResult)
                return nil, nil
            },
            OnSessionStart: func(input copilot.SessionStartHookInput, inv copilot.HookInvocation) (*copilot.SessionStartHookOutput, error) {
                return &copilot.SessionStartHookOutput{
                    AdditionalContext: "User prefers concise answers.",
                }, nil
            },
        },
    })
    _ = session
}
.NET
using GitHub.Copilot;

var client = new CopilotClient();

var session = await client.CreateSessionAsync(new SessionConfig
{
    Hooks = new SessionHooks
    {
        OnPreToolUse = (input, invocation) =>
        {
            Console.WriteLine($"Tool called: {input.ToolName}");
            return Task.FromResult<PreToolUseHookOutput?>(
                new PreToolUseHookOutput { PermissionDecision = "allow" }
            );
        },
        OnPostToolUse = (input, invocation) =>
        {
            Console.WriteLine($"Tool result: {input.ToolResult}");
            return Task.FromResult<PostToolUseHookOutput?>(null);
        },
        OnSessionStart = (input, invocation) =>
        {
            return Task.FromResult<SessionStartHookOutput?>(
                new SessionStartHookOutput { AdditionalContext = "User prefers concise answers." }
            );
        },
    },
});
Java
import com.github.copilot.sdk.*;
import com.github.copilot.sdk.json.*;
import java.util.concurrent.CompletableFuture;

try (var client = new CopilotClient()) {
    client.start().get();

    var hooks = new SessionHooks()
        .setOnPreToolUse((input, invocation) -> {
            System.out.println("Tool called: " + input.getToolName());
            return CompletableFuture.completedFuture(PreToolUseHookOutput.allow());
        })
        .setOnPostToolUse((input, invocation) -> {
            System.out.println("Tool result: " + input.getToolResult());
            return CompletableFuture.completedFuture(null);
        })
        .setOnSessionStart((input, invocation) -> {
            return CompletableFuture.completedFuture(
                new SessionStartHookOutput("User prefers concise answers.", null)
            );
        });

    var session = client.createSession(
        new SessionConfig()
            .setHooks(hooks)
            .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
    ).get();
}

Контекст вызова крюка

Каждый крюк получает invocation параметр с контекстом текущей сессии:

ПолеТипDescription
sessionIdstringID текущей сессии

Это позволяет хукам сохранять состояние или выполнять логику, специфичную для сессии.

Распространенные шаблоны

Логирование всех вызовов инструментов

const session = await client.createSession({
  hooks: {
    onPreToolUse: async (input) => {
      console.log(`[${new Date().toISOString()}] Tool: ${input.toolName}, Args: ${JSON.stringify(input.toolArgs)}`);
      return { permissionDecision: "allow" };
    },
    onPostToolUse: async (input) => {
      console.log(`[${new Date().toISOString()}] Result: ${JSON.stringify(input.toolResult)}`);
      return null;
    },
  },
});

Блокировка опасных инструментов

const BLOCKED_TOOLS = ["shell", "bash", "exec"];

const session = await client.createSession({
  hooks: {
    onPreToolUse: async (input) => {
      if (BLOCKED_TOOLS.includes(input.toolName)) {
        return {
          permissionDecision: "deny",
          permissionDecisionReason: "Shell access is not permitted",
        };
      }
      return { permissionDecision: "allow" };
    },
  },
});

Добавление пользовательского контекста

const session = await client.createSession({
  hooks: {
    onSessionStart: async () => {
      const userPrefs = await loadUserPreferences();
      return {
        additionalContext: `User preferences: ${JSON.stringify(userPrefs)}`,
      };
    },
  },
});

Гайды по крючкам

См. также