Vai al contenuto principale

Hook di sessione

Con hooks puoi inserire logica in ciascuna fase del ciclo di vita di una sessione Copilot. Puoi aggiungere controllo dell’esecuzione degli strumenti, log di audit, arricchimento del prompt, gestione degli errori e altro senza modificare l’implementazione core.

Flusso degli hook

Uso di base

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: 'Riassumi i punti chiave del 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: 'Correggi l\'errore corrente e riassumi le modifiche.',
                );
            }

            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} non è consentito in questo ambiente",
                );
            }

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

        onPostToolUse: function (PostToolUseHookInput $input): ?PostToolUseHookOutput {
            if ($input->toolName === 'read_file') {
                return new PostToolUseHookOutput(
                    additionalContext: 'Se necessario, esplora anche i file correlati e confrontali.',
                );
            }

            return null;
        },

        onErrorOccurred: function (ErrorOccurredHookInput $input): ?ErrorOccurredHookOutput {
            if ($input->errorContext === 'model_call' && $input->recoverable) {
                return new ErrorOccurredHookOutput(
                    errorHandling: 'retry',
                    retryCount: 2,
                    userNotification: 'Errore temporaneo del modello, si tenta di nuovo.',
                );
            }

            return null;
        },

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

            return null;
        },
    ),
]);

Hook disponibili

HookMomento di attivazioneUso principale
onSessionStartAvvio sessione (new / resume / startup)Iniezione di contesto iniziale, override di configurazione
onUserPromptSubmittedAll’invio di un prompt utenteArricchimento prompt, espansione template, filtro input
onPreToolUsePrima dell’esecuzione dello strumentoConsenti/nega/chiedi, modifica argomenti, sopprimi output
onPostToolUseDopo l’esecuzione dello strumentoModifica risultato, mascheramento dati sensibili, audit log
onErrorOccurredAll’occorrenza di un errore in sessioneRetry, notifiche, classificazione degli errori
onSessionEndAlla chiusura della sessioneCleanup, metriche, riepilogo finale
Restituendo null prosegue il comportamento predefinito.

Casi d’uso tipici

1) Permission control (controllo esecuzione)

  • Usa onPreToolUse per applicare una allow-list di strumenti
  • Le operazioni distruttive richiedono approvazione umana con permissionDecision: 'ask'
  • Motiva il rifiuto con permissionDecisionReason
  • Consulta l’elenco di Tools per i possibili toolName (es. view, glob, bash)

2) Auditing / compliance

  • Combina gli hook del ciclo di vita per raccogliere eventi di audit
  • Persisti i dati raccolti per singolo ID sessione

3) Prompt enrichment (arricchimento input)

  • In onSessionStart aggiungi le informazioni del progetto (linguaggio, framework, convenzioni) in additionalContext
  • In onUserPromptSubmitted espandi shortcut (/fix, /test)

4) Result filtering (formattazione dei risultati)

  • In onPostToolUse maschera API key / token / password ecc.
  • Sintetizza i risultati troppo lunghi e restituisci i dettagli solo se necessario

5) Error recovery (ripristino)

  • In onErrorOccurred esegui retry solo quando model_call e recoverable=true
  • Per errori non recuperabili notifica in modo conciso l’utente tramite userNotification

6) Session metrics (misurazione)

  • In onSessionStart registra l’orario di inizio
  • In onPreToolUse / onUserPromptSubmitted aggiorna i contatori
  • In onSessionEnd emetti durata, numero di strumenti e motivo di terminazione

Tipi di input / output degli hook

Input comune (BaseHookInput)

ProprietàTipoDescrizione
timestampintTimestamp di attivazione (Unix ms)
cwdstringDirectory di lavoro corrente

PreToolUseHookInput

ProprietàTipoDescrizione
toolNamestringNome dello strumento che sta per essere eseguito
toolArgsmixedArgomenti previsti per l’esecuzione

PreToolUseHookOutput

ProprietàTipoDescrizione
permissionDecision?stringallow / deny / ask
permissionDecisionReason?stringMotivo in caso di rifiuto/conferma
modifiedArgsmixedArgomenti dopo l’override
additionalContext?stringContesto aggiuntivo
suppressOutput?boolSopprime l’output dello strumento

PostToolUseHookInput

ProprietàTipoDescrizione
toolNamestringNome dello strumento eseguito
toolArgsmixedArgomenti dell’esecuzione
toolResultToolResultObject|arrayRisultato dello strumento

PostToolUseHookOutput

ProprietàTipoDescrizione
modifiedResultToolResultObject|array|nullRisultato dopo la modifica
additionalContext?stringContesto aggiuntivo
suppressOutput?boolSopprime la visualizzazione del risultato

UserPromptSubmittedHookInput

ProprietàTipoDescrizione
promptstringPrompt inserito dall’utente

UserPromptSubmittedHookOutput

ProprietàTipoDescrizione
modifiedPrompt?stringPrompt modificato
additionalContext?stringContesto integrativo
suppressOutput?boolSopprime la visualizzazione della risposta

SessionStartHookInput

ProprietàTipoDescrizione
sourcestringstartup / resume / new
initialPrompt?stringPrompt iniziale

SessionStartHookOutput

ProprietàTipoDescrizione
additionalContext?stringContesto iniziale della sessione
modifiedConfig?arrayOverride parziale della configurazione

SessionEndHookInput

ProprietàTipoDescrizione
reasonstringcomplete / error / abort / timeout / user_exit
finalMessage?stringMessaggio finale
error?stringErrore al termine

SessionEndHookOutput

ProprietàTipoDescrizione
suppressOutput?boolSopprime l’output finale
cleanupActions?arrayInformazioni sulle azioni di cleanup eseguite
sessionSummary?stringRiepilogo della sessione

ErrorOccurredHookInput

ProprietàTipoDescrizione
errorstringMessaggio d’errore
errorContext?stringUno tra model_call / tool_execution / system / user_input
recoverableboolSe è recuperabile

ErrorOccurredHookOutput

ProprietàTipoDescrizione
suppressOutput?boolSopprime la visualizzazione dell’errore
errorHandling?stringretry / skip / abort
retryCount?intNumero di retry
userNotification?stringTesto di notifica all’utente

ToolResultObject

Oggetto standard per il risultato di uno strumento.
ProprietàTipoDescrizione
textResultForLlm?stringRisultato testuale da passare all’LLM
resultType?stringsuccess / failure / rejected / denied
resultForAssistant?arrayDati di risultato per l’assistente

Best practice

  1. Non eseguire troppi processi sincroni pesanti direttamente negli hook. Se necessario, rendili asincroni.
  2. Quando non sono necessarie modifiche, restituisci null e lascia il comportamento predefinito.
  3. Rendi esplicito permissionDecision quando possibile.
  4. Non sopprimere eccessivamente gli errori critici: prevedi percorsi di log/notifica.
  5. Gestisci lo stato per sessione basandoti sull’ID e ripulisci in onSessionEnd.
Per le informazioni più recenti fai riferimento al repository GitHub.
Ultima modifica il 13 luglio 2026