Hooks

Unter diesem Thema wird beschrieben, wie Sie Hooks verwenden, um benutzerdefinierten Code an Schlüsselpunkten im Lebenszyklus des Agenten auszuführen. Mit Hooks können Sie Tool-Aufrufe abfangen, das Verhalten von Agenten überprüfen, Richtlinien durchsetzen, Kontext einfügen und den Ausführungsablauf kontrollieren.

Funktionsweise von Hooks

Hooks folgen einem vierstufigen Prozess: Es wird ein Ereignis ausgelöst, das SDK prüft, ob ein Matcher zutrifft, ruft Ihren Callback auf, und Ihr Callback gibt eine Entscheidung zurück, die steuert, was als Nächstes passiert.

  1. Der Agent löst ein Ereignis aus (z. B. wenn er dabei ist, ein Tool aufzurufen).

  2. Das SDK überprüft jeden Hook-Matcher, der für diesen Ereignistyp registriert ist.

  3. Wenn ein Matcher übereinstimmt (oder kein Matcher-Muster hat, d. h. er stimmt mit allem überein), ruft das SDK die zugehörigen Callback-Funktionen auf.

  4. Jeder Callback gibt ein Ausgabeobjekt zurück, das die Operation zulassen, blockieren oder ändern kann.

Hook-Ereignisse

Die folgenden Ereignisse sind verfügbar:

Ereignis

Wenn es ausgelöst wird

PreToolUse

Bevor ein Tool ausgeführt wird. Kann das Tool blockieren oder seine Eingabe ändern.

PostToolUse

Nachdem ein Tool erfolgreich ausgeführt wurde. Kann zusätzlichen Kontext einfügen.

PostToolUseFailure

Nachdem die Ausführung eines Tools fehlgeschlagen ist.

UserPromptSubmit

Wenn der Benutzer eine Aufforderung sendet. Kann zusätzlichen Kontext einfügen.

Stop

Wenn der Agent kurz davor ist, anzuhalten. Kann Kontext einfügen oder die Sitzung anhalten.

SubagentStart

Wenn ein Subagent startet.

SubagentStop

Wenn ein Subagent kurz davor ist, anzuhalten.

PreCompact

Bevor die Konversation komprimiert wird (zusammengefasst, um in das Kontextfenster zu passen).

Notification

Wenn der Agent eine Benachrichtigung ausgibt.

PermissionRequest

Wenn eine Tool-Berechtigungsprüfung stattfindet.

Konfigurieren von -Hooks

Führen Sie die Hooks durch der hooks-Option beim Erstellen einer Sitzung. Jedes Hook-Ereignis wird einer Liste von Matchern zugeordnet und jeder Matcher enthält eine Liste von Callback-Funktionen.

import { createCortexCodeSession } from "cortex-code-agent-sdk";

const session = await createCortexCodeSession({
  cwd: process.cwd(),
  hooks: {
    PreToolUse: [
      {
        matcher: "Bash",
        hooks: [
          async (input, toolUseId, context) => {
            console.log("Bash command:", input.tool_input);
            return {};
          },
        ],
      },
    ],
  },
});

Matcher

Jeder Hook-Matcher hat drei Felder:

Feld

Typ

Beschreibung

matcher

string (optional)

Ein Regex-Muster, das von Ereignissen verwendet wird, die Abgleiche unterstützen. PreToolUse, PostToolUse und``PermissionRequest`` gleichen mit dem Toolnamen ab. Notification gleicht mit dem Benachrichtigungstyp ab. PreCompact gleicht mit dem Triggerwert ab ("auto" oder``“manual“`` ). Wenn weggelassen, wird der Hook für alle Werte dieses Ereignisses ausgelöst.

hooks

Liste der Callbacks

Eine oder mehrere Callback-Funktionen, die ausgeführt werden, wenn der Matcher übereinstimmt.

timeout

number (optional)

Maximale Zeit in Sekunden für alle Callbacks in diesem Matcher. Der Standardwert ist 60.

