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

# Session hooks

> Haak met SessionHooks in op de lifecycle van een Copilot-session en implementeer uitvoeringscontrole, auditing en herstel-logica.

## Session hooks

Met `hooks` kun je op elk punt in de lifecycle van een Copilot-session eigen logica invoegen.\
Zo voeg je uitvoeringscontrole voor tools, auditlogs, promptverrijking en foutafhandeling toe zonder de kernimplementatie te wijzigen.

## De flow van 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
```

## Basisgebruik

```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: 'Vat de belangrijkste punten van de README samen');
    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: 'Los de huidige fouten op en vat de wijzigingen samen.',
                );
            }

            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} is niet toegestaan in deze omgeving",
                );
            }

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

        onPostToolUse: function (PostToolUseHookInput $input): ?PostToolUseHookOutput {
            if ($input->toolName === 'read_file') {
                return new PostToolUseHookOutput(
                    additionalContext: 'Verken indien nodig ook gerelateerde bestanden en vergelijk ze.',
                );
            }

            return null;
        },

        onErrorOccurred: function (ErrorOccurredHookInput $input): ?ErrorOccurredHookOutput {
            if ($input->errorContext === 'model_call' && $input->recoverable) {
                return new ErrorOccurredHookOutput(
                    errorHandling: 'retry',
                    retryCount: 2,
                    userNotification: 'Er wordt opnieuw geprobeerd vanwege een tijdelijke modelfout.',
                );
            }

            return null;
        },

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

            return null;
        },
    ),
]);
```

## Beschikbare hooks

| Hook                    | Wanneer afgevuurd                                   | Belangrijkste toepassingen                                                      |
| ----------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------- |
| `onSessionStart`        | Start van de session (`new` / `resume` / `startup`) | Initiële context injecteren, configuratie overschrijven                         |
| `onUserPromptSubmitted` | Bij het versturen van een gebruikersprompt          | Promptverrijking, templates uitvouwen, invoerfilters                            |
| `onPreToolUse`          | Vóór het uitvoeren van een tool                     | Toestaan/weigeren/bevestiging vragen, argumenten aanpassen, output onderdrukken |
| `onPostToolUse`         | Ná het uitvoeren van een tool                       | Resultaten aanpassen, gevoelige informatie maskeren, auditlogs                  |
| `onErrorOccurred`       | Bij een fout binnen de session                      | Retries, notificaties, foutclassificatie                                        |
| `onSessionEnd`          | Bij het einde van de session                        | Opruimen, metrics, eindsamenvatting                                             |

Als je `null` retourneert, gaat het standaardgedrag gewoon door.

## Typische use cases

### 1) Permission control (uitvoeringscontrole)

* Gebruik `onPreToolUse` om toegestane tools via een allow-list te beheren
* Laat destructieve operaties met `permissionDecision: 'ask'` door een mens goedkeuren
* Geef met `permissionDecisionReason` expliciet de reden van weigering op
* Bekijk de mogelijke waarden van `toolName` in het overzicht van [Tools](/nl/packages/laravel-copilot-sdk/tools) (bijv. `view`, `glob`, `bash`)

### 2) Auditing / compliance

* Combineer lifecycle-hooks om audit-events te verzamelen
* Sla de verzamelde data op per session-ID

### 3) Prompt enrichment (invoerverrijking)

* Voeg met `onSessionStart` projectinformatie (taal, framework, conventies) toe via `additionalContext`
* Vouw met `onUserPromptSubmitted` shortcuts uit (`/fix`, `/test`)

### 4) Result filtering (resultaten opschonen)

* Maskeer met `onPostToolUse` zaken als API keys, tokens en wachtwoorden
* Vat te lange resultaten samen en geef alleen op verzoek details terug

### 5) Error recovery (foutherstel)

* Voer met `onErrorOccurred` alleen een `retry` uit bij `model_call` met `recoverable=true`
* Informeer bij niet-herstelbare fouten de gebruiker beknopt via `userNotification`

### 6) Session metrics (meten)

* Leg met `onSessionStart` de starttijd vast
* Werk tellers bij in `onPreToolUse` / `onUserPromptSubmitted`
* Rapporteer met `onSessionEnd` de doorlooptijd, het aantal toolaanroepen en de eindreden

## Hook input-/output-types

### Gedeelde input (`BaseHookInput`)

| Property    | Type     | Beschrijving                                   |
| ----------- | -------- | ---------------------------------------------- |
| `timestamp` | `int`    | Tijdstip waarop de hook is afgevuurd (Unix ms) |
| `cwd`       | `string` | Huidige werkdirectory                          |

### `PreToolUseHookInput`

| Property   | Type     | Beschrijving                         |
| ---------- | -------- | ------------------------------------ |
| `toolName` | `string` | Naam van de uit te voeren tool       |
| `toolArgs` | `mixed`  | Argumenten van de uit te voeren tool |

### `PreToolUseHookOutput`

| Property                   | Type      | Beschrijving                    |
| -------------------------- | --------- | ------------------------------- |
| `permissionDecision`       | `?string` | `allow` / `deny` / `ask`        |
| `permissionDecisionReason` | `?string` | Reden bij weigering/bevestiging |
| `modifiedArgs`             | `mixed`   | Overschreven argumenten         |
| `additionalContext`        | `?string` | Aanvullende context             |
| `suppressOutput`           | `?bool`   | Onderdruk de tool-output        |

### `PostToolUseHookInput`

| Property     | Type                      | Beschrijving                 |
| ------------ | ------------------------- | ---------------------------- |
| `toolName`   | `string`                  | Naam van de uitgevoerde tool |
| `toolArgs`   | `mixed`                   | Argumenten bij uitvoering    |
| `toolResult` | `ToolResultObject\|array` | Toolresultaat                |

### `PostToolUseHookOutput`

| Property            | Type                            | Beschrijving                              |
| ------------------- | ------------------------------- | ----------------------------------------- |
| `modifiedResult`    | `ToolResultObject\|array\|null` | Aangepast resultaat                       |
| `additionalContext` | `?string`                       | Aanvullende context                       |
| `suppressOutput`    | `?bool`                         | Onderdruk het tonen van het toolresultaat |

### `UserPromptSubmittedHookInput`

| Property | Type     | Beschrijving                        |
| -------- | -------- | ----------------------------------- |
| `prompt` | `string` | Door de gebruiker ingevoerde prompt |

### `UserPromptSubmittedHookOutput`

| Property            | Type      | Beschrijving                       |
| ------------------- | --------- | ---------------------------------- |
| `modifiedPrompt`    | `?string` | Aangepaste prompt                  |
| `additionalContext` | `?string` | Aanvullende context                |
| `suppressOutput`    | `?bool`   | Onderdruk het tonen van de respons |

### `SessionStartHookInput`

| Property        | Type      | Beschrijving                 |
| --------------- | --------- | ---------------------------- |
| `source`        | `string`  | `startup` / `resume` / `new` |
| `initialPrompt` | `?string` | Initiële prompt              |

### `SessionStartHookOutput`

| Property            | Type      | Beschrijving                                           |
| ------------------- | --------- | ------------------------------------------------------ |
| `additionalContext` | `?string` | Initiële context van de session                        |
| `modifiedConfig`    | `?array`  | Gedeeltelijke overschrijving van de sessieconfiguratie |

### `SessionEndHookInput`

| Property       | Type      | Beschrijving                                             |
| -------------- | --------- | -------------------------------------------------------- |
| `reason`       | `string`  | `complete` / `error` / `abort` / `timeout` / `user_exit` |
| `finalMessage` | `?string` | Laatste bericht                                          |
| `error`        | `?string` | Fout bij het beëindigen                                  |

### `SessionEndHookOutput`

| Property         | Type      | Beschrijving                             |
| ---------------- | --------- | ---------------------------------------- |
| `suppressOutput` | `?bool`   | Onderdruk de laatste output              |
| `cleanupActions` | `?array`  | Informatie over uitgevoerde opruimacties |
| `sessionSummary` | `?string` | Samenvatting van de session              |

### `ErrorOccurredHookInput`

| Property       | Type      | Beschrijving                                                      |
| -------------- | --------- | ----------------------------------------------------------------- |
| `error`        | `string`  | Foutmelding                                                       |
| `errorContext` | `?string` | Een van `model_call` / `tool_execution` / `system` / `user_input` |
| `recoverable`  | `bool`    | Of herstel mogelijk is                                            |

### `ErrorOccurredHookOutput`

| Property           | Type      | Beschrijving                    |
| ------------------ | --------- | ------------------------------- |
| `suppressOutput`   | `?bool`   | Onderdruk het tonen van de fout |
| `errorHandling`    | `?string` | `retry` / `skip` / `abort`      |
| `retryCount`       | `?int`    | Aantal retries                  |
| `userNotification` | `?string` | Melding aan de gebruiker        |

## ToolResultObject

Het standaardobject voor toolresultaten.

| Property             | Type      | Beschrijving                                    |
| -------------------- | --------- | ----------------------------------------------- |
| `textResultForLlm`   | `?string` | Tekstresultaat dat aan de LLM wordt doorgegeven |
| `resultType`         | `?string` | `success` / `failure` / `rejected` / `denied`   |
| `resultForAssistant` | `?array`  | Resultaatdata voor de assistent                 |

## Best practices

1. Voer zware synchrone verwerking niet direct in een hook uit; maak deze zo nodig asynchroon.
2. Retourneer `null` als er niets hoeft te veranderen en laat het standaardgedrag zijn werk doen.
3. Maak `permissionDecision` waar mogelijk expliciet.
4. Onderdruk kritieke fouten niet te veel en zorg voor een log-/notificatiekanaal.
5. Beheer sessiestatus op basis van session-ID en ruim op in `onSessionEnd`.

<Info>
  Raadpleeg de [GitHub-repository](https://github.com/invokable/laravel-copilot-sdk) voor de meest actuele informatie.
</Info>


## Related topics

- [Session lifecycle events](/nl/packages/laravel-copilot-sdk/session-lifecycle-event.md)
- [SessionConfig](/nl/packages/laravel-copilot-sdk/session-config.md)
- [Plugin directories](/nl/packages/laravel-copilot-sdk/plugin-directories.md)
- [Aan de slag - GitHub Copilot SDK voor Laravel](/nl/packages/laravel-copilot-sdk/getting-started.md)
- [Broadcasting](/nl/broadcasting.md)
