# Event Reference

This page documents the input and output fields for each hook event. For the base input schema and common output fields shared by all events, see [Hooks](https://docs.tabnine.com/main/getting-started/tabnine-cli/features/hooks).

## `SessionStart`

Fires on application startup, when resuming a session, or after a `/clear` command.

**Additional input fields:**

| Field    | Type     | Values                             |
| -------- | -------- | ---------------------------------- |
| `source` | `string` | `"startup"`, `"resume"`, `"clear"` |

**Relevant output fields:**

* `hookSpecificOutput.additionalContext` (`string`): Injected as context into the session.
* `systemMessage`: Shown at the start of the session.

{% hint style="info" %}
Advisory only — `continue` and `decision` are ignored. Startup is never blocked.
{% endhint %}

**Example config:**

```json
{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node ./hooks/load-context.js",
            "name": "load-context",
            "timeout": 5000
          }
        ]
      }
    ]
  }
}
```

## `SessionEnd`

Fires when the CLI exits or a session is cleared.

**Additional input fields:**

| Field    | Type     | Values                                                            |
| -------- | -------- | ----------------------------------------------------------------- |
| `reason` | `string` | `"exit"`, `"clear"`, `"logout"`, `"prompt_input_exit"`, `"other"` |

{% hint style="info" %}
Best effort only — the CLI will not wait for this hook to complete.
{% endhint %}

## `BeforeAgent`

Fires after a user submits a prompt but before the agent begins planning.

**Additional input fields:**

| Field    | Type     | Description                  |
| -------- | -------- | ---------------------------- |
| `prompt` | `string` | The user's submitted prompt. |

**Relevant output fields:**

* `hookSpecificOutput.additionalContext` (`string`): Appended to the prompt for this turn.
* `decision: "deny"`: Blocks the turn and discards the user's message from history.
* `continue: false`: Blocks the turn but saves the message to history.

## `AfterAgent`

Fires after the model generates its final response for a turn.

**Additional input fields:**

| Field              | Type      | Description                                       |
| ------------------ | --------- | ------------------------------------------------- |
| `prompt`           | `string`  | The user's original prompt.                       |
| `prompt_response`  | `string`  | The final text generated by the agent.            |
| `stop_hook_active` | `boolean` | Whether this is already part of a retry sequence. |

**Relevant output fields:**

* `decision: "deny"`: Rejects the response and triggers a retry. `reason` is sent to the agent as a new prompt requesting correction.
* `hookSpecificOutput.clearContext` (`boolean`): If `true`, clears conversation history while preserving the UI display.

## `BeforeTool`

Fires before a tool is executed. Used for argument validation, security checks, and parameter rewriting.

**Additional input fields:**

| Field                   | Type     | Description                                                 |
| ----------------------- | -------- | ----------------------------------------------------------- |
| `tool_name`             | `string` | Name of the tool (e.g., `write_file`, `run_shell_command`). |
| `tool_input`            | `object` | The arguments generated by the model.                       |
| `mcp_context`           | `object` | Optional metadata for MCP-based tools.                      |
| `original_request_name` | `string` | Original tool name if this is a tail tool call.             |

**Relevant output fields:**

* `decision: "deny"`: Prevents the tool from executing. `reason` is sent to the agent as a tool error.
* `hookSpecificOutput.tool_input` (`object`): Replaces the model's arguments before execution. Must include **all** required tool parameters (not just the ones you want to change), because the CLI validates the complete object. Merge the original `tool_input` from stdin with your overrides: `{ ...input.tool_input, content: 'new value' }`.
* `continue: false`: Kills the entire agent loop.
* Exit code 2: Blocks execution; stderr is used as the reason.

## `AfterTool`

Fires after a tool executes. Used for result auditing, context injection, or hiding sensitive output.

**Additional input fields:**

| Field           | Type     | Description                                                                 |
| --------------- | -------- | --------------------------------------------------------------------------- |
| `tool_name`     | `string` | Name of the tool.                                                           |
| `tool_input`    | `object` | The original arguments.                                                     |
| `tool_response` | `object` | The result, containing `llmContent`, `returnDisplay`, and optional `error`. |

**Relevant output fields:**

* `decision: "deny"`: Hides the real tool output. `reason` replaces the result sent to the model.
* `hookSpecificOutput.additionalContext` (`string`): Appended to the tool result for the agent.
* `hookSpecificOutput.tailToolCallRequest` (`{ name, args }`): Execute another tool immediately after this one; its result replaces the original response.

## `BeforeModel`

Fires before sending a request to the LLM.

**Additional input fields:**

| Field         | Type     | Description                                           |
| ------------- | -------- | ----------------------------------------------------- |
| `llm_request` | `object` | Contains `model`, `messages`, `config`, `toolConfig`. |

**Relevant output fields:**

* `hookSpecificOutput.llm_request` (`object`): Overrides parts of the outgoing request (e.g., changing model or temperature).
* `hookSpecificOutput.llm_response` (`object`): A synthetic response. If provided, the LLM call is skipped entirely.
* `decision: "deny"`: Blocks the request and aborts the turn.

## `AfterModel`

Fires after receiving an LLM response chunk.

**Additional input fields:**

| Field          | Type     | Description                      |
| -------------- | -------- | -------------------------------- |
| `llm_request`  | `object` | The original request.            |
| `llm_response` | `object` | The model's response (or chunk). |

**Relevant output fields:**

* `hookSpecificOutput.llm_response` (`object`): Replaces the model's response chunk.
* `decision: "deny"`: Discards the response chunk and blocks the turn.

{% hint style="info" %}
**Note**: This fires for **every chunk** during streaming. Modifications only affect the current chunk.
{% endhint %}

## `BeforeToolSelection`

Fires before the LLM decides which tools to call. Used to filter the available toolset.

**Additional input fields:**

| Field         | Type     | Description                   |
| ------------- | -------- | ----------------------------- |
| `llm_request` | `object` | Same format as `BeforeModel`. |

**Relevant output fields:**

* `hookSpecificOutput.toolConfig.mode` (`"AUTO" | "ANY" | "NONE"`):
  * `"NONE"`: Disables all tools (wins over other hooks).
  * `"ANY"`: Forces at least one tool call.
* `hookSpecificOutput.toolConfig.allowedFunctionNames` (`string[]`): Whitelist of tool names. Multiple hooks' whitelists are combined.

{% hint style="info" %}
Does **not** support `decision`, `continue`, or `systemMessage`.
{% endhint %}

## `PreCompress`

Fires before the CLI summarizes history to save tokens.

**Additional input fields:**

| Field     | Type     | Values                 |
| --------- | -------- | ---------------------- |
| `trigger` | `string` | `"auto"` or `"manual"` |

{% hint style="info" %}
Advisory only — fired asynchronously. Cannot block or modify compression.
{% endhint %}

## `Notification`

Fires when the CLI emits a system alert (e.g., tool permission request).

**Additional input fields:**

| Field               | Type     | Description                                      |
| ------------------- | -------- | ------------------------------------------------ |
| `notification_type` | `string` | Type of notification (e.g., `"ToolPermission"`). |
| `message`           | `string` | Summary of the alert.                            |
| `details`           | `object` | Alert-specific metadata.                         |

{% hint style="info" %}
Observability only — cannot block alerts or grant permissions.
{% endhint %}
