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_mqtt

  • Subscription 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=GPU for the OVMS LLM container. To run on CPU-only Intel devices, set TARGET_DEVICE=CPU in 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_URL and MQTT_BROKER are 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

alert-agent-service

The alert action dispatcher

mqtt

Local MQTT broker used by the MQTT action tool

ovms-llm

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

8000

Port the service listens on

LOG_LEVEL

INFO

Logging level (DEBUG, INFO, WARNING, ERROR)

AGENT_MODE

true

Enable ADK (LLM-reasoned) dispatch; set false for rule-based mode

TARGET_DEVICE

GPU

OVMS inference device — set to CPU for Intel devices without a discrete GPU

LLM_URL

http://ovms-llm:9000/v3

OpenAI-compatible LLM endpoint

LLM_MODEL

OpenVINO/Phi-4-mini-instruct-int4-ov

Model repository path / name

LLM_TIMEOUT

10.0

LLM request timeout in seconds

ACTION_WORKERS

2

Concurrent worker pool size for tool execution

WEBHOOK_URL

(empty)

Default webhook endpoint for trigger_webhook

WEBHOOK_SECRET

(empty)

HMAC-SHA256 secret for webhook request signing

MQTT_BROKER

(empty)

MQTT broker hostname or IP

MQTT_PORT

1883

MQTT broker port

MQTT_USERNAME

(empty)

MQTT broker username

MQTT_PASSWORD

(empty)

MQTT broker password

MQTT_BASE_TOPIC

alerts

Base MQTT topic prefix

SNAPSHOT_DIR

snapshots

Directory for saving image snapshots

RETRY_ATTEMPTS

3

Number of retry attempts for failed tool invocations

RETRY_INTERVAL_SECONDS

2.0

Delay in seconds between retry attempts

SUBSCRIPTION_CONFIG_PATH

resources/config.yaml

Path to the subscription YAML configuration file

MCP_ENABLED

true

Enable MCP server integration

MCP_CONFIG_FILE

resources/mcp_servers.json

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

./resources

/app/resources

Subscription config, tools.json, and mcp_servers.json (mounted for live updates)

snapshots

/app/snapshots

Persistent storage for captured image snapshots


Troubleshooting#

The alert-agent-service fails to start, showing Agent not initialised:

  • Check that ovms-llm has passed its health check: docker compose -f docker/docker-compose.yml --profile agent logs ovms-llm

  • The LLM model may still be loading. Wait up to 5 minutes and re-check.

  • If running on a CPU-only device, ensure TARGET_DEVICE=CPU is set in your environment before running docker compose -f docker/docker-compose.yml up (add --profile agent when using agent mode).

Webhook notifications are skipped:

  • Verify WEBHOOK_URL is 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_BROKER is set and the broker is reachable.

  • Ensure MQTT_PORT, MQTT_USERNAME, and MQTT_PASSWORD are 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#

  1. Install uv (if not already installed):

    pip install uv
    
  2. Create and activate a virtual environment:

    uv venv
    source .venv/bin/activate
    
  3. Install dependencies:

    uv sync
    
  4. Run tests:

    uv run pytest tests/ -v
    

Learn More#