Vss Summarize Video logo

Vss Summarize Video

OrganizationPopular
NVIDIA-AI-Blueprints
vss-summarize-video

Use when summarizing a recorded video through HITL-gated LVS, with an explicitly approved VLM fallback. Not for reports, archive search, or live RTSP captioning.

Overview

PublisherNVIDIA-AI-Blueprints
Repositoryvideo-search-and-summarization
Skill namevss-summarize-video
Stars
1.9K
Forks
393
Bundled files
14
LicenseApache-2.0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 14 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by NVIDIA-AI-Blueprints on GitHub. Read the source before you install it.

Installation

Install the Vss Summarize Video AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/NVIDIA-AI-Blueprints/video-search-and-summarization.git /tmp/video-search-and-summarization
mkdir -p .claude/skills
cp -r /tmp/video-search-and-summarization/skills/operations/vss-summarize-video .claude/skills/vss-summarize-video
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Vss Summarize Video in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Vss Summarize Video on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Vss Summarize Video is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

VSS Summarize Video

Instructions

  • Execute the five workflow stages below in order.
  • Run API commands yourself; do not tell the user to run them.
  • Use the required references at their named decision points.

Examples

Runnable scenarios live under evals/. The command implementations are in references/end-to-end-example.md.

When to Use

Use when summarizing a recorded video through HITL-gated LVS, to produce one polished narrative summary with timestamped events when LVS is available.

Do not use this skill for:

  • Live RTSP captioning: use vss-deploy-dense-captioning.
  • Incident or alert-window reports: use vss-generate-video-report Mode B.
  • Archive search: use vss-search-archive.

Required References

Load these files only as directed:

Core Invariants

  • Route by LVS readiness, never by video duration.
  • HTTP 200 from /v1/ready selects LVS. Empty response bodies do not mean unavailable.
  • Once LVS is selected, do not call a VLM /v1/chat/completions endpoint.
  • Issue exactly one vss summarize run per user summarize request. One run is one POST /v1/summarize. Never retry, hedge, broaden events, or run a second backend automatically.
  • Endpoints come from the deployment vss configure recorded. Never pass an endpoint, index, or model flag the caller did not name, and never replace a failed run with hand-rolled curl against /v1/summarize.
  • Save the complete command and its stdout. Diagnose failures from those files, the run's own exit code, service logs, and non-mutating GET requests.
  • Render video_summary and every returned event verbatim. Do not paraphrase, truncate descriptions, add fields, or fabricate id.
  • Direct VLM fallback requires explicit user approval unless the original request pre-authorized it.

Prerequisites

  • VSS lvs profile reachable either on Docker ($HOST_IP:38111) or through the public Ingress at ${VSS_PUBLIC_URL}/lvs.
  • curl and jq on the agent host.
  • Network reachability from the LVS service to the final VIOS clip URL (Docker: from vss-lvs; Kubernetes: deploy must mint a URL the LVS pod can fetch).
  • A checkout containing libs/vss and host uv, for vss summarize run.
  • One recorded deployment origin. Configure it once, before Stage 4:
bash
VSS_REPO_ROOT="${VSS_REPO_ROOT:-$HOME/video-search-and-summarization}"
test -f "${VSS_REPO_ROOT}/libs/vss/pyproject.toml" || {
  echo "VSS checkout not found at ${VSS_REPO_ROOT}; set VSS_REPO_ROOT explicitly" >&2
  exit 1
}
VSS=(uv run --project "${VSS_REPO_ROOT}/libs/vss" vss)
cd "${VSS_REPO_ROOT}" && "${VSS[@]}" summarize run --help >/dev/null || exit 1
# Compose publishes the ingress on :7777; Kubernetes uses VSS_PUBLIC_URL.
VSS_ORIGIN="${VSS_PUBLIC_URL:-http://${HOST_IP:-localhost}:7777}"
"${VSS[@]}" configure --base-url "${VSS_ORIGIN%/}" || exit 1

