The Problem
Real-time video AI agents are hard to build because the pipeline spans video ingestion, object detection, speech, and an LLM, and each hop adds latency. Most frameworks treat video as an afterthought or lock you into one model provider. This repo solves that by giving you a Python core that wires video/audio tracks, vision processors (YOLO, Roboflow), and pluggable LLM/STT/TTS providers together over Stream's low-latency edge network, with a claimed sub-30ms audio/video path.
What This Does
agents-core/ is the framework: vision_agents/core/agents/agent_launcher.py owns the agent lifecycle, agents.py the turn loop, runner/runner.py serves agents over HTTP, and edge/sfu_events.py is the generated protocol layer for Stream's SFU. Provider integrations live in plugins/ (openai, gemini, cartesia, deepgram, elevenlabs, ultralytics). Seven working examples in examples/ show the pattern end to end, from a golf coach (YOLO pose + Gemini realtime) to a security camera that posts "WANTED" posters.
How It Is Wired
Execution starts at start in agent_launcher.py:147 (reaches 44 functions, nothing else calls it) or run in runner.py:83. The example entry point plugins/cartesia/example/main.py calls join_call, which reaches 137 functions — the widest reach in the repo. The shortest path to an external effect is start -> warmup -> _warmup_agent, which hits a model via agent.llm.warmup; the join path reaches the network through simple_response via client.post in 2 hops. Across the repo, 54 functions call a model, 27 make network calls, 24 touch the filesystem, 1 hits a database.
The blast-radius hubs: edge/sfu_events.py (241 functions, called from 12 files), agent_launcher.py (called from 36 files), and agents.py (67 functions, called from 25). agents.py sits in a 34-module circular-import cycle with instability 0.93, so changing it ripples widely. The most-called functions are wait (47 call sites), simple_response (31), and upsert_message (26) — these are the seams to change carefully.
How To Use It
Setup uses uv (examples ship uv.lock; agents-core/pyproject.toml is the package manifest). Copy .env.example to .env with your provider keys, then run an example:
uv sync
cp .env.example .env
uv run examples/02_golf_coach_example/golf_coach_example.py
Deployment options exist in examples/07_deploy_example/ (Dockerfile, docker-compose, Helm chart). The README documents the Agent(...) constructor pattern with edge, llm, processors, tts, stt arguments.
Real-World Use
A security-camera agent from examples/05_security_camera_example/: a SecurityCameraProcessor runs YOLOv11 at 5 fps to detect package theft, gemini.LLM("gemini-2.5-flash-lite") reasons about frames, and deepgram.STT()/elevenlabs.TTS() handle voice. The agent posts generated posters to X automatically — a vision pipeline, not a chatbot.
Code Health & Issues
Static analysis (not opinion) found 121 issues: 58 high (27 deep-nesting sites, 27 circular-import members, duplicated code blocks — 939 repeated 6-line blocks across 108 files, likely the generated protobuf layer), 61 medium, 2 low. The SDLC audit found 7 medium, 1 low: un-pinned GITHUB_TOKEN permissions in .github/workflows/ci.yml, no Dependabot, unpinned base image (python:3.13-slim), no dependency vulnerability scan, 32MB GIFs in assets/ (no LFS), persist-credentials left on in release.yml, and no non-root USER in the deploy Dockerfile. Tests and CI exist (106 test files, GitHub Actions).
The Bottom Line
A credible, production-oriented framework for real-time vision agents with strong provider coverage and working deployment examples. The circular imports and generated-code duplication make agents.py and sfu_events.py costly to modify, and CI hygiene needs tightening. Use it if you want a working vision-agent stack fast; expect to refactor if you need deep customization of the core.