Get Started#
The Alert Agent Service is a generic multimodal alert action dispatcher. It accepts alert events from detection pipelines (video analytics, audio sensors, IoT devices, and more), optionally applies LLM-based reasoning via Google ADK and OpenVINO™ Model Server, and dispatches configurable action tools such as webhook notifications, MQTT publishing, snapshot saving, and structured logging.
Features#
Dispatches alert actions via LLM-powered ADK or deterministic rule-based mode
Accepts multimodal payloads — text, image, audio, video, and binary artifacts
Built-in action tools:
log_alert,trigger_webhook,capture_snapshot,publish_mqttSubscription config for per-alert-name default tool routing and deduplication rules
Escalation support — additional tools triggered after a consecutive-detection threshold
MCP (Model Context Protocol) integration to extend the tool set dynamically
Real-time SSE and WebSocket event streams for alert fanout to monitoring clients
Hot-reload of tool and MCP configurations without service restart
Prerequisites#
Docker Engine 24 or later
Docker Compose v2 plugin (
docker compose)Sufficient disk space for the LLM model (approximately 4 GB for the default Phi-4-mini-instruct model)
Note: The default configuration uses
TARGET_DEVICE=GPUfor the OVMS LLM container. To run on CPU-only Intel devices, setTARGET_DEVICE=CPUin your environment. This increases LLM inference latency but requires no GPU.
See System Requirements for full details.
Deploy with Docker Compose#
1. Clone the Microservice#
Go to the target directory of your choice and clone the microservice. If you want to clone a specific release branch, replace main with the desired tag. To learn more on partial cloning, check the Repository Cloning guide.
git clone --filter=blob:none --sparse --branch main https://github.com/open-edge-platform/edge-ai-libraries.git
cd edge-ai-libraries/
git sparse-checkout set microservices/alert-agent-service/
cd microservices/alert-agent-service/
2. Configure Environment Variables#
Export variables with the required configuration:
# ----- Service -----
export PORT=8000
export LOG_LEVEL=INFO
export REGISTRY="intel/"
export TAG=latest
# ----- ADK / LLM -----
export AGENT_MODE=true
export LLM_URL=http://ovms-llm:9000/v3
export LLM_MODEL=OpenVINO/Phi-4-mini-instruct-int4-ov
export LLM_TIMEOUT=10.0
export TARGET_DEVICE=GPU # GPU (default) or CPU
# ----- Webhook action tool (optional) -----
export WEBHOOK_URL=https://your-webhook-endpoint.example.com/hook
export WEBHOOK_SECRET= # leave empty to skip HMAC signing
# ----- MQTT action tool (optional) -----
export MQTT_BROKER= # e.g. mqtt.example.com
export MQTT_PORT=1883
export MQTT_USERNAME=
export MQTT_PASSWORD=
export MQTT_BASE_TOPIC=alerts
# ----- Proxy (if required) -----
export http_proxy=
export https_proxy=
export no_proxy=localhost,127.0.0.1,ovms-llm
Note:
WEBHOOK_URLandMQTT_BROKERare optional. If not set, the corresponding tools are skipped gracefully when invoked.
3. Start the Services#
For rule-based mode:
docker compose -f docker/docker-compose.yml up -d
For ADK / agent mode:
docker compose -f docker/docker-compose.yml --profile agent up -d
This starts up to three containers:
Container |
Description |
|---|---|
|
The alert action dispatcher |
|
Local MQTT broker used by the MQTT action tool |
|
OpenVINO™ Model Server serving the Phi-4-mini-instruct LLM (agent mode only) |
In agent mode, the ovms-llm container is started only when you include --profile agent. Initial startup may take 2–5 minutes while the LLM model is downloaded and loaded. During that time, alert-agent-service may be up before the LLM is ready.
To build the image locally before starting:
docker compose -f docker/docker-compose.yml up -d --build
# add --profile agent to start ovms-llm as well
4. Verify the Service is Running#
docker compose -f docker/docker-compose.yml ps
Check the health endpoint:
curl http://localhost:8000/api/v1/health
Expected response:
{
"status": "healthy",
"adk_enabled": true,
"mcp_enabled": true,
"uptime_seconds": 12.4,
"timestamp": "2026-06-15T07:30:00Z"
}
5. Access the API Documentation#
Open the Swagger UI at http://localhost:8000/docs.
6. Stop the Services#
# rule-based mode
docker compose -f docker/docker-compose.yml down
# agent mode
docker compose -f docker/docker-compose.yml --profile agent down
Sample Usage#
Dispatch a Text Alert#
curl -X POST http://localhost:8000/api/v1/actions/execute \
-H "Content-Type: application/json" \
-d '{
"data":{
"source_id": "sensor-42",
"alert_name": "TemperatureThreshold",
"answer": "YES",
"reason": "CPU temperature exceeded 90°C",
"tools": ["log_alert", "trigger_webhook"]
}
}'
Dispatch an Image Alert (base64 JPEG)#
curl -X POST http://localhost:8000/api/v1/actions/execute \
-H "Content-Type: application/json" \
-d '{
"data":{
"source_id": "cam-01",
"alert_name": "CONCEALMENT",
"answer": "YES",
"reason": "Camera lens partially covered",
"tools": ["log_alert", "capture_snapshot", "trigger_webhook"],
"payloads": [
{
"kind": "image",
"mime_type": "image/jpeg",
"encoding": "base64",
"data_base64": "<base64-encoded-jpeg>",
"metadata": {"width": 1920, "height": 1080}
}
]
}
}'
Sample response:
{
"event_id": "a3f7c2d1e8b04e5f90123456789abcde",
"source_id": "cam-01",
"alert_name": "CONCEALMENT",
"actions_taken": ["capture_snapshot", "log_alert", "trigger_webhook"],
"snapshot_path": "/app/snapshots/cam-01_CONCEALMENT_20260615_073045.jpg",
"duration_ms": 312.5,
"timestamp": "2026-06-15T07:30:45Z"
}
Subscribe to Real-Time SSE Events#
curl -N http://localhost:8000/api/v1/events
Example output:
event: init
data: {"message": "Connected to Alert Agent Service SSE stream", "adk_enabled": true, "mcp_enabled": true}
event: alert_action
data: {"event_id": "...", "source_id": "cam-01", "alert_name": "CONCEALMENT", "actions_taken": ["log_alert"], ...}
event: keepalive
data: {"ts": 1749971445.123}
List Available Tools#
curl http://localhost:8000/api/v1/tools
Configuration#
Environment Variables#
Variable |
Default |
Description |
|---|---|---|
|
|
Port the service listens on |
|
|
Logging level ( |
|
|
Enable ADK (LLM-reasoned) dispatch; set |
|
|
OVMS inference device — set to |
|
|
OpenAI-compatible LLM endpoint |
|
|
Model repository path / name |
|
|
LLM request timeout in seconds |
|
|
Concurrent worker pool size for tool execution |
|
(empty) |
Default webhook endpoint for |
|
(empty) |
HMAC-SHA256 secret for webhook request signing |
|
(empty) |
MQTT broker hostname or IP |
|
|
MQTT broker port |
|
(empty) |
MQTT broker username |
|
(empty) |
MQTT broker password |
|
|
Base MQTT topic prefix |
|
|
Directory for saving image snapshots |
|
|
Number of retry attempts for failed tool invocations |
|
|
Delay in seconds between retry attempts |
|
|
Path to the subscription YAML configuration file |
|
|
Enable MCP server integration |
|
|
Path to the MCP servers configuration file |
Subscription Configuration (resources/config.yaml)#
The subscription config defines default routing rules per alert name. Request-level fields always override these defaults.
subscriptions:
- alert_name: CONCEALMENT
tools:
- log_alert
- trigger_webhook
- capture_snapshot
tool_arguments:
trigger_webhook:
url: "${WEBHOOK_URL}"
dedup:
enabled: true
strategy: field_hash
fields:
- source_id
window_seconds: 30
on_missing: skip
escalation:
threshold_consecutive: 3
additional_tools:
- publish_mqtt
- alert_name: LOITERING
tools:
- log_alert
dedup:
enabled: true
strategy: field_hash
fields:
- source_id
window_seconds: 120
on_missing: skip
- alert_name: INTRUSION
tools:
- log_alert
- trigger_webhook
tool_arguments:
trigger_webhook:
url: "${WEBHOOK_URL}"
dedup:
enabled: false
Note: The
${WEBHOOK_URL}placeholder is resolved at runtime from the environment variable.
MCP Server Configuration (resources/mcp_servers.json)#
Configure external MCP servers to extend the tool set dynamically:
{
"servers": [
{
"name": "prometheus",
"enabled": true,
"transport": "http",
"url": "http://prometheus-mcp-server:9090/mcp",
"description": "Prometheus MCP Server",
"timeout": 30.0
}
]
}
Set "enabled": false to disable a server without removing its configuration.
Docker Volumes#
Volume |
Container Path |
Description |
|---|---|---|
|
|
Subscription config, tools.json, and mcp_servers.json (mounted for live updates) |
|
|
Persistent storage for captured image snapshots |
Troubleshooting#
The alert-agent-service fails to start, showing Agent not initialised:
Check that
ovms-llmhas passed its health check:docker compose -f docker/docker-compose.yml --profile agent logs ovms-llmThe LLM model may still be loading. Wait up to 5 minutes and re-check.
If running on a CPU-only device, ensure
TARGET_DEVICE=CPUis set in your environment before runningdocker compose -f docker/docker-compose.yml up(add--profile agentwhen using agent mode).
Webhook notifications are skipped:
Verify
WEBHOOK_URLis set and reachable from within the container.Check logs:
docker compose -f docker/docker-compose.yml logs alert-agent-service | grep webhook
MQTT publishing is skipped:
Verify
MQTT_BROKERis set and the broker is reachable.Ensure
MQTT_PORT,MQTT_USERNAME, andMQTT_PASSWORDare correct.
Container logs:
docker compose -f docker/docker-compose.yml logs -f alert-agent-service
docker compose -f docker/docker-compose.yml --profile agent logs -f ovms-llm
Run Unit Tests#
Install
uv(if not already installed):pip install uv
Create and activate a virtual environment:
uv venv source .venv/bin/activate
Install dependencies:
uv syncRun tests:
uv run pytest tests/ -v