> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Hooks de sesión

> Inserta lógica en el ciclo de vida de una sesión de Copilot mediante SessionHooks para implementar control de ejecución, auditoría y recuperación.

## 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

```mermaid theme={null}
flowchart LR
    A[Session starts] -->|onSessionStart| B[User prompt]
    B -->|onUserPromptSubmitted| C[Pre tool]
    C -->|onPreToolUse| D[Tool execution]
    D -->|onPostToolUse| E{Continue?}
    E -->|yes| C
    E -->|no| F[Session ends]
    F -->|onSessionEnd| G((Done))
    C -. error .-> H[onErrorOccurred]
    D -. error .-> H
```

## Uso básico

```php theme={null}
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

| Hook                    | Momento en el que se dispara                    | Uso principal                                                                      |
| ----------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------- |
| `onSessionStart`        | Inicio de sesión (`new` / `resume` / `startup`) | Inyectar contexto inicial, sobreescribir configuración                             |
| `onUserPromptSubmitted` | Al enviar un prompt del usuario                 | Enriquecer el prompt, expandir plantillas, filtrar entradas                        |
| `onPreToolUse`          | Antes de ejecutar una herramienta               | Permitir / denegar / requerir confirmación, modificar argumentos, silenciar salida |
| `onPostToolUse`         | Después de ejecutar una herramienta             | Modificar resultados, enmascarar información sensible, log de auditoría            |
| `onErrorOccurred`       | Al producirse un error en la sesión             | Reintentar, notificar, clasificar el error                                         |
| `onSessionEnd`          | Al terminar la sesión                           | Limpieza, 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](/es/packages/laravel-copilot-sdk/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`)

| Propiedad   | Tipo     | Descripción                                 |
| ----------- | -------- | ------------------------------------------- |
| `timestamp` | `int`    | Momento en que se disparó el hook (Unix ms) |
| `cwd`       | `string` | Directorio de trabajo actual                |

### `PreToolUseHookInput`

| Propiedad  | Tipo     | Descripción                                   |
| ---------- | -------- | --------------------------------------------- |
| `toolName` | `string` | Nombre de la herramienta que se va a ejecutar |
| `toolArgs` | `mixed`  | Argumentos previstos                          |

### `PreToolUseHookOutput`

| Propiedad                  | Tipo      | Descripción                          |
| -------------------------- | --------- | ------------------------------------ |
| `permissionDecision`       | `?string` | `allow` / `deny` / `ask`             |
| `permissionDecisionReason` | `?string` | Motivo del rechazo o confirmación    |
| `modifiedArgs`             | `mixed`   | Argumentos sobreescritos             |
| `additionalContext`        | `?string` | Contexto adicional                   |
| `suppressOutput`           | `?bool`   | Silencia la salida de la herramienta |

### `PostToolUseHookInput`

| Propiedad    | Tipo                      | Descripción                        |
| ------------ | ------------------------- | ---------------------------------- |
| `toolName`   | `string`                  | Nombre de la herramienta ejecutada |
| `toolArgs`   | `mixed`                   | Argumentos utilizados              |
| `toolResult` | `ToolResultObject\|array` | Resultado de la herramienta        |

### `PostToolUseHookOutput`

| Propiedad           | Tipo                            | Descripción                             |
| ------------------- | ------------------------------- | --------------------------------------- |
| `modifiedResult`    | `ToolResultObject\|array\|null` | Resultado modificado                    |
| `additionalContext` | `?string`                       | Contexto adicional                      |
| `suppressOutput`    | `?bool`                         | Silencia la visualización del resultado |

### `UserPromptSubmittedHookInput`

| Propiedad | Tipo     | Descripción                       |
| --------- | -------- | --------------------------------- |
| `prompt`  | `string` | Prompt introducido por el usuario |

### `UserPromptSubmittedHookOutput`

| Propiedad           | Tipo      | Descripción                               |
| ------------------- | --------- | ----------------------------------------- |
| `modifiedPrompt`    | `?string` | Prompt modificado                         |
| `additionalContext` | `?string` | Contexto complementario                   |
| `suppressOutput`    | `?bool`   | Silencia la visualización de la respuesta |

### `SessionStartHookInput`

| Propiedad       | Tipo      | Descripción                  |
| --------------- | --------- | ---------------------------- |
| `source`        | `string`  | `startup` / `resume` / `new` |
| `initialPrompt` | `?string` | Prompt inicial               |

### `SessionStartHookOutput`

| Propiedad           | Tipo      | Descripción                                             |
| ------------------- | --------- | ------------------------------------------------------- |
| `additionalContext` | `?string` | Contexto inicial de la sesión                           |
| `modifiedConfig`    | `?array`  | Sobreescritura parcial de la configuración de la sesión |

### `SessionEndHookInput`

| Propiedad      | Tipo      | Descripción                                              |
| -------------- | --------- | -------------------------------------------------------- |
| `reason`       | `string`  | `complete` / `error` / `abort` / `timeout` / `user_exit` |
| `finalMessage` | `?string` | Mensaje final                                            |
| `error`        | `?string` | Error en el momento de la finalización                   |

### `SessionEndHookOutput`

| Propiedad        | Tipo      | Descripción                                        |
| ---------------- | --------- | -------------------------------------------------- |
| `suppressOutput` | `?bool`   | Silencia la salida final                           |
| `cleanupActions` | `?array`  | Información de las acciones de limpieza realizadas |
| `sessionSummary` | `?string` | Resumen de la sesión                               |

### `ErrorOccurredHookInput`

| Propiedad      | Tipo      | Descripción                                                      |
| -------------- | --------- | ---------------------------------------------------------------- |
| `error`        | `string`  | Mensaje de error                                                 |
| `errorContext` | `?string` | Uno de `model_call` / `tool_execution` / `system` / `user_input` |
| `recoverable`  | `bool`    | Si es recuperable                                                |

### `ErrorOccurredHookOutput`

| Propiedad          | Tipo      | Descripción                         |
| ------------------ | --------- | ----------------------------------- |
| `suppressOutput`   | `?bool`   | Silencia la visualización del error |
| `errorHandling`    | `?string` | `retry` / `skip` / `abort`          |
| `retryCount`       | `?int`    | Número de reintentos                |
| `userNotification` | `?string` | Texto de notificación al usuario    |

## ToolResultObject

Objeto estándar del resultado de ejecución de una herramienta.

| Propiedad            | Tipo      | Descripción                                   |
| -------------------- | --------- | --------------------------------------------- |
| `textResultForLlm`   | `?string` | Resultado en texto que se pasa al LLM         |
| `resultType`         | `?string` | `success` / `failure` / `rejected` / `denied` |
| `resultForAssistant` | `?array`  | Datos 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`.

<Info>
  Consulta la información más reciente en el [repositorio de GitHub](https://github.com/invokable/laravel-copilot-sdk).
</Info>


## Related topics

- [Eventos del ciclo de vida de sesión](/es/packages/laravel-copilot-sdk/session-lifecycle-event.md)
- [Contexto de sesión y filtrado](/es/packages/laravel-copilot-sdk/session-context.md)
- [Guía de actualización de Laravel 12 a 13](/es/blog/upgrade-12-to-13.md)
- [Token de GitHub](/es/packages/laravel-copilot-sdk/github-token.md)
- [Introducción a la autenticación](/es/authentication.md)
