- Controlar la ejecución de herramientas - aprobar, denegar o modificar las llamadas a herramientas
- Transformar resultados : modificar las salidas de la herramienta antes de procesarlas
- Adición de contexto : inserción de información adicional al inicio de la sesión
- Control de errores : implementación del control de errores personalizado
- Auditoría y registro : realizar un seguimiento de todas las interacciones para el cumplimiento
Para los hooks del sistema de archivos cargados desde directorios de inicio adicionales en lugar de callbacks del SDK registrados, consulte Trabajar con enlaces.
Enlaces disponibles
| Enlace | Trigger | Caso de uso |
|---|---|---|
| Gancho previo al uso de la herramienta | Antes de que se ejecute una herramienta | Control de permisos, validación de argumentos |
| Enlace de uso posterior a la herramienta | Después de ejecutar una herramienta (solo en caso de éxito) | Transformación de resultados, registro |
| Enlace de uso posterior a la herramienta | Después de una ejecución de la herramienta cuyo resultado fue un error | Insertar directrices de reintento, registrar fallos |
| Enlace enviado de la solicitud de usuario | Cuando el usuario envía un mensaje | Modificación rápida, filtrado |
| Gancho de transformación de la solicitud al usuario | Tras la transformación de indicaciones en tiempo de ejecución | Inspección o reemplazo del contenido orientado al modelo |
| Enlaces de ciclo de vida de sesión | Inicio de la sesión | Agregar contexto, configurar sesión |
| Enlaces de ciclo de vida de sesión | Finaliza la sesión | Limpieza, análisis |
| Gancho de manejo de errores | Se produce un error | Control de errores personalizado |
| Enlaces de ciclo de vida de sesión | El agente de nivel superior se detiene naturalmente | Validar la finalización o solicitar otro turno |
Inicio rápido
Lenguajes de código navigation
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.*;
import com.github.copilot.rpc.*;
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();
}
Contexto de invocación del enlace
Cada hook recibe un parámetro invocation con información sobre la sesión actual:
| Campo | Tipo | Descripción |
|---|---|---|
sessionId | string | Identificador de la sesión actual |
Esto permite que los hooks conserven el estado o realicen lógica específica de la sesión.
Patrones comunes
Registro de todas las llamadas a herramientas
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;
},
},
});
Bloqueo de herramientas peligrosas
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" };
},
},
});
Agregar contexto de usuario
const session = await client.createSession({
hooks: {
onSessionStart: async () => {
const userPrefs = await loadUserPreferences();
return {
additionalContext: `User preferences: ${JSON.stringify(userPrefs)}`,
};
},
},
});
Guías de enlace
- Gancho previo al uso de la herramienta : permisos de ejecución de herramientas de control
- Enlace de uso posterior a la herramienta: resultados de la herramienta de transformación
- Enlace enviado de la solicitud de usuario : modificación de solicitudes de usuario
- Gancho de transformación de la solicitud al usuario - Reemplazar indicaciones dirigidas al modelo
- Enlaces de ciclo de vida de sesión : inicio y finalización de la sesión
- Enlaces de ciclo de vida de sesión - Validar la finalización antes de que se detenga el agente
- Gancho de manejo de errores : control de errores personalizado