agentsclimarketplace

Nvidia video search and summarization rt vlm

Skill autohandai/community-skills/nvidia-video-search-and-summarization-rt-vlm

A collection of curated, useful, and safe skills for Autohand Code CLI Agent

Install
npx -y skills add autohandai/community-skills --skill nvidia-video-search-and-summarization-rt-vlm

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 9 stars9 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

'Use this skill when working with the RTVI VLM or RT-VLM microservice API on VSS 3.1. Generate dense captions and alerts for stored video files and live RTSP streams via `/v1/generate_captions_alerts`; upload media via `/v1/files`; add and remove live streams with `/v1/streams/add` and `/v1/streams/delete/{stream_id}`; call OpenAI-compatible `/v1/chat/completions`; consume Kafka caption, incident, and error topics; or debug rtvi-vlm responses. For deployment, read `references/deploy-rt-vlm-service.md` first.

The file declares its own license as Apache-2.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

16.6 KB, ~4.5k tokens by cl100k_base, as published. Nobody here has run it

RTVI VLM Usage API (VSS 3.1)

RTVI VLM is NVIDIA's real-time vision-language microservice: decode video (file or RTSP) → segment into chunks → run a VLM (cosmos-reason1, cosmos-reason2, or any OpenAI-compatible model) → stream dense captions back over SSE/HTTP and publish captions + incident alerts + errors to Kafka. Use this skill whenever you need to hit any /v1/... endpoint on the VSS 3.1 rtvi-vlm microservice: caption generation, file upload, live-stream management, health checks, NIM-compatible chat completions, Prometheus metrics. API reference: https://docs.nvidia.com/vss/latest/real-time-vlm-api.html.

Setup

export BASE_URL="http://localhost:8000"     # RTVI VLM host:port — matches $RTVI_VLM_PORT in compose
export API_KEY="$NGC_API_KEY"               # Bearer token (NGC key works if the service was deployed with NGC auth)

