Skip to content

Hooks & Events

✓ Fresh · 2026-02-24

Pi provides a comprehensive event system that extensions can hook into. These events cover the full lifecycle of sessions, messages, tools, agents, and more.

Event Categories

Complete Event Reference

Session Events

EventFires WhenUse Case
session_startA new session beginsInitialize state, load resources
session_shutdownSession is endingClean up, save state
session_before_compactBefore context compactionCustomize what gets preserved
session_compactAfter context compactionLog or process the summary
session_before_forkBefore session forkValidate or modify fork behavior
session_forkAfter session forkInitialize the new session
session_before_switchBefore switching branchesSave branch-specific state
session_switchAfter switching branchesRestore branch-specific state

Input Events

EventFires WhenUse Case
inputUser submits a messagePreprocess, filter, or transform input

Tool Events

EventFires WhenUse Case
tool_callAgent requests a tool callPermission gating, logging, modification
tool_resultTool returns a resultPost-processing, validation
execution_startTool execution beginsStart timers, show status
execution_updateTool execution progressUpdate progress displays
execution_endTool execution completesStop timers, log metrics

Bash Events

EventFires WhenUse Case
BashSpawnHookA bash process is spawnedSandbox configuration, env setup
user_bashUser runs a !commandLog or gate user bash commands

Agent/Turn Events

EventFires WhenUse Case
before_agent_startBefore agent begins processingInject context, modify config
agent_startAgent starts processingTrack agent activity
agent_endAgent finishes processingCollect metrics, trigger actions
turn_startA conversation turn beginsPer-turn setup
turn_endA conversation turn endsPer-turn cleanup

Message Events

EventFires WhenUse Case
message_startLLM begins generatingShow streaming indicators
message_updateLLM produces a chunkReal-time processing
message_endLLM finishes generatingProcess complete response

Model Events

EventFires WhenUse Case
model_selectModel is changedLog model usage, adjust settings
contextContext is assembled for the LLMModify or inspect context

Using Events in Extensions

Basic Event Handler

typescript
export default function (pi: ExtensionAPI) {
  pi.on("session_start", async (event) => {
    console.log("Session started:", event.sessionId);
  });

  pi.on("tool_call", async (event, ctx) => {
    console.log(`Tool: ${event.tool}, Args: ${JSON.stringify(event.args)}`);
  });

  pi.on("session_shutdown", async () => {
    console.log("Session ended — cleaning up");
  });
}

Permission Gate Example

typescript
export default function (pi: ExtensionAPI) {
  const BLOCKED_COMMANDS = ["rm -rf /", "DROP DATABASE", "git push --force"];

  pi.on("tool_call", async (event, ctx) => {
    if (event.tool === "bash") {
      const cmd = event.args.command;
      for (const blocked of BLOCKED_COMMANDS) {
        if (cmd.includes(blocked)) {
          return {
            abort: true,
            message: `BLOCKED: "${blocked}" is not allowed.`
          };
        }
      }
    }
  });
}

Metrics Collector Example

typescript
export default function (pi: ExtensionAPI) {
  const metrics = { tools: 0, tokens: 0, turns: 0 };

  pi.on("tool_call", async () => { metrics.tools++; });
  pi.on("turn_end", async () => { metrics.turns++; });
  pi.on("message_end", async (event) => {
    metrics.tokens += event.tokenCount || 0;
  });

  pi.on("session_shutdown", async () => {
    console.log("Session metrics:", JSON.stringify(metrics, null, 2));
  });
}

Event Execution Order

Pi Coding Agent SOP Documentation