Zum Hauptinhalt springen

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

Grundlegende Verwendung

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

HookAuslösezeitpunktHauptanwendung
onSessionStartSession-Start (new / resume / startup)Initialen Kontext einspeisen, Konfiguration überschreiben
onUserPromptSubmittedBeim Senden eines User-PromptsPrompt anreichern, Templates expandieren, Eingabefilter
onPreToolUseVor der Tool-AusführungZulassen/Verweigern/Nachfragen, Argumente ändern, Ausgabe unterdrücken
onPostToolUseNach der Tool-AusführungErgebnisse verändern, sensible Informationen maskieren, Audit-Log
onErrorOccurredBei Fehlern in der SessionRetry, Benachrichtigungen, Fehlerklassifizierung
onSessionEndBei Session-EndeCleanup, 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 (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)

EigenschaftTypBeschreibung
timestampintZeitpunkt der Hook-Auslösung (Unix ms)
cwdstringAktuelles Arbeitsverzeichnis

PreToolUseHookInput

EigenschaftTypBeschreibung
toolNamestringName des einzusetzenden Tools
toolArgsmixedÜbergebene Argumente

PreToolUseHookOutput

EigenschaftTypBeschreibung
permissionDecision?stringallow / deny / ask
permissionDecisionReason?stringGrund für Ablehnung/Rückfrage
modifiedArgsmixedÜberschriebene Argumente
additionalContext?stringZusätzlicher Kontext
suppressOutput?boolTool-Ausgabe unterdrücken

PostToolUseHookInput

EigenschaftTypBeschreibung
toolNamestringName des ausgeführten Tools
toolArgsmixedVerwendete Argumente
toolResultToolResultObject|arrayErgebnis des Tools

PostToolUseHookOutput

EigenschaftTypBeschreibung
modifiedResultToolResultObject|array|nullGeändertes Ergebnis
additionalContext?stringZusätzlicher Kontext
suppressOutput?boolErgebnisausgabe unterdrücken

UserPromptSubmittedHookInput

EigenschaftTypBeschreibung
promptstringVom Nutzer eingegebener Prompt

UserPromptSubmittedHookOutput

EigenschaftTypBeschreibung
modifiedPrompt?stringModifizierter Prompt
additionalContext?stringErgänzender Kontext
suppressOutput?boolAntwortdarstellung unterdrücken

SessionStartHookInput

EigenschaftTypBeschreibung
sourcestringstartup / resume / new
initialPrompt?stringInitialer Prompt

SessionStartHookOutput

EigenschaftTypBeschreibung
additionalContext?stringInitialer Session-Kontext
modifiedConfig?arrayTeilweise Überschreibung der Session-Konfiguration

SessionEndHookInput

EigenschaftTypBeschreibung
reasonstringcomplete / error / abort / timeout / user_exit
finalMessage?stringLetzte Nachricht
error?stringFehler zum Endzeitpunkt

SessionEndHookOutput

EigenschaftTypBeschreibung
suppressOutput?boolFinale Ausgabe unterdrücken
cleanupActions?arrayInformationen zu durchgeführten Cleanup-Aktionen
sessionSummary?stringZusammenfassung der Session

ErrorOccurredHookInput

EigenschaftTypBeschreibung
errorstringFehlermeldung
errorContext?stringEiner von model_call / tool_execution / system / user_input
recoverableboolOb wiederherstellbar

ErrorOccurredHookOutput

EigenschaftTypBeschreibung
suppressOutput?boolFehleranzeige unterdrücken
errorHandling?stringretry / skip / abort
retryCount?intAnzahl der Wiederholungen
userNotification?stringMeldungstext an den Nutzer

ToolResultObject

Standard-Objekt für Tool-Ausführungsergebnisse.
EigenschaftTypBeschreibung
textResultForLlm?stringAn das LLM übergebenes Textergebnis
resultType?stringsuccess / failure / rejected / denied
resultForAssistant?arrayErgebnisdaten 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.
Aktuelle Informationen finden Sie im GitHub-Repository.
Zuletzt geändert am 13. Juli 2026