libs/vss is the library's own workspace, so no extras and no --no-dev are needed — the agent stack is not in it. Configure against the ingress origin, never :38111 — that LVS container port exposes no Elasticsearch, so a deployment recorded from it cannot persist.

The vss-build-vision-ai skill can deploy the profile. A remote fallback VLM must be able to fetch the clip URL; it generally cannot fetch localhost or private addresses.

Limitations

  • Direct VLM fallback cannot target LVS scenarios or events and is lower quality.
  • Private VIOS URLs may be unreachable from remote VLM endpoints.
  • Each user request permits one vss summarize run, with no automatic retry.
  • Persistence needs a routed Elasticsearch. A deployment without one summarizes and reports the result unpersisted rather than failing the job.
  • Both edges are configured to wait an hour, matching the CLI's own default, so a long summarization is not cut short by a 504 that would be recorded as a failed job. An Ingress the deployment overrides shorter still caps the wait.
  • Stock LVS Helm Ingress does not publish LVS /models, LVS /openapi.json, /recommended_config, or /metrics — those remain Docker :38111 only.

Endpoint resolution (Kubernetes vs Docker)

Resolve endpoints once before probing. Follow ../vss-build-vision-ai/references/deployment_resolution.md.

bash
# Prefer VSS_PUBLIC_URL; accept legacy VSS_ENDPOINT as the same public origin.
if [ -z "${VSS_PUBLIC_URL:-}" ] && [ -n "${VSS_ENDPOINT:-}" ]; then
  VSS_PUBLIC_URL="${VSS_ENDPOINT}"
fi

if [ -n "${VSS_PUBLIC_URL:-}" ]; then
  DEPLOYMENT_KIND="kubernetes"
  VSS_PUBLIC_URL="${VSS_PUBLIC_URL%/}"
  # Force public origin — ignore leftover Docker LVS_BACKEND_URL / VLM_* env.
  # The /lvs mount, not the origin — skill appends /v1/ready and /v1/summarize,
  # and the gateway strips /lvs before the backend sees them.
  LVS_BACKEND_URL="${VSS_PUBLIC_URL}/lvs"
  VIDEO_SUMMARIZATION_URL="${LVS_BACKEND_URL}"
  VSS_VIOS_URL="${VSS_PUBLIC_URL}/vst"
  VST_API_BASE="${VSS_VIOS_URL}/api/v1"
  # RT-VLM is at its own mount; /v1/models and /v1/chat/completions hang off it.
  VLM="${VSS_PUBLIC_URL}/rtvi-vlm"
else
  DEPLOYMENT_KIND="docker"
  LVS_BACKEND_URL="${LVS_BACKEND_URL:-http://${HOST_IP:-localhost}:38111}"
  VIDEO_SUMMARIZATION_URL="${LVS_BACKEND_URL}"
  VSS_VIOS_URL="http://${HOST_IP:-localhost}:30888/vst"
  VST_API_BASE="${VSS_VIOS_URL}/api/v1"
  VLM="${VLM_BASE_URL:-${RTVI_VLM_BASE_URL:-http://${HOST_IP:-localhost}:8018}}"
  VLM="${VLM%/v1}"
fi

On Kubernetes, do not use kubectl port-forward, Service DNS, NodePorts, docker exec, or docker inspect. Do not append /v1 to LVS_BACKEND_URL. Ignore Docker-derived LVS_BACKEND_URL / VLM_BASE_URL / RTVI_VLM_BASE_URL when VSS_PUBLIC_URL is set. Do not treat public /openapi.json as the LVS schema (that path is Agent on stock Ingress).

Routing

