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

> Klinken Sie sich mit SessionHooks in den Lebenszyklus einer Copilot-Session ein und implementieren Sie Ausführungssteuerung, Auditing und Recovery-Logik.

## Session-Hooks

Mit `hooks` können Sie sich in die einzelnen Lebenszyklusphasen einer Copilot-Session einklinken.
Tool-Ausführungssteuerung, Audit-Logs, Prompt-Anreicherung, Fehlerbehandlung usw. lassen sich hinzufügen, ohne die Kernimplementierung zu ändern.

## Ablauf der 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
```

## Grundlegende Verwendung

```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;
        },
    ),
]);
```

## Verfügbare Hooks

| Hook                    | Auslösezeitpunkt                             | Hauptanwendung                                                         |
| ----------------------- | -------------------------------------------- | ---------------------------------------------------------------------- |
| `onSessionStart`        | Session-Start (`new` / `resume` / `startup`) | Initialen Kontext einspeisen, Konfiguration überschreiben              |
| `onUserPromptSubmitted` | Beim Senden eines User-Prompts               | Prompt anreichern, Templates expandieren, Eingabefilter                |
| `onPreToolUse`          | Vor der Tool-Ausführung                      | Zulassen/Verweigern/Nachfragen, Argumente ändern, Ausgabe unterdrücken |
| `onPostToolUse`         | Nach der Tool-Ausführung                     | Ergebnisse verändern, sensible Informationen maskieren, Audit-Log      |
| `onErrorOccurred`       | Bei Fehlern in der Session                   | Retry, Benachrichtigungen, Fehlerklassifizierung                       |
| `onSessionEnd`          | Bei Session-Ende                             | Cleanup, Metriken, Abschluss-Zusammenfassung                           |

Wird `null` zurückgegeben, läuft das Standardverhalten weiter.

## Typische Anwendungsfälle

### 1) Berechtigungssteuerung (Ausführungskontrolle)

* Zulassene Tools per Allow-List über `onPreToolUse`
* Destruktive Operationen mit `permissionDecision: 'ask'` menschlich freigeben lassen
* Über `permissionDecisionReason` den Ablehnungsgrund explizit machen
* Kandidaten für `toolName` finden Sie in der Liste unter [Tools](/de/packages/laravel-copilot-sdk/tools) (z. B. `view`, `glob`, `bash`)

### 2) Auditing / Compliance

* Audit-Ereignisse durch Kombination der Lebenszyklus-Hooks sammeln
* Gesammelte Daten pro Session-ID persistieren

### 3) Prompt-Anreicherung

* In `onSessionStart` Projektinformationen (Sprache, Framework, Konventionen) via `additionalContext` ergänzen
* In `onUserPromptSubmitted` Shortcuts (`/fix`, `/test`) expandieren

### 4) Ergebnisfilterung

* In `onPostToolUse` API-Keys / Tokens / Passwörter maskieren
* Zu lange Ergebnisse zusammenfassen und Details nur bei Bedarf ausgeben

### 5) Fehler-Recovery

* In `onErrorOccurred` nur bei `model_call` und `recoverable=true` einen `retry` ausführen
* Nicht wiederherstellbare Fälle über `userNotification` knapp an den Nutzer melden

### 6) Session-Metriken

* In `onSessionStart` die Startzeit erfassen
* In `onPreToolUse` / `onUserPromptSubmitted` Zähler aktualisieren
* In `onSessionEnd` Dauer, Anzahl der Tool-Aufrufe und Abschlussgrund ausgeben

## Hook-Input-/Output-Typen

### Gemeinsame Eingabe (`BaseHookInput`)

| Eigenschaft | Typ      | Beschreibung                           |
| ----------- | -------- | -------------------------------------- |
| `timestamp` | `int`    | Zeitpunkt der Hook-Auslösung (Unix ms) |
| `cwd`       | `string` | Aktuelles Arbeitsverzeichnis           |

### `PreToolUseHookInput`

| Eigenschaft | Typ      | Beschreibung                  |
| ----------- | -------- | ----------------------------- |
| `toolName`  | `string` | Name des einzusetzenden Tools |
| `toolArgs`  | `mixed`  | Übergebene Argumente          |

### `PreToolUseHookOutput`

| Eigenschaft                | Typ       | Beschreibung                  |
| -------------------------- | --------- | ----------------------------- |
| `permissionDecision`       | `?string` | `allow` / `deny` / `ask`      |
| `permissionDecisionReason` | `?string` | Grund für Ablehnung/Rückfrage |
| `modifiedArgs`             | `mixed`   | Überschriebene Argumente      |
| `additionalContext`        | `?string` | Zusätzlicher Kontext          |
| `suppressOutput`           | `?bool`   | Tool-Ausgabe unterdrücken     |

### `PostToolUseHookInput`

| Eigenschaft  | Typ                       | Beschreibung                |
| ------------ | ------------------------- | --------------------------- |
| `toolName`   | `string`                  | Name des ausgeführten Tools |
| `toolArgs`   | `mixed`                   | Verwendete Argumente        |
| `toolResult` | `ToolResultObject\|array` | Ergebnis des Tools          |

### `PostToolUseHookOutput`

| Eigenschaft         | Typ                             | Beschreibung                 |
| ------------------- | ------------------------------- | ---------------------------- |
| `modifiedResult`    | `ToolResultObject\|array\|null` | Geändertes Ergebnis          |
| `additionalContext` | `?string`                       | Zusätzlicher Kontext         |
| `suppressOutput`    | `?bool`                         | Ergebnisausgabe unterdrücken |

### `UserPromptSubmittedHookInput`

| Eigenschaft | Typ      | Beschreibung                   |
| ----------- | -------- | ------------------------------ |
| `prompt`    | `string` | Vom Nutzer eingegebener Prompt |

### `UserPromptSubmittedHookOutput`

| Eigenschaft         | Typ       | Beschreibung                    |
| ------------------- | --------- | ------------------------------- |
| `modifiedPrompt`    | `?string` | Modifizierter Prompt            |
| `additionalContext` | `?string` | Ergänzender Kontext             |
| `suppressOutput`    | `?bool`   | Antwortdarstellung unterdrücken |

### `SessionStartHookInput`

| Eigenschaft     | Typ       | Beschreibung                 |
| --------------- | --------- | ---------------------------- |
| `source`        | `string`  | `startup` / `resume` / `new` |
| `initialPrompt` | `?string` | Initialer Prompt             |

### `SessionStartHookOutput`

| Eigenschaft         | Typ       | Beschreibung                                       |
| ------------------- | --------- | -------------------------------------------------- |
| `additionalContext` | `?string` | Initialer Session-Kontext                          |
| `modifiedConfig`    | `?array`  | Teilweise Überschreibung der Session-Konfiguration |

### `SessionEndHookInput`

| Eigenschaft    | Typ       | Beschreibung                                             |
| -------------- | --------- | -------------------------------------------------------- |
| `reason`       | `string`  | `complete` / `error` / `abort` / `timeout` / `user_exit` |
| `finalMessage` | `?string` | Letzte Nachricht                                         |
| `error`        | `?string` | Fehler zum Endzeitpunkt                                  |

### `SessionEndHookOutput`

| Eigenschaft      | Typ       | Beschreibung                                     |
| ---------------- | --------- | ------------------------------------------------ |
| `suppressOutput` | `?bool`   | Finale Ausgabe unterdrücken                      |
| `cleanupActions` | `?array`  | Informationen zu durchgeführten Cleanup-Aktionen |
| `sessionSummary` | `?string` | Zusammenfassung der Session                      |

### `ErrorOccurredHookInput`

| Eigenschaft    | Typ       | Beschreibung                                                        |
| -------------- | --------- | ------------------------------------------------------------------- |
| `error`        | `string`  | Fehlermeldung                                                       |
| `errorContext` | `?string` | Einer von `model_call` / `tool_execution` / `system` / `user_input` |
| `recoverable`  | `bool`    | Ob wiederherstellbar                                                |

### `ErrorOccurredHookOutput`

| Eigenschaft        | Typ       | Beschreibung               |
| ------------------ | --------- | -------------------------- |
| `suppressOutput`   | `?bool`   | Fehleranzeige unterdrücken |
| `errorHandling`    | `?string` | `retry` / `skip` / `abort` |
| `retryCount`       | `?int`    | Anzahl der Wiederholungen  |
| `userNotification` | `?string` | Meldungstext an den Nutzer |

## ToolResultObject

Standard-Objekt für Tool-Ausführungsergebnisse.

| Eigenschaft          | Typ       | Beschreibung                                  |
| -------------------- | --------- | --------------------------------------------- |
| `textResultForLlm`   | `?string` | An das LLM übergebenes Textergebnis           |
| `resultType`         | `?string` | `success` / `failure` / `rejected` / `denied` |
| `resultForAssistant` | `?array`  | Ergebnisdaten für den Assistenten             |

## Best Practices

1. Führen Sie schwere synchrone Verarbeitung nicht direkt im Hook aus. Bei Bedarf asynchron auslagern.
2. Wenn keine Änderung nötig ist, geben Sie `null` zurück und überlassen den Standardablauf.
3. Setzen Sie `permissionDecision` möglichst explizit.
4. Unterdrücken Sie kritische Fehler nicht zu stark – halten Sie Log-/Notification-Pfade offen.
5. Verwalten Sie Session-bezogenen Zustand auf Basis der Session-ID und räumen Sie ihn in `onSessionEnd` auf.

<Info>
  Aktuelle Informationen finden Sie im [GitHub-Repository](https://github.com/invokable/laravel-copilot-sdk).
</Info>


## Related topics

- [Session-Lebenszyklus-Ereignisse](/de/packages/laravel-copilot-sdk/session-lifecycle-event.md)
- [Agent-Loop](/de/packages/laravel-copilot-sdk/agent-loop.md)
- [SessionConfig](/de/packages/laravel-copilot-sdk/session-config.md)
- [Plugin Directories](/de/packages/laravel-copilot-sdk/plugin-directories.md)
- [Session](/de/session.md)
