{"id":"2652dd4b-b7e1-43f0-87ab-5eba4fd893f9","slug":"vss-manage-alerts","kind":"skill","name":"vss-manage-alerts","summary":"Use for VSS alert workflows — real-time monitoring, Alert-Bridge subscriptions, Slack notifications, incident queries, camera onboarding. Not for non-alert analytics.","owner":"NVIDIA","repoUrl":"https://github.com/NVIDIA/skills/tree/HEAD/skills/vss-manage-alerts","license":"Apache-2.0","licenseTier":"permissive","trust":"official","stars":3586,"match":null,"fewStars":false,"format":"skill","createdAt":null,"addedAt":"2026-10-14T05:51:49.611Z","logoUrl":"https://avatars.githubusercontent.com/u/1728152?v=4","linkOnly":false,"collection":{"name":"skills","repo":"nvidia/skills"},"skillPath":"skills/vss-manage-alerts","categories":["developer-tools","communication","cloud-infra"],"tags":["agentic-ai","ai-agents","claude-code","codex","coding-agents","cuda","developer-tools","llm"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-14T05:51:49.609Z","sample":false,"url":"https://conduits.dev/tools/vss-manage-alerts","language":"Python","transports":[],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"## Purpose\n\nOperate the VSS alert pipeline (mode detection, Alert-Bridge subscriptions, Slack notifications, queries, camera onboarding, verifier-prompt customization).\n\n## Prerequisites\n\n- Active VSS deployment reachable on `$HOST_IP` (see `vss-deploy-profile` and `references/`).\n- NGC credentials in `$NGC_CLI_API_KEY` and `$NVIDIA_API_KEY` for any image pulls.\n- `curl`, `jq`, and Docker available on the caller.\n\n## Instructions\n\nFollow the routing tables and step-by-step workflows below. Each section that ends in *workflow*, *quick start*, or *flow* is intended to be executed top-to-bottom. Detailed reference material lives in `references/` and helper scripts live in `scripts/` — call them via `run_script` when the skill points to a script by name.\n\n## Examples\n\nRunnable end-to-end scenarios live under `evals/` (each `*.json` manifest); inline `curl` blocks appear in each workflow below. Replay with `nv-base validate <this-skill-dir> --agent-eval`.\n\n## Limitations\n\nRequires the matching VSS profile/microservice deployed and reachable. NGC-hosted models/NIMs are subject to rate-limits, GPU-memory needs, and license terms; concurrency and storage limits depend on host hardware and the profile's compose file.\n\n## Troubleshooting\n\n- **Connection refused** → microservice not running: probe `/docs` or `/health`, redeploy via `vss-deploy-profile`.\n- **HTTP 401/403 on NGC pulls** → missing/expired `NGC_CLI_API_KEY`: `docker login nvcr.io` and re-export the key.\n- **OOM / model load failure** → insufficient GPU memory: use a smaller variant or `docker compose down` to free GPUs.\n\n# VSS Alert Management\n\nThe alerts profile runs in one of two modes (chosen at `/vss-deploy-profile -p alerts -m {verification,real-time}`) — see **The Two Modes** table below. This skill routes by **deployed mode + user intent** (monitoring vs subscription CRUD vs Slack webhook).\n\n## When to Use\n\n- Start/stop a real-time alert on a sensor (\"Start real-time alert for boxes dropped on warehouse_sample\")\n- Create/list/stop realtime subscription rules on Alert Bridge\n- Set up or manage Slack incident notifications\n- List or query detected incidents / alerts; check verdicts (confirmed/rejected/unverified)\n- Add a new camera to the alerts pipeline; customize VLM-verifier prompts (CV mode)\n\n---\n\n## Deployment prerequisite\n\nRequires the VSS **alerts** profile on `$HOST_IP` in either `verification` (CV) or `real-time` (VLM) mode.\n\n```bash\n# Either vss-rtvi-cv (CV mode) OR vss-rtvi-vlm (VLM mode) must be present.\ncurl -sf --max-time 5 \"http://${HOST_IP}:8000/docs\" >/dev/null \\\n  && docker ps --format '{{.Names}}' \\\n     | grep -qE '^(vss-rtvi-cv|vss-rtvi-vlm)$'\n```\n\nIf the probe fails, ask which mode to deploy and hand off to `/vss-deploy-profile -p alerts -m <mode>` (decline → stop; pre-authorized autonomous deploy → run directly with `verification` by default). If it passes, detect the mode per Step 1.\n\n---\n\n## The Two Modes (Deploy-Time Choice)\n\n| Mode | Deploy flag | Env (`.env`) | What runs | What is available |\n|---|---|---|---|---|\n| **CV (verification)** | `-m verification` | `MODE=2d_cv` | RT-CV (Grounding DINO) + Behavior Analytics + `alert-bridge` VLM verifier + **`rtvi-vlm`** | **Both** static CV pipeline (Workflow A) **and** dynamic VLM real-time alerts (Workflows B/D) |\n| **VLM (real-time)** | `-m real-time` | `MODE=2d_vlm` | `alert-bridge` + `rtvi-vlm` | **Only** dynamic VLM real-time alerts (Workflows B/D) and `alert-bridge` backend. No static CV pipeline. |\n\n**Switching modes** uses the `vss-deploy-profile` teardown + deploy flow with the other `-m` flag (VLM → CV adds the CV pipeline; CV → VLM tears it down). `rtvi-vlm` runs in both modes.\n\n---\n\n## Step 1 — Detect the Currently Deployed Mode\n\nBefore running any alert workflow, check which mode is live. Use **CV-only** containers as the signal — `vss-rtvi-vlm` is **not** a reliable mode signal because it runs in both modes.\n\n```bash\n# CV verification mode (vss-behavior-analytics + vss-rtvi-cv are CV-only)\ndocker ps --format '{{.Names}}' | grep -qx vss-behavior-analytics && echo \"mode=CV\"\n\n# VLM real-time mode (no CV pipeline; vss-rtvi-vlm still runs)\ndocker ps --format '{{.Names}}' | grep -qx vss-behavior-analytics || \\\n  docker ps --format '{{.Names}}' | grep -qx vss-rtvi-vlm && echo \"mode=VLM\"\n```\n\nIf `vss-behavior-analytics` is present → **CV mode** (which also has `vss-rtvi-vlm`).\nIf only `vss-rtvi-vlm` is present (and no CV pipeline) → **VLM mode**.\nIf neither matches, the alerts profile is not deployed — direct the user to the `vss-deploy-profile` skill.\n\nAlternative signal (preferred when `docker ps` isn't accessible): check the profile's `generated.env`:\n\n```bash\ngrep -E '^MODE=' deploy/docker/developer-profiles/dev-profile-alerts/generated.env\n# MODE=2d_cv   → CV mode (full superset)\n# MODE=2d_vlm  → VLM real-time mode (vss-rtvi-vlm only; no vss-rtvi-cv)\n```\n\n---\n\n## Step 2 — Route by Deployed Mode\n\n| Deployed mode | User asks about… | Action |\n|---|---|---|\n| **VLM real-time** | Slack webhook setup/status/test/stop | **Workflow E** — `references/alert-notify.md` |\n| **VLM real-time** | rule CRUD, or a realtime alert on a sensor with a detection condition, or stop/delete a named alert (by `alert_type`/condition or rule ID) | **Workflow D** — `references/alert-subscriptions.md` (incl. two-step stop/confirm) |\n| **CV verification** | subscription/rule CRUD or Slack/notification setup | Refuse — see canonical refusal text below |\n| **CV or VLM** | generic start/stop monitoring **without** a detection condition | **Workflow B (VLM)** — call the VSS Agent; `rtvi-vlm` runs in both modes |\n| **CV or VLM** | incident lookup / *what happened* (recent alerts, time-range, casual \"any alerts today?\") | **Workflow C (Query)** — works on both; **always run the query, never answer from memory** |\n| **CV** | static CV alert onboarding / verdict-prompt customization | **Workflow A (CV)** — onboard RTSP via `vss-manage-video-io-storage`; pipeline auto-picks it up |\n| **VLM** | a CV / behavior-analytics / PPE-rule alert needing the static CV pipeline | **Redeployment required** — confirm first, then `vss-deploy-profile -m verification` |\n\n**Always confirm before triggering a redeploy.** A mode switch stops all currently-running monitoring and restarts services.\n\n### Intent precedence (first match wins)\n\n1. **Workflow E (Slack)** — Slack-specific keywords (`slack`, `webhook` + `slack`, `bot token`, `slack channel`). `notify` alone is **not** sufficient.\n2. **Workflow D (Subscriptions)** — sensor **plus** a detection condition, rule CRUD keywords (`rule`, `subscription`, rule ID), **or stopping/deleting a named alert by type/condition** (\"stop the PPE alert\", \"delete the collision rule\"). A named `alert_type`/condition = an existing **rule** → D's two-step stop protocol (`GET /api/v1/realtime` → yes/no confirm → delete), never Workflow B.\n3. **Workflow B (VLM monitoring)** — generic start/stop on a sensor with **no** detection condition and **no** alert-type qualifier (\"start/stop real-time alert for sensor X\"). A stop that names a type (\"stop the **PPE** alert\") is a rule stop → Workflow D.\n4. **Workflow C (Query)** — incident lookup / *what happened* (`show/list incidents`, `recent alerts`, time-range queries, **and casual \"any alerts…?\" / \"any alerts so far today?\" / \"what's been triggered?\" phrasings**). Bare `alerts` (without `rule`/`subscription`/`active rules`) means **incidents** → Workflow C, never Workflow D.\n5. **Workflow A (CV)** — CV deployment handling for anything not matched above.\n\n> **`alerts` vs `alert rules` (C vs D) — pick exactly one, never both:**\n> *what happened / has been triggered* (incidents) → **Workflow C**\n> (`POST /generate`). *What\n> rules/subscriptions are configured or active* → **Workflow D** (the\n> **bare** `GET /api/v1/realtime`, no `/incidents`). Bare `alerts` =\n> incidents (C); `alert rules` / `subscriptions` / `active rules` =\n> inventory (D). Never answer from memory; run the one correct call —\n> full endpoint detail in Workflow C below.\n\n**Disambiguation (B vs D):** if a sensor is named with start/monitor language but the detection condition is unclear, ask:\n> *\"Do you want me to (a) create a persistent alert rule on Alert Bridge that keeps running until you delete it, or (b) start a one-time monitoring session via the VSS Agent?\"*\n\n**Stop routing (B vs D):** \"Stop the **&lt;type&gt;** alert\" (names an `alert_type`/condition like PPE, collision, fire) = stop a **subscription rule** → **Workflow D** (find via `GET /api/v1/realtime`, then the two-step stop/confirm protocol in `references/alert-subscriptions.md`; do **not** call `POST /generate`). A bare \"stop real-time alert / stop monitoring on &lt;sensor&gt;\" with **no** type qualifier = Workflow B.\n\nIf a prompt mixes workflows (\"start monitoring and send to Slack\"), ask one clarifying question to split execution order.\n\n### CV-mode refusal text for D and E intents\n\nWhen the deployed mode is CV verification and the user asks for an alert-subscription or Slack/notification intent, refuse with this message verbatim:\n\n> \"Alert subscriptions and Slack notifications are only supported in VLM real-time mode. Your current deployment is `<CV verification | not deployed>`. To use these features, redeploy with `/vss-deploy-profile -p alerts -m real-time` (note: switching tears down current CV monitoring).\"\n\nNo auto-redeploy. The user decides whether to switch modes.\n\n---\n\n## Prereq for Either Mode: Sensor Must Be in VIOS\n\nBoth modes require the camera registered in VIOS first (via the `vss-manage-video-io-storage` skill):\n\n- RTSP URL / IP camera → add it with `POST /sensor/add` (that skill's Section 6); record the `sensorId` / name.\n- Named existing sensor → confirm it appears in `GET /sensor/list` before proceeding.\n\nOn **CV**, adding the RTSP is the *entire* onboarding step (pipeline auto-picks it up). On **VLM**, it is a prerequisite to Workflow B.\n\n---\n\n## The Agent `/generate` Endpoint\n\nAll VLM-flow actions and all query actions go through the VSS Agent's natural-language endpoint:\n\n```bash\nAGENT=\"http://<AGENT_ENDPOINT>\"   # default http://localhost:8000 on the alerts profile\n\ncurl -s -X POST \"$AGENT/generate\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"input_message\": \"<natural-language request>\"}' | jq .\n```\n\n**Endpoint resolution:** use the agent endpoint from the active VSS deployment context. If unavailable, ask the user. Do not discover via filesystem.\n\n**Availability check:** `curl -sf --connect-timeout 5 \"$AGENT/docs\"`.\n\nDo not call the `rtvi-vlm` microservice endpoints directly — always go through the agent. The agent internally dispatches to `rtvi_vlm_alert`, `rtvi_prompt_gen`, and `video_analytics_mcp.get_incidents`.\n\n---\n\n## Workflow A — CV Mode (`-m verification` / `MODE=2d_cv`)\n\nCV alerts are **deployment-driven, not request-driven** — there is no agent\ncall to \"create\" one.\n\n1. Check if the sensor is in VIOS via `vss-manage-video-io-storage`'s `GET /sensor/list` (idempotent — don't blindly `POST /sensor/add`).\n2. If missing, onboard via that skill's `POST /sensor/add`. The CV pipeline auto-picks up the stream once registered and online.\n3. Confirm online: `curl -s \"http://<VST_ENDPOINT>/vst/api/v1/sensor/<sensorId>/status\" | jq .`\n4. Alerts land in Elasticsearch (Behavior Analytics → `alert-bridge` verification per `alert_type_config.json`). Query with **Workflow C**.\n\nA static-CV-pipeline alert on a VLM-only deployment is a mode mismatch — see the routing table above.\n\n---\n\n## Workflow B — VLM Real-time Monitoring (CV or VLM mode)\n\nGeneric start / stop intents through the VSS Agent for a named sensor\nwithout a detection condition (if a condition is present, route to\nWorkflow D). `rtvi-vlm` runs in both modes.\n\n```bash\n# start: input_message = \"Start real-time alert for sensor <id>\"\n# stop:  input_message = \"Stop real-time alert for sensor <id>\"\ncurl -s -X POST \"$AGENT/generate\" -H \"Content-Type: application/json\" \\\n  -d '{\"input_message\": \"<start|stop> real-time alert for sensor <id>\"}' | jq .\n```\n\nUnder the hood: `rtvi_prompt_gen` → `rtvi_vlm_alert action=\"start\"`.\nEvery chunk is captioned; a chunk whose VLM response contains `yes`/`true`\n(case-insensitive) publishes an incident to `mdx-vlm-incidents`. Prompts\nmust force a Yes/No answer. A static-CV-pipeline request on a VLM-only\ndeployment is a mode mismatch — see the routing table.\n\n---\n\n## Workflow D — Alert Subscriptions (VLM real-time mode only)\n\nCreate / list / delete persistent realtime alert rules on Alert Bridge.\nRoute here when the prompt has rule keywords (`rule`, `subscription`, a rule\nID) **or** when it pairs a specific sensor with a specific detection\ncondition (e.g. \"Set up a realtime alert on warehouse-dock-1 for PPE\nviolations\", \"Watch sensor entrance-1 for tailgating\", \"Stop rule\n496aebd1-…\").\n\n**Not here:** generic start/stop without a condition (→ Workflow B) or Slack\noperations (→ Workflow E).\n\nLoad and follow `references/alert-subscriptions.md` as the authoritative\nplaybook for subscription CRUD. VLM real-time mode only; refuse with the\ncanonical refusal text on CV.\n\n---\n\n## Workflow E — Slack Notifications (VLM real-time mode only)\n\nUse when the user **explicitly mentions Slack or the webhook relay** (start/stop webhook server, check status/health, send a test message, set Slack channel/token). The word `notify` alone is **not** enough.\n\n> **`alert-notify` (port 9090) ≠ `vss-alert-bridge` (`/api/v1/realtime`).**\n> Do NOT touch `vss-alert-bridge` for Slack ops.\n\nRoutes here: \"Set up Slack notifications\", \"Check if alert-notify is running\", \"Send a test alert to Slack\". Does **not** route here: \"Notify me when someone enters the zone\" (→ D/B), \"Alert and notify on my phone\" (ambiguous — ask).\n\nLoad and follow `references/alert-notify.md`. Code lives in `scripts/alert-notify/`. VLM real-time mode only.\n\n---\n\n## Workflow C — Query / List Alerts (works on either mode)\n\nBoth CV- and VLM-generated alerts land in Elasticsearch and are\nqueryable via the agent's `video_analytics_mcp.get_incidents` tool. POST\nnatural-language requests to `$AGENT/generate` — \"Show me recent alerts\nfor sensor X\", \"List confirmed alerts from the last hour\", \"Show\ncollision incidents from Camera_02 between `<ISO>` and `<ISO>`\".\n\n**Casual phrasings route here too.** Questions like \"Any alerts so far\ntoday?\", \"Any alerts today?\", \"What's been triggered?\", or \"Anything\ndetected lately?\" are incident queries — issue a `POST /generate` (e.g.\n`{\"input_message\": \"List alerts from today\"}`) and summarize the result.\n**Never answer these from memory and never reply \"no alerts\" without\nrunning the query.** A bare \"alerts\" question is *always* an incident\nlookup (Workflow C), not a subscription-rule listing (Workflow D).\n\n> **Do NOT list subscription rules for an incident query.** The **bare**\n> `GET /api/v1/realtime` (no `/incidents`) lists *rules* (Workflow D) and\n> is wrong for \"what happened\" — never call/probe it or load the Workflow\n> D playbook for an incident query.\n>\n> **Empty result is a valid answer.** If no incidents match (e.g. a\n> freshly deployed system with no activity yet), report that **none were\n> found / the count is 0** for the requested period and STOP — do not fall\n> back to listing rules or hunting other endpoints.\n\nFor\nricher / non-natural-language filtering (sensor-level, time-series,\ncounts) use the **`vss-query-analytics` skill** (VA-MCP on port 9901).\n\n### Verdict interpretation & CV verifier prompts (CV mode only)\n\nCV alerts carry a VLM verification verdict (`confirmed` / `rejected` /\n`unverified`); VLM real-time incidents have no separate verdict (the\ntrigger is itself a Yes/No VLM answer). CV-path verifier prompts are\ncustomizable via `alert_type_config.json` (restart `alert-bridge` to\napply). See `references/cv-verifier-prompts.md` for the verdict table,\nfield meanings, and the prompt-customization rules.\n\n---\n\n## Cross-Skill Links\n\n| Task | Skill |\n|---|---|\n| Deploy, redeploy, or switch alert mode | **`vss-deploy-profile`** — `-p alerts -m {verification,real-time}` |\n| Add an RTSP/IP camera, list sensors, snapshots, clips | **`vss-manage-video-io-storage`** (Section 6 for Add Sensor) |\n| Time-range incident / occupancy / PPE metrics from Elasticsearch | **`vss-query-analytics`** (VA-MCP :9901) |\n| Detailed incident report from an alert | **`vss-generate-video-report`** |\n| Subscriptions / Slack sub-workflows | `references/alert-subscriptions.md`, `references/alert-notify.md` (code in `scripts/alert-notify/`) |\n\n---\n\n## Gotchas\n\n- **`alert-notify` (port 9090) ≠ `vss-alert-bridge`.** Slack ops → Workflow E (`alert-notify`); never route Slack to `vss-alert-bridge`'s `/api/v1/realtime`.\n- **Workflow scope by mode:** A is CV-only; B and C work on either mode; D and E are VLM real-time only (refuse on CV with the canonical text).\n- **Don't use `vss-rtvi-vlm` as a mode signal** — it runs in both modes. Use `vss-behavior-analytics` (CV-only) or the `MODE` env var.\n- **A mode switch tears down the current deployment** — running VLM streams and un-persisted CV alert state are lost.\n- **Always go through `$AGENT/generate`** — never call `rtvi-vlm` directly. The VLM trigger is a `\"yes\"`/`\"true\"` token match (case-insensitive); `rtvi_prompt_gen` enforces the Yes/No pattern, so don't hand-craft prompts that break it.\n- **Sensor must already be in VIOS** for either mode (use `vss-manage-video-io-storage` for RTSP-only inputs).\n\nbump:1"}