ServiceBase URL
LVS${VIDEO_SUMMARIZATION_URL} (K8s: ${VSS_PUBLIC_URL}; Docker: http://${HOST_IP}:38111)
VLM / RT-VLM${VLM} then append /v1/... (K8s: the /rtvi-vlm mount; Docker: :8018)
VIOS${VST_API_BASE}

Strip a trailing /v1 from the VLM base because this skill appends it. Do not scan ports or inspect configuration files to guess endpoints.

Probe LVS /v1/ready using the loop in the end-to-end reference. Readiness is the HTTP status only: retry 503 warmup responses for about 30 seconds, and do not inspect the body.

LVS resultAction
HTTP 200Use LVS for every video duration.
Anything elseReport that LVS must be deployed, or ask before using VLM fallback.

If LVS is unavailable, ask:

The VSS lvs profile isn't reachable (${VSS_PUBLIC_URL:-$HOST_IP:38111}). Shall I deploy it now using the /vss-build-vision-ai stock Video Summarization workflow? Reply no to stop here; I can use the lower-quality VLM-only fallback only if you explicitly ask for it.

  • Deployment approved or pre-authorized: invoke vss-build-vision-ai, re-probe, and continue only after LVS returns 200.
  • Deployment declined: ask separately whether to use VLM fallback. Stop unless the user approves it.
  • Fallback pre-authorized: use the fallback without another prompt.
  • Non-interactive run: the original task is the only approval source. If it pre-authorizes neither deployment nor fallback, report blocked and stop.

Recorded Video Workflow

Stage 1: Select the Backend

Load the end-to-end and CLI references. Run the LVS readiness probe before preparing the clip. Also probe VLM /v1/models so an approved fallback can be validated, but do not infer against it while LVS is ready.

The summarization model needs no discovery: vss configure recorded the id LVS reports serving, and vss summarize run defaults to it on both Docker and Kubernetes. Pass --model only when the caller named one, and read the recorded value from vss configure show when it has to be reported.

Discover a model id by hand only for an approved VLM fallback, which does not run through the CLI:

  • Docker: honor ${VLM_NAME} only if it matches an id from LVS GET /models; otherwise use the sole advertised LVS id.
  • Kubernetes: prefer ${VLM_NAME} when set; otherwise take the sole id from GET ${LVS_BACKEND_URL}/models (LVS) or GET ${VLM}/v1/models (RT-VLM). If multiple ids exist and no valid preference selects one, report them and stop.

A non-200 LVS readiness result after warmup is the only unavailability signal. An empty summary, empty events, missing optional fields, or empty readiness stdout must not trigger fallback.

Stage 2: Prepare the Video Through VIOS

Execute VIOS API operations directly as part of this workflow; do not invoke a separate skill. Follow Prepare the video through VIOS in the end-to-end reference (uses ${VST_API_BASE}).

  1. List sensors and reuse the exact requested recording when present.
  2. If absent and the exact local file is available, upload it through the VIOS file API. For uploaded or sample media without a requested timestamp, use 2025-01-01T00:00:00.000Z so timeline resolution is deterministic.
  3. Poll the returned stream's timelines and obtain the complete minimum start and maximum end time.
  4. Generate a fresh temporary MP4 URL for that full interval with audio disabled. Pass that minted URL to --url as returned (after stripping a doubled http:// scheme if present). Do not rewrite it for browser Ingress paths before the summarize run.
  5. If LVS was selected, verify one-byte reachability:
    • Docker: docker exec vss-lvs Python range probe in the reference.
    • Kubernetes: bounded Range GET of the minted URL from the agent host (no docker exec / kubectl exec). Deploy must mint a URL the LVS pod can fetch.

Require the exact recording, full timeline, and fresh clip URL before continuing. When the source file is available, compare VIOS timeline duration with source duration. An upload response or byte probe proves reachability, not complete media readiness.

If preparation fails, stop and report the missing prerequisite. Do not choose an arbitrary /tmp video, alternate recording, local HTTP server, NvStreamer, or RTSP source unless the user explicitly requested that source.

Do not use the vss-lvs container's lightweight curl shim for reachability; it can write the entire video into tool output. Use the one-byte Python probe on Docker.

Stage 3: Collect LVS Settings

When LVS is selected, load the HITL reference and collect scenario, events, and optional objects_of_interest before the summarize run.

When the caller explicitly says to run autonomously without prompting and asks for defaults or supplies no settings, use these values verbatim:

text
scenario="activity monitoring"
events=["notable activity"]

This is the only HITL bypass. Do not infer defaults from filenames or sensor names. Mention defaults in the final response and offer a separate rerun with specific settings.

Stage 4: Submit Once Through the CLI

Load the CLI reference. vss summarize run issues the summarize request on both Docker and Kubernetes, and persists only when static memory policy enables it. Do not build a /v1/summarize payload by hand, and do not fetch /openapi.json to construct one — the CLI owns the request shape, vss configure owns the endpoint, and vss configure memory owns persistence.

Use the invocation in the end-to-end reference. It passes the fresh VIOS URL from Stage 2, the exact HITL values from Stage 3, --chunk-duration 10, and --seed 1; repeat --event per event and add --object-of-interest only when the caller provided objects. Pass no endpoint flag.

Do not pass --persist or --memory-index; those per-request controls do not exist. The standard workflow also does not pass --no-persist, so the operator's configured persistence default applies. When persistence is enabled, the record needs two values:

  • --video-id, required alongside --url. Use the recording's VIOS sensor id — from sensor/list, or from the sensorId an upload returns — never the stream id. It becomes the record's sensor, which is what list --sensor-id and time-windowed recall key on. Without --video-id the run exits 2 before summarizing rather than after.
  • --creation-time, the media's absolute start. LVS reports event times as offsets into the clip unless this anchors them, and unified memory stores instants — so without it the events cannot be written and the run degrades to exit 6. For uploaded sample media use the same 2025-01-01T00:00:00.000Z Stage 2 uploaded with.

Do not pass --num-frames-per-chunk in the standard workflow. RT-VLM owns frame sampling; unset fields are absent from the request, so the deployment's own default applies.

The final line of stdout is one JSON object naming the job. Read that line and the exit code; the prose on stderr is a diagnostic, not the result. A call refused before a job exists prints no marker at all and stderr is the whole result — check stdout is non-empty before parsing it. Emptiness, not the exit code, is what says whether a job was created.

exitmeaningaction
0summarized; persistence followed configured policypresent the result and report persisted truthfully
2a flag the CLI refused, before anything was submittedfix the call, then run once
2LVS rejected the request it was sent; the marker names a job closed as failedreport the failure with that job_id
3LVS unreachable or returned 5xxreport it with the marker's job_id
4deployment configuration is missing, or an explicit Markdown note lacks static sink configurationno job, no marker — run the remediation command from stderr
6summary produced; Elasticsearch or Markdown cache write failedpresent the summary; report ES and Markdown outcomes separately
7timed outreconcile with vss summarize get --job-id; do not re-run

Exits 6 and 7 both mean the summarization already happened. Never repeat the run to obtain a different view of it, and never repeat it for diagnosis — a second run requires a separate user request. The exit 2 that carries a marker is the same story earlier: the request reached LVS and came back refused, so the one submission this request had is spent and a corrected call belongs to a new request. Once a job exists, every outcome names its job_id; use it rather than re-running. A call refused before a job exists names nothing, which is why empty stdout is the test.

The completion marker's persisted boolean is the authoritative Elasticsearch outcome. The result body includes persist only when persistence was attempted and reports its index and event count; optional Markdown status is separate under memory_note. record says what the job_id is worth to a later read: closed, absent when policy skipped persistence, or stale when a submitted record could not be closed. Do not read the record back to confirm it, and never read Elasticsearch directly — recalling memory is a separate skill's job. The one read that belongs here is reconciling an exit 7, whose outcome is genuinely unknown until vss summarize get --job-id <job_id> answers.

If video_summary and events are empty, inspect the same payload's summary.usage.total_chunks_processed. A positive integer confirms processing; zero or missing means processing was not confirmed. Do not claim "no detections."

VLM Fallback for Stages 3-4

Use the fallback command in the end-to-end reference only when LVS remained unavailable after warmup and the user explicitly approved fallback. Do not run LVS HITL, and never use fallback to repair or replace an LVS response.

Before the result, include:

Note: Input video <name> is <N>s long. The video summarization service is not deployed, so this summary was produced by the VLM alone with a generic default prompt. Deploy the lvs profile for higher-quality summaries with scenario/events targeting.

If the VLM cannot fetch the VIOS URL, report that blocker instead of sending an inference request.

Stage 5: Present the Result

Start with exactly one header:

text
Summary of <video_name> (<duration>)

Use Ns below 60 seconds and Mm Ss otherwise.

For LVS, the CLI nests the service's own envelope under summary: parse the JSON string in summary.choices[0].message.content while preserving summary.usage. Render video_summary verbatim, followed by every event in service order. Preserve every returned field and the full description; use a per-event list if a table would truncate text.

Close with the job's identity: the job_id, the completion marker's persisted value, and any separate memory_note result. An absent persist object with persisted=false means static policy chose stdout-only execution, not a failure.

For VLM, render choices[0].message.content verbatim. For Cosmos output, omit the <think>...</think> block and show the answer. Do not add emojis or re-voice either backend's content.

Troubleshooting

SymptomAction
/v1/ready remains 503Treat LVS as unavailable after the warmup loop.
Readiness stdout is emptyUse the HTTP status; a 200 body may be empty.
Summary and events are emptyInspect saved summary.usage.total_chunks_processed; do not retry.
vss not foundVerify VSS_REPO_ROOT points at the checkout; never install globally.
Run exits 4Follow stderr: configure the deployment, or configure the Markdown sink requested explicitly.
Run exits 6A post-operation memory write failed. Present the summary and separate ES/Markdown status; do not re-run.
Run exits 7Timed out. vss summarize get --job-id <id>; do not re-run.
VLM returns <think>Remove reasoning through </think> when rendering.
K8s /openapi.json looks like AgentExpected — do not use it as LVS schema.
K8s /models 404 / HTMLProbing the bare origin — use ${LVS_BACKEND_URL}/models or ${VLM}/v1/models.

Use the debugging reference for deeper diagnostics and the deployment reference for logs or configuration. The LVS image is a multi-arch manifest, so LVS_TAG=3.3.0-rc2 is the x86/Jetson Thor default; use 3.3.0-rc2-sbsa on SBSA/DGX Spark/Grace. RT-VLM likewise needs a host-matched tag (3.3.0-26.08.2 on x86/Jetson Thor, 3.3.0-26.08.2-sbsa on SBSA/DGX Spark/Grace).

Direct API and Service Operations

For direct API questions such as models, readiness, recommended configuration, metrics, schemas, or 422 responses, use the API reference instead of the recorded-video workflow. /lvs is a Prefix mount, so everything LVS serves is public under it on Kubernetes — /lvs/v1/ready, /lvs/v1/summarize, /lvs/models, /lvs/metrics — where the previous Exact-path Ingress published only readiness and summarize. For deployment, restart, teardown, backend selection, or service logs, prefer vss-build-vision-ai and use the deployment reference.

Cross-reference

  • vss-build-vision-ai: deploy the lvs profile.
  • vss-manage-video-io-storage: general VIOS administration outside this ordered workflow.
  • vss-search-archive: search archived video.
  • vss-query-analytics: query stored incidents and events.
  • vss-generate-video-report: Mode A delegates here when LVS /v1/ready is 200.

bump:3

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Vss Summarize Video AI skill do?

Use when summarizing a recorded video through HITL-gated LVS, with an explicitly approved VLM fallback. Not for reports, archive search, or live RTSP captioning.

Why use Vss Summarize Video on TypingMind?

Because you install it once and use it with any model. Vss Summarize Video is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Vss Summarize Video in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/NVIDIA-AI-Blueprints/video-search-and-summarization/tree/develop/skills/operations/vss-summarize-video. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Vss Summarize Video?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Vss Summarize Video?

As many as you like. As long as a model supports skills, you can use Vss Summarize Video with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Vss Summarize Video AI skill free?

Yes. It is published on GitHub by NVIDIA-AI-Blueprints under the Apache-2.0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