Use Case: Event-Driven Agent with Webhooks
Run Octomind as a persistent daemon that reacts to external events -- GitHub pushes, Slack messages, monitoring alerts.
The Problem
You want an AI agent that monitors events and acts autonomously: reviewing pushed code, responding to incidents, or summarizing deployments. Polling is wasteful; you need event-driven reactions.
Solution
Combine daemon mode with webhook hooks.
Architecture
GitHub/Slack/PagerDuty
|
| HTTP POST
v
Webhook Hook (HTTP listener on port 9876)
|
| stdin: raw HTTP body
v
Hook Script (process-event.sh)
|
| stdout: message for AI
v
Daemon Session Inbox
|
v
AI processes event, takes action
Step 1: Write a Hook Script
#!/bin/bash
# /opt/hooks/github-push.sh
payload=$(cat)
repo=$(echo "$payload" | jq -r '.repository.full_name')
branch=$(echo "$payload" | jq -r '.ref' | sed 's|refs/heads/||')
pusher=$(echo "$payload" | jq -r '.pusher.name')
commits=$(echo "$payload" | jq -r '.commits | length')
# Only react to main branch
if [ "$branch" != "main" ]; then
exit 1 # Non-zero = ignore
fi
# Files changed
files=$(echo "$payload" | jq -r '.commits[].modified[]' | sort -u | head -20)
cat <<EOF
Push to $repo/$branch by $pusher ($commits commits).
Changed files:
$files
Please:
1. Review the changes for potential issues
2. Check if any tests might be affected
3. Summarize the changes in 2-3 sentences
EOF
Make it executable:
chmod +x /opt/hooks/github-push.sh
Step 2: Configure the Hook
[[hooks]]
name = "github-push"
bind = "0.0.0.0:9876"
script = "/opt/hooks/github-push.sh"
timeout = 30
Step 3: Start the Daemon
octomind run --name code-monitor --daemon --format jsonl --hook github-push
Step 4: Point GitHub Webhook
In your GitHub repo settings:
- Webhook URL:
http://your-server:9876/ - Content type:
application/json - Events: "Push"
Now every push to main triggers an AI review.
Multiple Hooks
Monitor different event sources simultaneously:
[[hooks]]
name = "github-push"
bind = "0.0.0.0:9876"
script = "/opt/hooks/github-push.sh"
timeout = 30
[[hooks]]
name = "slack-mention"
bind = "0.0.0.0:9877"
script = "/opt/hooks/slack-mention.sh"
timeout = 15
[[hooks]]
name = "pagerduty-alert"
bind = "0.0.0.0:9878"
script = "/opt/hooks/pagerduty-alert.sh"
timeout = 30
octomind run --name ops-agent --daemon --format jsonl \
--hook github-push \
--hook slack-mention \
--hook pagerduty-alert
Injecting Messages Manually
Besides webhooks, you can inject messages directly:
echo "Summarize what happened in the last hour" | octomind send --name ops-agent
Hook Script Environment
Your script receives rich context via environment variables:
| Variable | Example |
|---|---|
HOOK_NAME |
github-push |
HOOK_METHOD |
POST |
HOOK_PATH |
/webhook |
HOOK_CONTENT_TYPE |
application/json |
HOOK_SESSION |
code-monitor |
HOOK_HEADER_X_GITHUB_EVENT |
push |
Use these to route different event types in a single script:
#!/bin/bash
event="$HOOK_HEADER_X_GITHUB_EVENT"
case "$event" in
push)
echo "Code pushed: $(cat | jq -r '.commits | length') commits"
;;
pull_request)
echo "PR $(cat | jq -r '.action'): $(cat | jq -r '.pull_request.title')"
;;
*)
exit 1 # Ignore unknown events
;;
esac
Key Points
--daemonkeeps the session alive between events--hookactivates webhook listeners (multiple allowed)- Scripts exit 0 = inject stdout as user message; non-zero = ignore
octomind send --name Xfor manual message injection- JSONL output is parseable by downstream tools
- The AI has full tool access -- it can read the actual files, not just the webhook payload