Documentation Index
Fetch the complete documentation index at: https://visionagents.ai/llms.txt
Use this file to discover all available pages before exploring further.
Reference of every event the agent emits, with fields and import paths.
For an overview of how events are dispatched and patterns for using them, see the Event System Guide.
For most app logic, prefer agent.simple_response(..., interrupt=...), agent.say(..., interrupt=...), and agent.metrics over wiring up low-level events.
Base Event Structure
All events inherit from BaseEvent:
| Field | Type | Description |
|---|
type | str | Event type identifier (e.g. "agent.user_transcript") |
event_id | str | Unique UUID for this event instance |
timestamp | datetime | When the event was created (UTC) |
session_id | str | None | Current session identifier |
participant | Participant | None | Participant the event relates to, when applicable |
user_metadata | Any | None | Optional caller-supplied metadata |
Plugin-emitted events extend PluginBaseEvent, which adds two fields:
| Field | Type | Description |
|---|
plugin_name | str | None | Name of the plugin that emitted the event |
plugin_version | str | None | Version of the plugin |
Agent Lifecycle Events
High-level events emitted by the agent itself as a call progresses through user and agent turns.
Import: from vision_agents.core.agents.events import ...
UserTranscriptEvent
Emitted with the final user transcript that triggers an LLM turn. This is the event most apps should listen to for “what did the user say” — it fires in both classic STT and realtime modes.
from vision_agents.core.agents.events import UserTranscriptEvent
@agent.events.subscribe
async def on_user_transcript(event: UserTranscriptEvent):
print(f"User said: {event.text}")
| Field | Type | Description |
|---|
text | str | Final transcribed user text |
participant | Participant | None | Who spoke |
UserTurnStartedEvent
Emitted when the user starts speaking.
| Field | Type | Description |
|---|
participant | Participant | None | Who started speaking |
UserTurnEndedEvent
Emitted when the user stops speaking.
| Field | Type | Description |
|---|
participant | Participant | None | Who stopped speaking |
AgentTurnStartedEvent
Emitted when the agent starts speaking (first audio chunk leaving the pipeline). Carries only the BaseEvent fields.
AgentTurnEndedEvent
Emitted when the agent stops speaking. Use interrupted to tell barge-in from natural completion.
from vision_agents.core.agents.events import AgentTurnEndedEvent
@agent.events.subscribe
async def on_agent_turn_ended(event: AgentTurnEndedEvent):
if event.interrupted:
print("User barged in")
| Field | Type | Description |
|---|
interrupted | bool | True if the turn was cut short by a user interruption |
AgentJoinedCallEvent
Emitted after the agent has joined a call.
| Field | Type | Description |
|---|
call | Call | The call that was joined |
AgentLeftCallEvent
Emitted when the agent leaves a call.
| Field | Type | Description |
|---|
call | Call | The call that was left |
AgentFinishEvent
Emitted when agent.finish() has completed. Carries only the BaseEvent fields.
Edge / Call Events
Events emitted by the edge transport for participant and track activity on the call.
Import: from vision_agents.core.edge.events import ...
ParticipantJoinedEvent
Emitted when a participant (other than the agent) joins the call.
from vision_agents.core.edge.events import ParticipantJoinedEvent
@agent.events.subscribe
async def on_join(event: ParticipantJoinedEvent):
print(f"{event.participant.user_id} joined")
| Field | Type | Description |
|---|
participant | Participant | Joined participant |
call | Call | The call |
ParticipantLeftEvent
Emitted when a participant (other than the agent) leaves the call.
| Field | Type | Description |
|---|
participant | Participant | Participant that left |
call | Call | The call |
CallEndedEvent
Emitted when a call ends.
| Field | Type | Description |
|---|
call | Call | The call that ended |
TrackAddedEvent
Emitted when a track is added to the call.
| Field | Type | Description |
|---|
track_id | str | None | Track identifier |
track_type | TrackType | None | Track type (audio/video) |
TrackRemovedEvent
Emitted when a track is removed from the call.
| Field | Type | Description |
|---|
track_id | str | None | Track identifier |
track_type | TrackType | None | Track type (audio/video) |
AudioReceivedEvent
Emitted when audio is received from a participant. High-volume — silence it with agent.events.silent(AudioReceivedEvent) if you don’t need it.
| Field | Type | Description |
|---|
pcm_data | PcmData | None | Audio data |
LLM Events
Events from non-realtime LLM interactions.
Import: from vision_agents.core.llm.events import ...
LLMResponseCompletedEvent
Emitted when the LLM finishes a response.
from vision_agents.core.llm.events import LLMResponseCompletedEvent
@agent.events.subscribe
async def on_response(event: LLMResponseCompletedEvent):
print(f"Response: {event.text}")
print(f"Model: {event.model}")
print(f"Tokens: {event.input_tokens} in, {event.output_tokens} out")
print(f"Latency: {event.latency_ms}ms")
| Field | Type | Description |
|---|
text | str | Complete response text |
original | Any | Raw response from provider |
item_id | str | None | Response item identifier |
latency_ms | float | None | Total request-to-response time |
time_to_first_token_ms | float | None | Time to first token (streaming) |
input_tokens | int | None | Input/prompt tokens consumed |
output_tokens | int | None | Output tokens generated |
total_tokens | int | None | Total tokens used |
model | str | None | Model identifier |
LLMResponseChunkEvent
Emitted for each chunk during streaming responses.
| Field | Type | Description |
|---|
delta | str | None | Text delta for this chunk |
content_index | int | None | Index of content part |
item_id | str | None | Response item identifier |
output_index | int | None | Output index |
sequence_number | int | None | Sequence number |
is_first_chunk | bool | Whether this is the first chunk |
time_to_first_token_ms | float | None | Time to this first chunk |
LLMResponseFinalEvent
Emitted when a final LLM response is received.
| Field | Type | Description |
|---|
text | str | Full LLM response text |
model | str | None | Model identifier |
LLMErrorEvent
Emitted when a non-realtime LLM error occurs.
| Field | Type | Description |
|---|
error | Exception | None | The exception |
error_code | str | None | Error code |
context | str | None | Additional context |
request_id | str | None | Request identifier |
is_recoverable | bool | Whether the error is recoverable |
error_message | str | Property: human-readable error message |
Realtime LLM Events
Events specific to realtime LLM connections (e.g. OpenAI Realtime, Gemini Live).
Import: from vision_agents.core.llm.events import ...
RealtimeConnectedEvent
Emitted when a realtime connection is established.
| Field | Type | Description |
|---|
session_id | str | None | Session identifier |
session_config | dict[str, Any] | None | Session configuration |
capabilities | list[str] | None | Available capabilities |
RealtimeDisconnectedEvent
Emitted when the realtime connection closes.
| Field | Type | Description |
|---|
session_id | str | None | Session identifier |
reason | str | None | Disconnection reason |
clean | bool | Whether disconnect was clean |
For conversation content in a realtime session, subscribe to UserTranscriptEvent (see Agent Lifecycle Events) — it fires for both realtime and classic STT modes.
Events for function calling / tool use.
Import: from vision_agents.core.llm.events import ...
Emitted when tool execution begins.
from vision_agents.core.llm.events import ToolStartEvent
@agent.events.subscribe
async def on_tool_start(event: ToolStartEvent):
print(f"Calling {event.tool_name}")
print(f"Args: {event.arguments}")
| Field | Type | Description |
|---|
tool_name | str | Name of the tool being called |
arguments | dict | None | Arguments passed to the tool |
tool_call_id | str | None | Unique call identifier |
Emitted when tool execution completes.
from vision_agents.core.llm.events import ToolEndEvent
@agent.events.subscribe
async def on_tool_end(event: ToolEndEvent):
if event.success:
print(f"{event.tool_name} returned: {event.result}")
print(f"Took {event.execution_time_ms}ms")
else:
print(f"{event.tool_name} failed: {event.error}")
| Field | Type | Description |
|---|
tool_name | str | Name of the tool |
success | bool | Whether execution succeeded |
result | Any | Return value (if success) |
error | str | None | Error message (if failed) |
tool_call_id | str | None | Unique call identifier |
execution_time_ms | float | None | Execution duration |
STT Events
Connection-state and error events from the speech-to-text plugin. Transcripts themselves surface as UserTranscriptEvent (see Agent Lifecycle Events).
Import: from vision_agents.core.stt.events import ...
STTConnectedEvent
Emitted when an STT connection is established. Carries only the PluginBaseEvent fields.
STTDisconnectedEvent
Emitted when an STT connection is closed.
| Field | Type | Description |
|---|
reason | str | None | Disconnection reason |
clean | bool | Whether disconnect was clean |
STTErrorEvent
Emitted when STT encounters an error.
| Field | Type | Description |
|---|
error | Exception | None | The exception that occurred |
error_code | str | None | Error code identifier |
context | str | None | Additional context |
error_message | str | Property: human-readable error message |
TTS Events
Events from speech synthesis.
Import: from vision_agents.core.tts.events import ...
TTSSynthesisStartEvent
Emitted when TTS synthesis begins.
| Field | Type | Description |
|---|
text | str | None | Text being synthesized |
synthesis_id | str | Unique ID for this synthesis |
model_name | str | None | TTS model name |
voice_id | str | None | Voice identifier |
estimated_duration_ms | float | None | Estimated audio duration |
TTSSynthesisCompleteEvent
Emitted when TTS synthesis finishes.
from vision_agents.core.tts.events import TTSSynthesisCompleteEvent
@agent.events.subscribe
async def on_complete(event: TTSSynthesisCompleteEvent):
print(f"Synthesis took {event.synthesis_time_ms}ms")
print(f"Audio duration: {event.audio_duration_ms}ms")
| Field | Type | Description |
|---|
synthesis_id | str | None | Unique ID for this synthesis |
text | str | None | Text that was synthesized |
total_audio_bytes | int | Total bytes of audio |
synthesis_time_ms | float | Processing time |
audio_duration_ms | float | None | Resulting audio duration |
chunk_count | int | Number of chunks produced |
real_time_factor | float | None | Synthesis speed vs real-time |
TTSConnectedEvent
Emitted when a TTS connection is established. Carries only the PluginBaseEvent fields.
TTSDisconnectedEvent
Emitted when a TTS connection is closed.
| Field | Type | Description |
|---|
reason | str | None | Disconnection reason |
clean | bool | Whether disconnect was clean |
TTSErrorEvent
Emitted when TTS encounters an error.
| Field | Type | Description |
|---|
error | Exception | None | The exception |
error_code | str | None | Error code |
context | str | None | Additional context |
error_message | str | Property: human-readable error message |
Video Processor Events
Vision plugins (Roboflow, Ultralytics, Huggingface, etc.) emit subclasses of VideoProcessorDetectionEvent whenever they finish processing a frame.
Import: from vision_agents.core.events import VideoProcessorDetectionEvent
VideoProcessorDetectionEvent
Base class for detection events from any video processor plugin. Plugins extend it with their own fields (detected objects, bounding boxes, raw provider output).
| Field | Type | Description |
|---|
model_id | str | None | Identifier of the model used |
inference_time_ms | float | None | Time taken for inference |
detection_count | int | Number of objects detected |
To subscribe, import the plugin-specific subclass (for example roboflow.DetectionCompletedEvent). See Create your own plugin for the conventions plugin events follow.
This event is used by MetricsCollector to record video processing metrics. See Telemetry for details.
ExceptionEvent
Wraps any unhandled exception raised by a subscriber. The event system catches handler failures and re-emits them as ExceptionEvent so that other handlers and the agent itself keep running. Subscribe if you want a single place to log handler errors.
| Field | Type | Description |
|---|
exc | Exception | The exception that was raised |
handler | Callable | The handler function that failed |
Subscribing to Events
All events can be subscribed to using the @agent.events.subscribe decorator:
@agent.events.subscribe
async def my_handler(event: EventType):
# Handle event
pass
Subscribe to multiple event types using union types:
@agent.events.subscribe
async def my_handler(event: UserTranscriptEvent | LLMResponseCompletedEvent):
print(event)
Event handlers must be async functions. Non-async handlers raise RuntimeError at subscribe time.
See the Event System Guide for the dispatch model (fire-and-forget, fanout, error isolation) and the patterns that go with it.