Das matcher-Feld akzeptiert jedes gültige Regex-Muster. Beispiel:

  • "Bash" – gleicht nur mit dem Bash-Tool ab

  • "Write|Edit" – gleicht mit „Schreiben“ oder „Bearbeiten“ ab

  • ".*" – gleicht mit allen Tools ab (wie das Weglassen des Matchers)

Callback-Eingaben

Jeder Callback erhält drei Argumente:

Argument

Beschreibung

input

Ein Objekt, das ereignisspezifische Daten enthält. Alle Ereignisse enthalten session_id,``transcript_path``, cwd, permission_mode und hook_event_name. Zu den Tool-Ereignissen gehört auch tool_name, tool_input und tool_use_id.

toolUseId / tool_use_id

Die Toolverwendungs-ID (für Tool-bezogene Ereignisse) oder null.

context

Ein Kontextobjekt. Reserviert für zukünftige Verwendung (z. B. Abbruchsignale).

Die Eingabefelder variieren je nach Ereignis:

Ereignis

Zusätzliche Eingabefelder

PreToolUse

tool_name, tool_input, tool_use_id

PostToolUse

tool_name, tool_input, tool_response, tool_use_id

PostToolUseFailure

tool_name, tool_input, tool_use_id, error, optional is_interrupt

UserPromptSubmit

prompt

Stop

stop_hook_active

SubagentStart

agent_id, agent_type

SubagentStop

stop_hook_active, agent_id, agent_transcript_path, agent_type

PreCompact

trigger ("manual" oder "auto"), custom_instructions

Notification

message, notification_type, optional title

PermissionRequest

tool_name, tool_input, optional permission_suggestions

Tool-Lebenszyklus-Hooks und PermissionRequest können optional auch agent_id und``agent_type``-Felder enthalten, wenn sie von einem Subagenten ausgelöst werden.

Callback-Ausgaben

Callbacks geben ein Ausgabeobjekt zurück, das die Ausführung steuert. Die folgenden Felder sind verfügbar:

Feld

Typ

Beschreibung

continue / continue_

boolean

Gibt an, ob die Verarbeitung fortgesetzt werden soll. Setzen Sie auf false, um die weitere Verarbeitung für die aktuelle Hook-Seite oder Runde zu stoppen. Standard: true.

stopReason

string

Meldung, die angezeigt wird, wenn continue false ist.

decision

"block"

Setzen Sie auf "block", um die aktuelle Operation zu blockieren.

reason

string

Feedback-Meldung an den Agenten über die Entscheidung.

systemMessage

string

Warnmeldung, die dem Benutzer angezeigt wird.

hookSpecificOutput

object

Ereignisspezifische Steuerelemente (siehe unten).

Bemerkung

Das Python-SDK verwendet continue_ (mit einem nachstehenden Unterstrich) anstelle von continue, um den Python-Schlüsselwortkonflikt zu vermeiden. Das SDK wandelt dies automatisch in continue bei der Kommunikation mit CLI um.

Hook-spezifische Ausgaben

Das hookSpecificOutput-Feld akzeptiert ereignisspezifische Steuerelemente:

PreToolUse

Feld

Beschreibung

permissionDecision

"allow", "deny" oder "ask". Steuert, ob das Tool ausführen kann.

permissionDecisionReason

Grund für die Entscheidung über die Berechtigung.

updatedInput

Geänderte Tool-Eingabe, anstelle der ursprünglichen zu verwenden.

PostToolUse

Feld

Beschreibung

additionalContext

Zusätzlicher Kontext, der nach der Ausführung des Tools in die Konversation eingefügt wird.

UserPromptSubmit

Feld

Beschreibung

additionalContext

Zusätzlicher Kontext, der in die Konversation eingefügt wird.

PermissionRequest

Feld

Beschreibung

decision.behavior

"allow" oder "deny". Steuert das Ergebnis der Berechtigung.

decision.message

Meldung, die angezeigt wird, wenn die Berechtigungsanfrage abgelehnt wird.

Beispiele

