Saltar al contenido principal

Hooks de sesión

Con hooks puedes insertar lógica en cada punto del ciclo de vida de una sesión de Copilot.
Puedes añadir control de ejecución de herramientas, log de auditoría, enriquecimiento de prompts, manejo de errores, etc., sin tocar la implementación principal.

Flujo de los hooks

Uso básico

use Revolution\Copilot\Contracts\CopilotSession;
use Revolution\Copilot\Facades\Copilot;
use Revolution\Copilot\Types\SessionHooks;
use Revolution\Copilot\Types\Hooks\ErrorOccurredHookInput;
use Revolution\Copilot\Types\Hooks\ErrorOccurredHookOutput;
use Revolution\Copilot\Types\Hooks\PostToolUseHookInput;
use Revolution\Copilot\Types\Hooks\PostToolUseHookOutput;
use Revolution\Copilot\Types\Hooks\PreToolUseHookInput;
use Revolution\Copilot\Types\Hooks\PreToolUseHookOutput;
use Revolution\Copilot\Types\Hooks\SessionEndHookInput;
use Revolution\Copilot\Types\Hooks\SessionEndHookOutput;
use Revolution\Copilot\Types\Hooks\SessionStartHookInput;
use Revolution\Copilot\Types\Hooks\SessionStartHookOutput;
use Revolution\Copilot\Types\Hooks\UserPromptSubmittedHookInput;
use Revolution\Copilot\Types\Hooks\UserPromptSubmittedHookOutput;

Copilot::start(function (CopilotSession $session) {
    $response = $session->sendAndWait(prompt: 'READMEの要点をまとめて');
    dump($response->content());
}, config: [
    'model' => 'gpt-5',
    'hooks' => new SessionHooks(
        onSessionStart: function (SessionStartHookInput $input): ?SessionStartHookOutput {
            return new SessionStartHookOutput(
                additionalContext: "Project root: {$input->cwd}",
            );
        },

        onUserPromptSubmitted: function (UserPromptSubmittedHookInput $input): ?UserPromptSubmittedHookOutput {
            if (str_starts_with($input->prompt, '/fix')) {
                return new UserPromptSubmittedHookOutput(
                    modifiedPrompt: '現在のエラーを修正して、変更点を要約して。',
                );
            }

            return null;
        },

        onPreToolUse: function (PreToolUseHookInput $input): ?PreToolUseHookOutput {
            $blocked = ['bash', 'shell', 'delete_file'];

            if (in_array($input->toolName, $blocked, true)) {
                return new PreToolUseHookOutput(
                    permissionDecision: 'deny',
                    permissionDecisionReason: "{$input->toolName} はこの環境では許可されていません",
                );
            }

            return new PreToolUseHookOutput(permissionDecision: 'allow');
        },

        onPostToolUse: function (PostToolUseHookInput $input): ?PostToolUseHookOutput {
            if ($input->toolName === 'read_file') {
                return new PostToolUseHookOutput(
                    additionalContext: '必要なら関連ファイルも探索して比較してください。',
                );
            }

            return null;
        },

        onErrorOccurred: function (ErrorOccurredHookInput $input): ?ErrorOccurredHookOutput {
            if ($input->errorContext === 'model_call' && $input->recoverable) {
                return new ErrorOccurredHookOutput(
                    errorHandling: 'retry',
                    retryCount: 2,
                    userNotification: '一時的なモデルエラーのためリトライします。',
                );
            }

            return null;
        },

        onSessionEnd: function (SessionEndHookInput $input): ?SessionEndHookOutput {
            if ($input->reason !== 'complete') {
                return new SessionEndHookOutput(
                    sessionSummary: "Session ended with reason: {$input->reason}",
                );
            }

            return null;
        },
    ),
]);

Hooks disponibles

HookMomento en el que se disparaUso principal
onSessionStartInicio de sesión (new / resume / startup)Inyectar contexto inicial, sobreescribir configuración
onUserPromptSubmittedAl enviar un prompt del usuarioEnriquecer el prompt, expandir plantillas, filtrar entradas
onPreToolUseAntes de ejecutar una herramientaPermitir / denegar / requerir confirmación, modificar argumentos, silenciar salida
onPostToolUseDespués de ejecutar una herramientaModificar resultados, enmascarar información sensible, log de auditoría
onErrorOccurredAl producirse un error en la sesiónReintentar, notificar, clasificar el error
onSessionEndAl terminar la sesiónLimpieza, métricas, resumen final
Si devuelves null, se mantiene el comportamiento por defecto.

Casos de uso típicos

