Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.enconvo.ai/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Hooks let you trigger shell commands or HTTP requests whenever something happens in EnConvo - like an agent starting, completing, or failing. No coding required - just create a JSON config file.
Hooks are great for notifications, logging, CI/CD integration, or syncing with external tools like Slack, Discord, or your own APIs.

Quick Start

1

Create the config file

Create ~/.config/enconvo/hooks.json:
{
  "run_status_changed": [
    {
      "hooks": [
        {
          "type": "command",
          "command": "echo 'Agent status changed!' >> /tmp/enconvo.log"
        }
      ]
    }
  ]
}
2

That's it

The config is loaded automatically. Every time an agent’s status changes, your command runs. No restart needed - the config is reloaded on each event.

Configuration

The config file lives at ~/.config/enconvo/hooks.json. The structure is:
{
  "event_name": [
    {
      "matcher": "optional_regex_filter",
      "hooks": [
        { "type": "command", "command": "..." },
        { "type": "http", "url": "..." }
      ]
    }
  ]
}
FieldTypeRequiredDescription
event_namestringYesThe event to listen for (top-level key)
matcherstringNoRegex to filter events. Empty = match all
hooksarrayYesList of hooks to execute

Hook Types

Command Hook

Runs a shell command. Event data is sent to stdin as JSON.
{
  "type": "command",
  "command": "/path/to/script.sh",
  "timeout": 30000
}
FieldTypeDefaultDescription
type"command"-Required
commandstring-Shell command to execute
timeoutnumber30000Timeout in milliseconds

HTTP Hook

Sends a POST request with event data as the JSON body.
{
  "type": "http",
  "url": "https://example.com/webhook",
  "headers": {
    "Authorization": "Bearer your-token"
  },
  "timeout": 30000
}
FieldTypeDefaultDescription
type"http"-Required
urlstring-HTTP endpoint URL
methodstring"POST"HTTP method
headersobject{}Additional headers
timeoutnumber30000Timeout in milliseconds

Event Data Format

Both command hooks (stdin) and HTTP hooks (request body) receive the same JSON:
{
  "event": "run_status_changed",
  "fullEvent": "event-run_status_changed",
  "params": {
    "commandKey": "chat_with_ai|chat",
    "runStatus": "running"
  },
  "timestamp": 1742313600000
}
FieldDescription
eventShort event name
fullEventFull internal event name
paramsEvent-specific payload
timestampUnix timestamp in milliseconds

Available Events

EventParamsWhen
run_status_changed{ commandKey, runStatus }Agent/chat/bot changes to running, completed, or failed
recent_chat_list_changed{ command, commandKey }Recent chat list is updated
audio_progress_<hash>{ currentTime, duration, progress }Audio playback progress
audio_played_<hash>{}Audio playback completed
audio_state_<hash>{ state }Audio player state changed
Extensions can fire custom events. Any event name used by an extension can be used as a hook trigger.

Examples

macOS Notification on Agent Failure

Get a native notification when any agent fails:
{
  "run_status_changed": [
    {
      "hooks": [
        {
          "type": "command",
          "command": "STATUS=$(cat | jq -r '.params.runStatus') && [ \"$STATUS\" = \"failed\" ] && osascript -e 'display notification \"An agent failed\" with title \"EnConvo\"'"
        }
      ]
    }
  ]
}

Log All Status Changes

Write a timestamped log of every agent status change:
{
  "run_status_changed": [
    {
      "hooks": [
        {
          "type": "command",
          "command": "jq -c '{time: (.timestamp / 1000 | strftime(\"%Y-%m-%d %H:%M:%S\")), agent: .params.commandKey, status: .params.runStatus}' >> ~/.config/enconvo/agent-status.log"
        }
      ]
    }
  ]
}

Slack Webhook

Send a message to Slack when an agent completes:
{
  "run_status_changed": [
    {
      "hooks": [
        {
          "type": "http",
          "url": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
        }
      ]
    }
  ]
}

Custom Script

Create a script that reads event data from stdin and takes action:
#!/bin/bash
# ~/.config/enconvo/hooks/on-status-change.sh
INPUT=$(cat)
STATUS=$(echo "$INPUT" | jq -r '.params.runStatus')
AGENT=$(echo "$INPUT" | jq -r '.params.commandKey')

echo "[$(date)] $AGENT -> $STATUS" >> /tmp/enconvo-hooks.log

if [ "$STATUS" = "failed" ]; then
    osascript -e "display notification \"$AGENT failed\" with title \"EnConvo\""
fi
Reference it in your config:
{
  "run_status_changed": [
    {
      "hooks": [
        {
          "type": "command",
          "command": "bash ~/.config/enconvo/hooks/on-status-change.sh"
        }
      ]
    }
  ]
}
Make sure your scripts are executable: chmod +x ~/.config/enconvo/hooks/on-status-change.sh

Multiple Hooks on One Event

You can run multiple hooks for the same event. They all execute concurrently:
{
  "run_status_changed": [
    {
      "hooks": [
        { "type": "command", "command": "echo 'log' >> /tmp/hooks.log" },
        { "type": "http", "url": "http://localhost:8080/webhook" },
        { "type": "command", "command": "bash ~/.config/enconvo/hooks/notify.sh" }
      ]
    }
  ]
}

Important Notes

Hooks run in the background and do not block EnConvo. If a hook fails or times out, it is logged to the server console but does not affect the event flow.
The hooks.json file is checked for changes (by modification time) each time an event fires. You can edit the file while EnConvo is running - no restart needed.
Shell commands run with the server’s environment. Use absolute paths for scripts, or prefix with bash to enable ~ expansion.
To test your hook script manually, pipe sample JSON to it:
echo '{"event":"run_status_changed","params":{"commandKey":"my_agent|main","runStatus":"failed"},"timestamp":1742313600000}' | bash ~/.config/enconvo/hooks/on-status-change.sh

Event System for Developers

Build extensions that listen and react to events programmatically

Agents

Learn about EnConvo agents and custom bots