Gefährliche Tools blockieren

Verhindern, dass der Agent bestimmte Bash-Befehle ausführt:

import { createCortexCodeSession } from "cortex-code-agent-sdk";

const session = await createCortexCodeSession({
  cwd: process.cwd(),
  hooks: {
    PreToolUse: [
      {
        matcher: "Bash",
        hooks: [
          async (input) => {
            const command = (input.tool_input as any)?.command ?? "";
            if (command.includes("rm -rf") || command.includes("DROP TABLE")) {
              return {
                decision: "block",
                reason: "Destructive commands are not allowed",
              };
            }
            return {};
          },
        ],
      },
    ],
  },
});

Anfragen nach Nur-Lesen-Berechtigung automatisch zulassen

Berechtigungsanfragen für Tools zulassen, die nur Daten lesen:

hooks: {
  PermissionRequest: [
    {
      matcher: "Read|Glob|Grep",
      hooks: [
        async (input) => {
          return {
            hookSpecificOutput: {
              hookEventName: "PermissionRequest",
              decision: { behavior: "allow" },
            },
          };
        },
      ],
    },
  ],
}

Tool-Eingabe ändern

Fügen Sie allen Bash-Befehlen ein Timeout hinzu, bevor sie ausgeführt werden:

hooks: {
  PreToolUse: [
    {
      matcher: "Bash",
      hooks: [
        async (input) => {
          const originalCommand = (input.tool_input as any)?.command ?? "";
          return {
            hookSpecificOutput: {
              hookEventName: "PreToolUse",
              updatedInput: { command: `timeout 30 ${originalCommand}` },
            },
          };
        },
      ],
    },
  ],
}

Audit-Protokollieren

Protokollieren Sie alle Tool-Aufrufe zu Auditing-Zwecken, ohne die Ausführung zu beeinträchtigen:

import { createCortexCodeSession } from "cortex-code-agent-sdk";
import { appendFileSync } from "node:fs";

const session = await createCortexCodeSession({
  cwd: process.cwd(),
  hooks: {
    PostToolUse: [
      {
        hooks: [
          async (input) => {
            const entry = {
              timestamp: new Date().toISOString(),
              tool: input.tool_name,
              input: input.tool_input,
              sessionId: input.session_id,
            };
            appendFileSync("audit.log", JSON.stringify(entry) + "\n");
            return {};
          },
        ],
      },
    ],
  },
});

Hooks vs. canUseTool

Sowohl Hooks als auch der canUseTool-Callback können Toolaufrufe abfangen, aber sie dienen unterschiedlichen Zwecken:

Feature

canUseTool

Hooks

Bereich

Nur Berechtigungsprüfung vor der Ausführung

Mehrere Lebenszyklusereignisse (Tool-Lebenszyklus, Prompt-Eingabe, Stopp, Lebenszyklus des Subagenten, Benachrichtigung und Komprimierung)

Veranstaltungen

Eins: Berechtigungsanfragen

Zehn: PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, UserPromptSubmit, Stop, SubagentStart, SubagentStop, Notification und PreCompact

Mustererkennung

Keine Matcher-Unterstützung. Wird für Berechtigungsanfragen aufgerufen, die noch nicht durch Regellisten aufgelöst wurden.

Ja (Regex-Matcher filtern je nach Ereignis nach Toolname, Benachrichtigungstyp oder Komprimierungstrigger)

Eingabe ändern

Begrenzt. updatedInput wird derzeit für SDK-Routing-Pseudo-Tools wie AskUserQuestion und ExitPlanMode verwendet.

Ja (hookSpecificOutput.updatedInput)

Am besten geeignet für

Einfache Entscheidungen zwischen Zulassen/Ablehnen

Audit-Protkollieren, Kontexteinschleusung, komplexe Richtlinien, Aktionen nach der Ausführung

Sie können beides zusammen verwenden. Der canUseTool-Callback wird als Teil des Berechtigungssystem von CLI ausgeführt, während PreToolUse-Hooks separat ausgeführt werden.