1) Permission control (control de ejecución)

  • Convierte las herramientas permitidas en una allow-list con onPreToolUse
  • Para operaciones destructivas, requiere aprobación humana con permissionDecision: 'ask'
  • Explicita el motivo del rechazo con permissionDecisionReason
  • Consulta los posibles toolName en el listado de Tools (por ejemplo view, glob, bash)

2) Auditing / compliance (auditoría)

  • Combina los hooks del ciclo de vida para recolectar eventos de auditoría
  • Persiste los datos recolectados por session ID

3) Prompt enrichment (enriquecer entradas)

  • En onSessionStart añade a additionalContext información del proyecto (lenguaje, framework, convenciones)
  • En onUserPromptSubmitted expande atajos como /fix o /test

4) Result filtering (formatear resultados)

  • En onPostToolUse enmascara API keys, tokens, contraseñas, etc.
  • Resume resultados demasiado largos y devuelve detalles solo cuando sea necesario

5) Error recovery (recuperación ante fallos)

  • En onErrorOccurred, haz retry solo si model_call y recoverable=true
  • Para errores no recuperables, notifica al usuario de forma concisa con userNotification

6) Session metrics (medición)

  • Registra la hora de inicio en onSessionStart
  • Incrementa contadores en onPreToolUse / onUserPromptSubmitted
  • Emite duración, número de herramientas y razón de finalización en onSessionEnd

Tipos de input / output de los hooks

Input común (BaseHookInput)

PropiedadTipoDescripción
timestampintMomento en que se disparó el hook (Unix ms)
cwdstringDirectorio de trabajo actual

PreToolUseHookInput

PropiedadTipoDescripción
toolNamestringNombre de la herramienta que se va a ejecutar
toolArgsmixedArgumentos previstos

PreToolUseHookOutput

PropiedadTipoDescripción
permissionDecision?stringallow / deny / ask
permissionDecisionReason?stringMotivo del rechazo o confirmación
modifiedArgsmixedArgumentos sobreescritos
additionalContext?stringContexto adicional
suppressOutput?boolSilencia la salida de la herramienta

PostToolUseHookInput

PropiedadTipoDescripción
toolNamestringNombre de la herramienta ejecutada
toolArgsmixedArgumentos utilizados
toolResultToolResultObject|arrayResultado de la herramienta

PostToolUseHookOutput

PropiedadTipoDescripción
modifiedResultToolResultObject|array|nullResultado modificado
additionalContext?stringContexto adicional
suppressOutput?boolSilencia la visualización del resultado

UserPromptSubmittedHookInput

PropiedadTipoDescripción
promptstringPrompt introducido por el usuario

UserPromptSubmittedHookOutput

PropiedadTipoDescripción
modifiedPrompt?stringPrompt modificado
additionalContext?stringContexto complementario
suppressOutput?boolSilencia la visualización de la respuesta

SessionStartHookInput

PropiedadTipoDescripción
sourcestringstartup / resume / new
initialPrompt?stringPrompt inicial

SessionStartHookOutput

PropiedadTipoDescripción
additionalContext?stringContexto inicial de la sesión
modifiedConfig?arraySobreescritura parcial de la configuración de la sesión

SessionEndHookInput

PropiedadTipoDescripción
reasonstringcomplete / error / abort / timeout / user_exit
finalMessage?stringMensaje final
error?stringError en el momento de la finalización

SessionEndHookOutput

PropiedadTipoDescripción
suppressOutput?boolSilencia la salida final
cleanupActions?arrayInformación de las acciones de limpieza realizadas
sessionSummary?stringResumen de la sesión

ErrorOccurredHookInput

PropiedadTipoDescripción
errorstringMensaje de error
errorContext?stringUno de model_call / tool_execution / system / user_input
recoverableboolSi es recuperable

ErrorOccurredHookOutput

PropiedadTipoDescripción
suppressOutput?boolSilencia la visualización del error
errorHandling?stringretry / skip / abort
retryCount?intNúmero de reintentos
userNotification?stringTexto de notificación al usuario

ToolResultObject

Objeto estándar del resultado de ejecución de una herramienta.
PropiedadTipoDescripción
textResultForLlm?stringResultado en texto que se pasa al LLM
resultType?stringsuccess / failure / rejected / denied
resultForAssistant?arrayDatos del resultado para el assistant

Buenas prácticas

  1. No ejecutes directamente en el hook procesos síncronos pesados. Hazlos asíncronos cuando sea necesario.
  2. Cuando no necesites cambiar nada, devuelve null y deja que actúe el comportamiento por defecto.
  3. Explicita permissionDecision siempre que puedas.
  4. No silencies en exceso los errores críticos; ten una vía de log/notificación.
  5. Gestiona el estado por sesión basándote en el session id y límpialo en onSessionEnd.
Consulta la información más reciente en el repositorio de GitHub.
Última modificación el 13 de julio de 2026