Skip to main content
Build custom plugins to connect Vision Agents to any AI provider. Plugins wrap provider APIs with a consistent interface, enabling seamless integration with the agent framework.
Vision Agents uses Stream Video for real-time WebRTC transport by default. External WebRTC transports are supported as well. Most AI providers offer free tiers to get started.

Before You Build

Many providers support OpenAI-compatible APIs. Before writing a custom plugin, check if you can use existing plugins with a custom base_url:
Build a custom plugin when:
  • The provider uses a proprietary API format
  • You need provider-specific features not exposed through Chat Completions
  • The provider requires custom authentication or connection handling

Plugin Categories

The TTS and Realtime base classes also provide a built-in interrupt() method and epoch property for barge-in handling. You do not need to override these — the Agent calls interrupt() automatically when a user interruption is detected.

Quickstart Template

Create your plugin in plugins/acme/:

pyproject.toml

init.py

stt.py

Base Class Interfaces

STT

TTS

LLM

VLM (Video Language Model)

VLM plugins process video frames alongside text. The framework provides VideoForwarder for frame management.
Key VLM concepts:
  • VideoForwarder: Manages frame buffering and distributes to multiple handlers at different FPS
  • Shared forwarder: Multiple plugins can share one forwarder to avoid duplicate frame processing
  • Frame buffer: Store recent frames for context (configurable size)
  • FPS control: Request frames at the rate your model needs (1-30 fps typical)

Realtime (Speech-to-Speech)

Audio Utilities

Vision Agents provides utilities to simplify audio handling in STT and TTS plugins.

PcmData Resampling

Most STT providers expect 16kHz mono audio. Use the built-in resampling:

TTS Output Format

The TTS base class handles output format conversion automatically:

AudioQueue for Buffering

For plugins that need to buffer audio (e.g., accumulating before processing):

Function Calling

To support function calling in your LLM plugin, override these methods:
The base class handles:
  • Function registration via @llm.register_function()
  • Tool execution with _execute_tools() (concurrent, with timeout)
  • Tool call deduplication by (name, arguments)
  • Multi-round tool calling (configurable via max_tool_rounds)

Event Emission

Base classes provide helper methods for common events: For custom events:

Gotchas & Best Practices

Connection Lifecycle

Owned vs shared clients: Track whether your plugin created the client or received it:
Connection timeouts: Always use timeouts for connection setup:

Cleanup Order

Follow this order in close() to prevent deadlocks:

Error Handling

Temporary errors (network timeouts, transient API errors): Emit and continue:
Permanent errors (invalid API key, unsupported model): Raise directly:

Threading for Blocking Operations

Some SDKs have blocking calls. Use a thread pool:

Concurrency Control

Prevent concurrent processing when your provider doesn’t support it:

Sample Rate Requirements

Reconnection with Backoff

For WebSocket-based plugins:

Testing

Contribution Checklist

  1. Implement required abstract methods
  2. Add tests with reasonable coverage
  3. Pass uv run pre-commit run --all-files
  4. Add README.md documenting usage and events
  5. Open a PR to the Vision Agents repo

Next Steps

Event System

Learn about events

Function Calling

Add tool support