Every request below uses Authorization: Bearer $API_KEY. Health endpoints (/v1/health/*, /v1/ready, /v1/live, /v1/startup) typically work without auth.

Smoke test before use:

curl -fsS "$BASE_URL/v1/health/ready" && curl -fsS "$BASE_URL/v1/models" | jq

Quick Start — dense captions from a local video

# 1. Upload the video, capture its file id
FILE_ID=$(curl -fsS -X POST "$BASE_URL/v1/files" \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@/path/to/warehouse.mp4" \
  -F "purpose=vision" \
  -F "media_type=video" | jq -r '.id')

# 2. Generate captions + alerts (SSE stream of chunked responses)
curl -N -X POST "$BASE_URL/v1/generate_captions_alerts" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"id\": \"$FILE_ID\",
    \"prompt\": \"Write a concise dense caption for each 10-second segment of this warehouse video.\",
    \"model\": \"cosmos-reason1\",
    \"chunk_duration\": 10,
    \"stream\": true
  }"

Endpoints

Captions

Generate VLM captions and alerts for videos and live streams.

POST /v1/generate_captions_alerts — Generate VLM captions (and alerts) for video/stream

Required:

FieldTypeDescription
idstring | arrayUUID of a previously-uploaded file, or id of an active live stream. Accepts a list of ids for batch
promptstringUser prompt to the VLM (e.g. dense-caption instruction)
modelstringModel name — see GET /v1/models

Key optional fields:

FieldTypeDefaultDescription
system_promptstringSystem prompt; use <think></think><answer></answer> tags to enable reasoning on Cosmos Reason
enable_reasoningbooleanfalseTurn on reasoning for Cosmos Reason models
enable_audiobooleanfalseTranscribe audio (via Riva) and fold into captions
chunk_durationintegerSegment video into N-second chunks (0 = no chunking)
chunk_overlap_durationinteger0Overlap between consecutive chunks
num_frames_per_second_or_fixed_frames_chunknumberFPS (if use_fps_for_chunking=true) or fixed frames per chunk
use_fps_for_chunkingbooleanfalseInterpret above as FPS vs. fixed-frame count
vlm_input_width / vlm_input_heightintResize frames before inference (0 = native)
media_infoobject{"start_offset_ms": ..., "end_offset_ms": ...} to process a slice of a file (not live streams)
streambooleanfalseSSE: emit per-chunk caption deltas as data: events (recommended for long videos)
max_tokens / temperature / top_p / top_k / seed / ignore_eosStandard sampling controls
response_formatobjectQuery response format object
mm_processor_kwargsobjectExtra kwargs for the multimodal processor (e.g. size, shortest/longest edge)
curl -N -X POST "$BASE_URL/v1/generate_captions_alerts" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "prompt": "Dense-caption this warehouse video, one sentence per 10s chunk.",
    "model": "cosmos-reason1",
    "chunk_duration": 10,
    "stream": true
  }'

Response (200, SSE when stream=true): each event payload has start_ts, end_ts, content, and a terminal {"status": "completed"} event. Response (200, non-stream): { "id", "object": "caption", "choices": [{...}], "usage": {...} }.

DELETE /v1/generate_captions_alerts/{stream_id} — Stop caption generation for a live stream

Stops inference while leaving the stream registered. Pair with DELETE /v1/streams/delete/{stream_id} to also un-register the RTSP source.

curl -X DELETE "$BASE_URL/v1/generate_captions_alerts/$STREAM_ID" -H "Authorization: Bearer $API_KEY"

Files

Upload and manage media files consumed by /v1/generate_captions_alerts.

POST /v1/files — Upload a media file (multipart)

curl -X POST "$BASE_URL/v1/files" -H "Authorization: Bearer $API_KEY" \
  -F "file=@./video.mp4" -F "purpose=vision" -F "media_type=video"

Response: { "id", "object": "file", "bytes", "created_at", "filename", "purpose" }.

GET /v1/files?purpose=vision — List uploaded files

GET /v1/files/{file_id} — File metadata

GET /v1/files/{file_id}/content — Download original file content

DELETE /v1/files/{file_id} — Delete file (releases asset storage)

Live Stream

RTSP stream lifecycle.

POST /v1/streams/add — Register one or more RTSP streams

Required per stream: liveStreamUrl (must start with rtsp://), description. Optional: username, password, sensor_name, and placement metadata (place_name, place_type, place_lat, place_lon, place_alt, place_coordinate_x, place_coordinate_y).

STREAM_ID=$(curl -fsS -X POST "$BASE_URL/v1/streams/add" \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d '{"streams":[{"liveStreamUrl":"rtsp://cam:8554/live","description":"warehouse cam 1"}]}' \
  | jq -r '.results[0].id')

GET /v1/streams/get-stream-info — List active streams

DELETE /v1/streams/delete/{stream_id} — Remove a single stream

DELETE /v1/streams/delete-batch — Remove many ({"stream_ids":[...]})

NIM Compatible

OpenAI-compatible endpoints for interop with OpenAI/NVIDIA-API clients.

POST /v1/chat/completions — OpenAI-compatible chat (text + multimodal)

Required: messages, model. Text-only requests omit id / video_url / image_url.

curl -X POST "$BASE_URL/v1/chat/completions" -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"cosmos-reason1","messages":[{"role":"user","content":"Summarize this scene."}]}'

POST /v1/completions — OpenAI-compatible legacy completions

GET /v1/version{ "version": "3.1.0-..." }

GET /v1/license — license text

GET /v1/manifest — NIM manifest

GET /v1/health/live · GET /v1/health/ready — NIM-style probes

Models · Metadata · Metrics · Health Check

GET /v1/models — List loaded VLMs: { "data": [{ "id", "object": "model", "owned_by" }] }

GET /v1/metadata — Service metadata (build, release, image tag)

GET /v1/metrics — Prometheus metrics (plain text)

GET /v1/ready · GET /v1/live · GET /v1/startup — Kubernetes-style probes


Common Workflows

The four scenarios from the VSS 3.1 RT-VLM Usage Skill requirements.

1. Dense captions from a stored video file

# Upload → capture file id → generate captions (SSE stream)
FILE_ID=$(curl -fsS -X POST "$BASE_URL/v1/files" \
  -H "Authorization: Bearer $API_KEY" \
  -F "[email protected]" -F "purpose=vision" -F "media_type=video" | jq -r '.id')

curl -N -X POST "$BASE_URL/v1/generate_captions_alerts" \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d "{
    \"id\": \"$FILE_ID\",
    \"prompt\": \"Describe warehouse events in 1 sentence per 10s chunk.\",
    \"model\": \"cosmos-reason1\",
    \"chunk_duration\": 10,
    \"stream\": true
  }"

# When done, free storage:
curl -X DELETE "$BASE_URL/v1/files/$FILE_ID" -H "Authorization: Bearer $API_KEY"

2. Dense captions from an RTSP live stream

# Register the stream
STREAM_ID=$(curl -fsS -X POST "$BASE_URL/v1/streams/add" \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d '{"streams":[{"liveStreamUrl":"rtsp://10.0.0.5:8554/warehouse","description":"warehouse cam"}]}' \
  | jq -r '.results[0].id')

# Start continuous caption generation (runs until stream stops or DELETE)
curl -N -X POST "$BASE_URL/v1/generate_captions_alerts" \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d "{
    \"id\": \"$STREAM_ID\",
    \"prompt\": \"Describe each event; start each sentence with a timestamp.\",
    \"model\": \"cosmos-reason1\",
    \"chunk_duration\": 10,
    \"num_frames_per_second_or_fixed_frames_chunk\": 2,
    \"use_fps_for_chunking\": true,
    \"stream\": true
  }" &

# Tear down when finished:
curl -X DELETE "$BASE_URL/v1/generate_captions_alerts/$STREAM_ID" -H "Authorization: Bearer $API_KEY"
curl -X DELETE "$BASE_URL/v1/streams/delete/$STREAM_ID"  -H "Authorization: Bearer $API_KEY"

Pre-req: the container was started with:

RTVI_VLM_KAFKA_ENABLED=true

RTVI_VLM_KAFKA_TOPIC=vision-llm-messages

RTVI_VLM_KAFKA_INCIDENT_TOPIC=vision-llm-events-incidents

RTVI_VLM_ERROR_MESSAGE_TOPIC=vision-llm-errors

HOST_IP=<kafka-host>

STREAM_ID=$(curl -fsS -X POST "$BASE_URL/v1/streams/add"
-H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json"
-d '{"streams":[{"liveStreamUrl":"rtsp://10.0.0.5:8554/warehouse","description":"warehouse cam"}]}'
| jq -r '.results[0].id')

curl -N -X POST "$BASE_URL/v1/generate_captions_alerts"
-H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json"
-d "{ "id": "$STREAM_ID", "prompt": "You are a warehouse monitoring system. Describe the scene in one sentence, then on a new line output exactly:\nAnomaly Detected: Yes/No\nReason: <one sentence>\nFlag an anomaly if any worker is missing a hard hat or high-vis vest.", "system_prompt": "Answer the user's question correctly in yes or no.", "model": "cosmos-reason2", "chunk_duration": 60, "chunk_overlap_duration": 10, "stream": true }"


**Consume alerts from Kafka** (when using the VSS foundational Kafka container).
Kafka values are NvSchema protobuf payloads, so use `print.value=false` for a
clean validation pass that shows timestamp, key, and headers without dumping
binary payload bytes:
```bash
docker exec mdx-kafka kafka-console-consumer \
  --bootstrap-server 127.0.0.1:9092 \
  --topic vision-llm-events-incidents \
  --from-beginning \
  --timeout-ms 5000 \
  --max-messages 10 \
  --property print.timestamp=true \
  --property print.key=true \
  --property print.headers=true \
  --property print.value=false

If Kafka is not running in the VSS mdx-kafka container, use the Kafka CLI from the host running the broker:

kafka-console-consumer \
  --bootstrap-server "$HOST_IP:9092" \
  --topic vision-llm-events-incidents \
  --from-beginning \
  --timeout-ms 5000 \
  --max-messages 10 \
  --property print.timestamp=true \
  --property print.key=true \
  --property print.headers=true \
  --property print.value=false

Incident protobuf (ext.proto :: Incident) key fields: sensorId, timestamp, end, objectIds, frameIds, place, analyticsModule, category, isAnomaly (true for alerts), llm (nested VisionLLM), info map including triggerPhrase, verdict, requestId, chunkIdx, streamId, alertCategory (if the deployment supports the alert_category query field — post-3.1).

3. Kafka workflows (alerts + message bus)

Dense captioning with alerts on an RTSP stream and the HTTP-vs-Kafka response model are documented in references/kafka-workflows.md.

Error Reference

CodeMeaningCommon Cause
400Bad RequestMissing required field (id, prompt, model); unsupported media_type; unknown model name
401UnauthorizedMissing/invalid Authorization: Bearer $API_KEY — or wrong key format (expect nvapi-...)
404Not Foundfile_id deleted / stream_id not registered / wrong endpoint path (note: {stream_id} is required on DELETE /v1/streams/delete/{stream_id})
413Payload Too LargeUploaded file exceeds server MAX_FILE_SIZE; increase or pre-chunk the video
422Unprocessable EntityPydantic schema violation — e.g. use_fps_for_chunking=true without num_frames_per_second_or_fixed_frames_chunk; stream ids supplied to a file-only field like media_info
429Rate LimitedToo many concurrent streams — raise VLM_BATCH_SIZE or spread across instances
500Server ErrorVLM inference exception (OOM, model unavailable) — check docker logs rtvi-vlm-*
503Service BusyStartup not complete (model still downloading) or upstream NIM dependency unhealthy

Gotchas

  • 3.1 GA endpoint is /v1/generate_captions_alerts, not /v1/generate_captions. The rename lands in a post-3.1 build. For VSS 3.1 releases (rtvi_vlm/26.01.x26.02.3), always use the _alerts suffix. https://docs.nvidia.com/vss/latest/real-time-vlm-api.html is the canonical reference.
  • No URL-based input in 3.1 GA — the url/media_type/creation_time fields were added post-3.1. You must upload via POST /v1/files first and then pass the returned id.
  • Alert trigger = the tokens "yes" or "true" in the VLM response (case-insensitive). There is no per-request alert flag. Design prompts with an explicit Anomaly Detected: Yes/No line and set system_prompt to constrain the model to Yes/No answers (per the VSS docs). Every chunk is published to KAFKA_TOPIC; matched chunks additionally go to KAFKA_INCIDENT_TOPIC with isAnomaly=true, info["triggerPhrase"] set to the matched tokens, and info["verdict"]="confirmed".
  • No alert_category query field in the 3.1 OpenAPI spec. The Kafka incident topic defaults incident.category = "vlm-alert" on 3.1. Post-3.1 builds expose an optional alert_category request field to override incident.category.
  • Kafka topics are server-side config, not per-request. The KAFKA_* env vars (via compose RTVI_VLM_KAFKA_* rewrites) are fixed at container start — clients can't override topics on a per-request basis. Kafka publish is additive to the HTTP response, never a replacement.
  • stream=true returns Server-Sent Events, not chunked JSON. Use curl -N (no buffering). Each event is data: {"content": "...", "start_ts": ..., "end_ts": ...}\n\n, terminated by data: {"status":"completed"}\n\n. Without stream=true the server buffers until the full video is processed — fine for short clips (<1 min), avoid for live streams.
  • chunk_duration=0 disables chunking — the entire video is sent to the VLM as one shot. Only meaningful for short clips; long videos will OOM or exceed max_model_len.
  • Default frame budget caps at VLLM_MM_PROCESSOR_VIDEO_NUM_FRAMES (256). Requesting FPS that implies >256 frames per chunk is silently capped; drop FPS or shorten chunk_duration to stay within budget.
  • enable_reasoning requires a Cosmos Reason model. Passing it with Qwen3-VL or other non-reasoning models is a no-op.
  • /v1/metrics requires auth, unlike /v1/health/*. Prometheus scrapers need the Bearer token.
  • File upload is multipart, not JSON. Use -F file=@path -F purpose=vision -F media_type=video; a -d body returns 422.
  • Live-stream lifecycle requires two deletes to fully tear down: DELETE /v1/generate_captions_alerts/{stream_id} stops inference; DELETE /v1/streams/delete/{stream_id} un-registers the stream. Skipping the second leaks RTSP connection resources.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.