AI provider fields
NovaVMS v5 ships a single VLM provider (Gemini 3.1 Flash-Lite via Vertex AI) plus a local Python AI Runtime sidecar running three CPU models (MobileCLIP2-B, YOLO26n, InsightFace buffalo_l). This page documents the environment-variable contract and the canonical model identifiers, plus the reference checksums used by the AI maintenance wizard.
Environment variables
Loaded from cloud/.env (development) or cloud/.env.prod (production) by the cloud server.
| Variable | Default | Required | Purpose |
|---|---|---|---|
VERTEX_AI_PROJECT | unset | yes for production | Vertex AI GCP project. When set, Vertex AI Backend is used. |
VERTEX_AI_LOCATION | unset | yes when VERTEX_AI_PROJECT set | Vertex AI region, e.g. us-central1 or global. |
GOOGLE_CLOUD_PROJECT | unset | optional | SDK-native alias for VERTEX_AI_PROJECT. |
GOOGLE_CLOUD_LOCATION | unset | optional | SDK-native alias for VERTEX_AI_LOCATION. |
GOOGLE_APPLICATION_CREDENTIALS | unset | yes for Vertex AI | Absolute path to the Vertex AI service-account JSON used for Application Default Credentials. |
GEMINI_MODEL | gemini-3.1-flash-lite | no | Override the default VLM / judge model. |
GEMINI_API_KEY | unset | only for dev / AI Studio fallback | API-key auth when VERTEX_AI_PROJECT is unset. AI Studio is geo-blocked from many production VPS regions; production should always use Vertex AI. |
AI_RUNTIME_BASE_URL | http://127.0.0.1:8091 | no | URL of the local AI Runtime sidecar. |
AI_RUNTIME_MAX_ACTIVE_REQUESTS | 1 | no | Concurrent ai-runtime calls. Increase only after benchmark mode confirms CPU headroom. |
AI_RUNTIME_ORT_THREADS | 4 | no | ONNX Runtime CPU thread count. |
AI_RUNTIME_OPENVINO_THREADS | 4 | no | OpenVINO inference engine thread count. |
The legacy variables AI_PROVIDER, AI_DEFAULT_PROVIDER, AI_DEFAULT_MODEL, AI_ENABLED, AI_FRAME_COUNT_NORMAL, OPENAI_API_KEY, QWEN_API_KEY, and OLLAMA_BASE_URL are NOT consumed by v5. They were retired in the L12 cutover or superseded by the per-organization frame settings.
Model identifiers
The cloud client verifies the AI Runtime response carries these exact identifiers (cloud/internal/ai/runtime_client.go:16-21):
| Stage | Identifier | Source artifact |
|---|---|---|
| Visual embedding | mobileclip2_b | Apple MobileCLIP2-B ONNX export |
| Object detection | yolo26n_openvino | Ultralytics YOLO26n exported to OpenVINO IR |
| Face detection + recognition | insightface_buffalo_l | InsightFace buffalo_l ONNX bundle |
| VLM (non-blocking) | gemini-3.1-flash-lite (default; GEMINI_MODEL override) | Vertex AI |
A response whose model_versions block does not exactly match the first three identifiers is rejected by the cloud client — the pipeline retries via the queue. This is the production safeguard against silent model swaps.
Reference checksums
cloud/config/reference_checksums.json is the source of truth. The AI maintenance wizard’s checksum preflight (GET /admin/ai-maintenance/preflight/checksums, handler at cloud/internal/ai/maintenance_handler.go:409) reads this file via h.configDir and compares SHA256s against the actual model files on disk. (ai-runtime/reference_checksums.json is a sibling reference used by the Python sidecar at runtime startup, but the cloud preflight reads its own copy under cloud/config/.)
| Artifact | SHA256 |
|---|---|
| MobileCLIP2-B image encoder | 144b1344f5f01f08af8be1077f0db5eec95bf0fd1e349c1e9ca6102724448486 |
| YOLO26n OpenVINO XML | 1f6a35fb0008ebcfe3e28847b7c8b5db8f904d13b85ce349b6cb44f40e56faa2 |
| InsightFace buffalo_l | 5838f7fe053675b1c7a08b633df49e7af5495cee0493c7dcf6697200b85b5b91 |
Five JPEG fixtures (person, dog, known face, low-light, motion blur) are checksummed separately for the eval harness — see ai-runtime/reference_checksums.json.
Embedding contract
| Property | Value |
|---|---|
| Visual frame embedding dimension | 512 |
| Visual frame embedding normalization | L2 (norm must be in [0.99, 1.01]) |
| Face embedding dimension | 512 |
| Face embedding normalization | L2 |
| Tag text embedding dimension | 512 |
| Tag text embedding normalization | L2 |
Frame embeddings and face embeddings are different vector spaces even though they share a dimension. Face vectors live in event_faces.embedding; frame vectors live in frame_embeddings.embedding. They are never compared across tables (v5 PRD §P3).
Frame extraction defaults
| Setting | v5 default | Constant |
|---|---|---|
| Frame count (uniform mode) | 8 | DefaultFrameCountV5 |
short_edge_px (historical name; maximum width) | 2560 | DefaultShortEdgePxV5 |
| JPEG quality | 85 | DefaultJPEGQualityV5 |
| Effective max frames cap | 8 | DefaultMaxFramesV5 |
Source: cloud/internal/ai/frame_extractor.go:33-51.
Detection knob defaults
These mirror the current database defaults and CHECK constraints through migrations 000091 and 000092.
| Knob | Default | Range |
|---|---|---|
jpeg_quality | 85 | 50–100 |
short_edge_px (applied as maximum width) | 2560 | 320–3840 |
runtime_active_requests | 1 | 1–8 |
max_frames | 8 | 1–16 |
uniform_frame_count | 8 | 1–16 |
frame_extraction_mode | uniform | uniform | scene |
yolo_confidence | 0.35 | 0.05–0.95 |
face_in_person_min | 0.80 | 0.50–1.00 |
face_min_size_px | 64 | 16–256 |
thinking_level_default | minimal | minimal | low |
ai_v5_intelligence_enabled | true | bool |
Related
- Configure AI for your organization — the
/admin/aihow-to - Why NovaVMS uses one AI stack with v5 evidence-first design — architecture rationale
- Canonical AI tags — compiled/search vocabulary and YOLO-derived event tags
- Event has no AI tags — v5 failure paths