Built-in Channels¶
ConferenceChannel has a page of its own: Conference.
SMSChannel ¶
Create an SMS transport channel.
RCSChannel ¶
Create an RCS (Rich Communication Services) transport channel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel_id
|
str
|
Unique identifier for this channel. |
required |
provider
|
Any
|
RCS provider instance (e.g., TwilioRCSProvider). |
None
|
fallback
|
bool
|
If True (default), allow SMS fallback when RCS unavailable. |
True
|
Returns:
| Type | Description |
|---|---|
TransportChannel
|
A TransportChannel configured for RCS messaging. |
EmailChannel ¶
Create an Email transport channel.
AIChannel ¶
AIChannel(channel_id, provider, system_prompt=None, temperature=0.7, max_tokens=None, max_context_events=50, tool_handler=None, tools=None, max_tool_rounds=200, tool_loop_timeout_seconds=300.0, tool_loop_warn_after=50, max_empty_retries=1, thinking_coalesce_ms=80.0, thinking_coalesce_chars=256, retry_policy=None, fallback_provider=None, skills=None, skills_in_prompt=True, script_executor=None, sandbox=None, external_tool_handler=None, human_input_handler=None, memory=None, tool_policy=None, thinking_budget=None, enable_thinking=None, reasoning_effort=None, evict_threshold_tokens=5000, enable_planning=False, config_provider=None, tool_search=None, tool_search_pinned=None, tool_search_threshold=DEFAULT_TOOL_SEARCH_THRESHOLD, tool_search_threshold_pct=DEFAULT_TOOL_SEARCH_THRESHOLD_PCT, tool_search_miss_hint=None)
Bases: AIStreamingMixin, AIGenerationMixin, AIToolsMixin, AIContextMixin, AIResilienceMixin, AIToolPolicyMixin, AISteeringMixin, AIEventsMixin, Channel
AI intelligence channel that generates responses using an AI provider.
tool_handler
property
writable
¶
The current tool handler (may be wrapped by orchestration).
active_turns
property
¶
Turns being produced right now.
A tool loop — streamed or not — registers itself in _active_loops
for steering, from the start of its generation to its finally; a
text-only stream has no loop context to register and is counted on
its own. Both spans start when the turn is consumed: a streaming
output handed back by on_event and not yet iterated reads 0, a
window the caller's own wait has to cover. close() tears the
provider down under whichever of them is running, so a caller
retiring this object waits for zero first.
recent_events_window
property
¶
Recent-events need = this channel's memory provider's window.
set_system_prompt ¶
Replace the system prompt for subsequent turns.
AIChannel rebuilds its request context from self._system_prompt
at the start of every turn, so the new prompt takes effect on the next
turn with no reconnect and no loss of memory or tool state — the
supported way to swap personas/attitudes mid-conversation.
Note: when a config_provider is set the system prompt is resolved
fresh per turn, so this value is overridden on the next turn.
active_skill_names ¶
Skills whose instructions are binding in room_id right now.
Runtime state, not the catalogue: these are the activations recorded for
this conversation, which is exactly what the system prompt already
carries under "Active skill instructions". A host rendering its own
manifest (skills_in_prompt=False) cannot otherwise tell an available
skill from an active one, and pushing the model to load what is already
binding costs a tool round and contradicts the rules in front of it.
on_event
async
¶
React to an event by generating an AI response.
Skips events from this channel to prevent self-loops. When the provider supports streaming or structured streaming: - With tools: uses the streaming tool loop that executes tool calls between generation rounds while yielding text deltas progressively. - Without tools: returns a plain streaming response. Otherwise falls back to the non-streaming generate path.
deliver
async
¶
Intelligence channels are not called via deliver by the router.
ACPChannel ¶
ACPChannel(channel_id, command=None, *, transport=None, cwd, additional_directories=None, env=None, inherit_env=None, mcp_servers=None, authentication_method=None, external_tool_handler=None, room_history=_DEFAULT_ROOM_HISTORY, context_contributor=None)
Bases: ACPConnectionMixin, ACPEventsMixin, Channel
Connect a RoomKit Room to an external ACP coding agent.
One connection to the agent is opened lazily for the channel and one ACP session is created per Room. Prompts are serialized inside each session, while different Rooms progress concurrently over the same connection.
Pass command for the usual case — the agent is spawned here as a
subprocess and spoken to over its stdio. Pass transport instead when
the agent runs somewhere this process cannot spawn it (another machine,
behind a relay); see :class:~roomkit.channels.acp_transport.ACPTransport.
Exactly one of the two is required.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel_id
|
str
|
RoomKit channel identifier. |
required |
command
|
Sequence[str] | None
|
Executable and arguments used to start the ACP agent. No shell
is involved. Mutually exclusive with |
None
|
transport
|
ACPTransport | None
|
How to reach an agent this channel does not spawn. Mutually
exclusive with |
None
|
cwd
|
str | Path
|
Absolute working directory declared to the ACP session — and, for a spawned agent, the process's own directory. With a custom transport it names a directory on the agent's machine. |
required |
additional_directories
|
Sequence[str | Path] | None
|
Additional absolute directories exposed in the ACP session declaration. |
None
|
env
|
Mapping[str, str] | None
|
Environment variables added to the SDK's restricted inherited environment. Spawned agents only. |
None
|
inherit_env
|
Sequence[str] | None
|
Names of parent-process environment variables to forward
to the agent. The ACP SDK strips the environment down to
|
None
|
mcp_servers
|
Sequence[Any] | None
|
ACP MCP-server descriptors accepted by the official SDK. |
None
|
authentication_method
|
str | None
|
Optional ACP authentication method identifier. |
None
|
external_tool_handler
|
ExternalToolHandler | None
|
Permission policy and tool observability bridge. Without a handler, every permission request is rejected. |
None
|
room_history
|
int
|
How many room messages the agent catches up on when it is
asked to act, having been skipped while it was not (RFC §19.3.2).
An ACP session holds its history in the agent's process, so a room
where two agents are addressed in turn would otherwise leave each
one with a private thread and no way to know it. |
_DEFAULT_ROOM_HISTORY
|
context_contributor
|
ACPContextContributor | None
|
What the host adds to a turn's prompt that the agent cannot go and fetch — member memories, a document corpus, an organisation's rules. Awaited once per solicited turn with the room's context and the triggering event; the blocks it returns open the prompt, ahead of the catch-up and the request. Non-empty blocks can supply the prompt for an event without text, such as a host-managed attachment. A turn with neither text nor blocks is skipped. One that raises is logged and the turn goes without it. Turn-scoped context only. An ACP session keeps what it was already
told, so a block that never changes is paid for again every turn;
what is stable belongs to the agent's own configuration
( Nothing here is bounded. RoomKit does not truncate the blocks — it knows neither their unit nor the agent's tokenizer, and the model can change mid-session — and does not bound how long the contributor takes. Both budgets are the host's, and a slow contributor delays the broadcast for the whole room, not just for this agent. Nor can RoomKit filter what the blocks carry: the catch-up is filtered per reader because it is made of room events (RFC §7.5 rule 8), and these are not. |
None
|
active_turns
property
¶
Turns in flight: registered by _prompt_stream when the prompt
goes out, dropped when its stream closes. The whole of the turn as
the consumer sees it, not only while the agent is answering.
recent_events_window
property
¶
Room tail this channel reads — the catch-up window (RFC §19.3.2).
The framework sizes RoomContext.recent_events to the largest window
any bound channel declares, under a floor it keeps for hooks (50
events, while one is registered). So a room_history under that
floor reads a tail that was loaded anyway, one above it grows the tail
to match, and on a room with no hook the declaration is what loads the
tail at all: declaring the window is what keeps the two in step.
session_config ¶
Current ACP session config values for room_id, keyed by config id.
Agents publish their tunables through this one list — model,
mode, effort, vendor switches. Empty until the room's session
exists (sessions open on the first prompt).
Tracks what the agent announces. A switch made inside the agent
with its own slash command may not be announced at all — the ACP
bridge for Claude Code relays /model output as plain text and
sends no config update — so drive changes through
:meth:set_config_option when the value must stay observable.
config_options ¶
The agent's session tunables for room_id, as ACP describes them.
Full descriptors — id, name, current value, available choices — for
surfaces that let a user pick one (a model picker). Empty until the
session exists. :meth:session_config is the values-only shortcut.
set_config_option
async
¶
Set one session config option — set_config_option(room, "model", "opus").
Returns the full config mapping the agent reports back, so the caller sees the value it landed on (agents resolve aliases) plus any option the change invalidated. Opens the room's session if the first prompt has not yet done so, which connects to the agent.
on_event
async
¶
Create a lazy ACP prompt stream for a Room event.
close_session
async
¶
Close and forget one Room's ACP session.
Forget is the whole of it: every map keyed by the session, and the room's turn lock once no session is left behind it, is dropped here. A long-lived channel cycling sessions (one per conversation, one per reconnect) would otherwise carry every dead session's config options until the channel itself closed.
close
async
¶
Cancel turns, close sessions, and close the transport.
Shutdown is bounded: the graceful ACP round trips share
_SHUTDOWN_TIMEOUT, and the transport teardown runs even when
they time out, fail, or the caller is cancelled mid-close (a second
Ctrl-C landing on close_session). An agent that has stopped
answering must not outlive — or hang — the process that started it.
WebSocketChannel ¶
Bases: Channel
WebSocket transport channel with connection registry.
Args: channel_id: Channel identifier. send_timeout: Seconds a single send may take before the connection is treated as failing. Broadcast runs under the room lock and is unbounded by design (RFC §10.1), so an unbounded send would let one unresponsive socket freeze the room.
supports_streaming_delivery
property
¶
Whether any connected client supports streaming text delivery.
register_connection ¶
Register a WebSocket connection and subscribe it to a room.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
connection_id
|
str
|
Unique connection identifier. |
required |
send_fn
|
SendFn
|
Callback for delivering complete events. |
required |
room_id
|
str
|
The room this connection is for. Required: a channel
instance can be attached to several rooms, and without this the
channel has no way to tell which of its sockets belongs to the
room it is delivering — it would have to send everything to
everyone. Use :meth: |
required |
stream_send_fn
|
StreamSendFn | None
|
Optional callback for delivering streaming messages.
When provided, this connection receives progressive text delivery
via the |
None
|
subscribe ¶
Also deliver room_id's events to an existing connection.
For the client that holds several conversations open on one socket.
unregister_connection ¶
Unregister a WebSocket connection and drop its subscriptions.
supports_streaming_delivery_for ¶
Whether any client in this room speaks the streaming protocol.
The channel-wide property answers for every socket the channel holds, which is the wrong question once connections are scoped: a room whose clients are all non-streaming would otherwise take the streaming path and fall back at the end, having set up a stream nobody reads.
deliver_stream
async
¶
Deliver a streaming response with interleaved events to clients.
The stream yields str for text deltas and RoomEvent for
persisted events (text segments, tool calls). Streaming-capable
connections receive:
stream_start— streaming beginsstream_chunk— text delta (drives the live bubble)event— persisted event (tool call, text segment)stream_end— streaming complete
Non-streaming connections receive all persisted events via
the regular send_fn.
VoiceChannel ¶
VoiceChannel(channel_id, *, stt=None, tts=None, backend=None, pipeline=None, streaming=True, enable_barge_in=True, barge_in_threshold_ms=200, interruption=None, batch_mode=False, voice_map=None, max_audio_frames_per_second=None, tts_filter=None, bridge=None, recording=None, close_providers=True, stt_language_lock=None)
Bases: VoiceSTTMixin, VoiceTTSMixin, VoiceHooksMixin, VoiceTurnMixin, VoicePipelineMixin, FrameworkAwareChannel, Channel
Real-time voice communication channel.
Supports three STT modes:
- VAD mode (default): VAD segments speech, streaming STT during speech
with batch fallback on SPEECH_END.
- Continuous mode: No VAD + streaming STT provider — all audio streamed,
provider handles endpointing.
- Batch mode (batch_mode=True): No VAD, audio accumulates post-pipeline.
Caller controls when to transcribe via :meth:flush_stt. Useful for
dictation, voicemail, and audio-file transcription with offline models.
When a VoiceBackend and AudioPipelineConfig are configured, the channel: - Registers for raw audio frames from the backend via on_audio_received - Routes frames through the AudioPipeline inbound chain: [Resampler] -> [Recorder] -> [AEC] -> [AGC] -> [Denoiser] -> VAD -> [Diarization] + [DTMF] - Fires hooks based on pipeline events (speech, silence, DTMF, recording, etc.) - Transcribes speech using the STT provider - Optionally evaluates turn completion via TurnDetector - Synthesizes AI responses using TTS and streams to the client
When no pipeline is configured, the channel operates without VAD — the backend must handle speech detection externally.
The STT language can be chosen per session at runtime with
:meth:set_stt_language; it applies from the session's next stream.
stt_language_lock installs an
:class:~roomkit.voice.stt.language.STTLanguageLock that starts every
session detecting (Deepgram multi), pins it to the language the
speaker uses, and releases it when the results stop fitting.
supports_streaming_delivery
property
¶
Whether this channel can accept streaming text delivery.
set_bridge_filter ¶
Set a synchronous filter for bridged audio frames.
The filter runs in the audio callback thread before each frame
is forwarded. It receives (source_session, frame) and
returns the frame (possibly modified) or None to drop it.
This is the synchronous equivalent of BEFORE_BRIDGE_AUDIO
— use it for fast operations like per-session muting or gain.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
BridgeFrameFilter | None
|
Filter function, or |
required |
set_framework ¶
Set the framework reference for inbound routing.
Called automatically when the channel is registered with RoomKit.
on_trace ¶
Register a trace observer and bridge to the backend.
bind_session ¶
Bind a voice session to a room for message routing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
VoiceSession
|
The voice session to bind. |
required |
room_id
|
str
|
Target room ID. |
required |
binding
|
ChannelBinding
|
Channel binding descriptor. |
required |
backend
|
VoiceBackend | None
|
Override backend for the bridge. When bridging sessions from different transports (e.g. SIP + WebRTC), pass the session's own backend so the bridge sends audio through the correct transport. |
None
|
connect_session
async
¶
Accept a voice session via process_inbound.
Delegates to :meth:bind_session which handles pipeline
activation and framework events.
disconnect_session
async
¶
Clean up a voice session on remote disconnect.
update_binding ¶
Update cached bindings for all sessions in a room.
Called by the framework after mute/unmute/set_access so the
audio gate in _on_audio_received sees the new state.
add_media_tap ¶
Register a tap on processed inbound audio frames (for room recording).
Delegates to the pipeline's on_processed_frame callback list.
add_outbound_media_tap ¶
Register a tap on outbound TTS audio (for room recording).
The callback receives (session, pcm_data, sample_rate) for
every outbound chunk after pipeline processing.
update_voice_map ¶
Merge entries into the per-agent voice map.
Called by :meth:ConversationPipeline.install to auto-wire
voice IDs from :class:Agent instances.
set_stt_language ¶
Choose the STT language for one session, from its next stream on.
None returns the session to the provider's configured language.
A streaming STT fixes its language when the stream opens, so the
choice lands on the next stream:
- VAD mode — the next utterance. A stream that is open stays open; restarting it would cut the utterance in progress in two.
- Continuous mode — right away: the current cycle is ended and the loop reconnects with the new language. Audio arriving in the gap is kept, as on every reconnect.
- Batch mode — the next :meth:
flush_stt.
The typical caller is an ON_TRANSCRIPTION hook reading
event.language from a detecting stream (Deepgram multi) and
pinning the session to what it heard;
:class:~roomkit.voice.stt.language.STTLanguageLock packages that
loop.
Raises:
| Type | Description |
|---|---|
RuntimeError
|
No STT provider, or one whose
|
get_stt_language ¶
The STT language chosen for a session, None for the provider's default.
send_dtmf ¶
Send a DTMF digit to the remote party via the voice backend.
The digit is sent as an RFC 4733 telephone-event (out-of-band).
Requires a backend with DTMF_SIGNALING capability (SIP, RTP).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
VoiceSession
|
The active voice session. |
required |
digit
|
str
|
DTMF digit ('0'-'9', '*', '#', 'A'-'D'). |
required |
duration_ms
|
int
|
Tone duration in milliseconds (default 160). |
160
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If no backend is configured or session is ended. |
ValueError
|
If digit or duration_ms is invalid. |
interrupt
async
¶
Interrupt ongoing TTS playback for a session.
interrupt_all
async
¶
Interrupt all active TTS playback in a room.
Returns:
| Type | Description |
|---|---|
int
|
Number of sessions that were interrupted. |
wait_playback_done
async
¶
Wait until active TTS playback finishes for all sessions in room_id.
Returns immediately if no playback is in progress. Uses per-session
events that are set when send_audio() returns (before the echo
drain delay), so callers don't wait for the 2-second drain window.
RealtimeVoiceChannel ¶
RealtimeVoiceChannel(channel_id, *, provider, transport, owns_transport=True, system_prompt=None, voice=None, tools=None, temperature=None, input_sample_rate=16000, output_sample_rate=24000, transport_sample_rate=None, emit_transcription_events=True, tool_handler=None, mute_on_tool_call=False, tool_result_max_length=16384, pipeline=None, recording=None, skills=None, script_executor=None, skill_delivery_mode=None, tool_recovery=True, tool_search=None, tool_search_pinned=None, tool_search_threshold=20)
Bases: RealtimeToolRecoveryMixin, RealtimeToolsMixin, RealtimeTranscriptionMixin, RealtimeSpeechMixin, RealtimeAudioMixin, RealtimeResponseMixin, VoicePipelineMixin, FrameworkAwareChannel, Channel
Real-time voice channel using speech-to-speech AI providers.
Wraps APIs like OpenAI Realtime and Gemini Live as a first-class RoomKit channel. Audio flows directly between the user's browser and the provider; transcriptions are emitted into the Room so other channels (supervisor dashboards, logging) see the conversation.
Category is TRANSPORT so that:
- on_event() receives broadcasts (for text injection from supervisors)
- deliver() is called but returns empty (customer is on voice)
Example
from roomkit.voice.realtime.mock import MockRealtimeProvider, MockRealtimeTransport
provider = MockRealtimeProvider() transport = MockRealtimeTransport()
channel = RealtimeVoiceChannel( "realtime-1", provider=provider, transport=transport, system_prompt="You are a helpful agent.", ) kit.register_channel(channel)
Initialize realtime voice channel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel_id
|
str
|
Unique channel identifier. |
required |
provider
|
RealtimeVoiceProvider
|
The realtime voice provider (OpenAI, Gemini, etc.). |
required |
transport
|
VoiceBackend
|
The audio transport (WebSocket, etc.). |
required |
owns_transport
|
bool
|
Close the transport with this channel (default True). Set False for a shared transport with unsubscribe support, such as FastRTC. Only this channel's sessions and callbacks close. |
True
|
system_prompt
|
str | None
|
Default system prompt for the AI. |
None
|
voice
|
str | None
|
Default voice ID for audio output. |
None
|
tools
|
list[dict[str, Any] | Any] | None
|
Tool definitions as dicts, or Tool objects with
|
None
|
temperature
|
float | None
|
Default sampling temperature. |
None
|
input_sample_rate
|
int
|
Default input audio sample rate (Hz). |
16000
|
output_sample_rate
|
int
|
Default output audio sample rate (Hz). |
24000
|
transport_sample_rate
|
int | None
|
Sample rate of audio from the transport (Hz).
When set and different from provider rates, enables automatic
resampling. Transports can override it in session metadata:
|
None
|
emit_transcription_events
|
bool
|
If True, emit final transcriptions as RoomEvents so other channels see them. |
True
|
tool_handler
|
ToolHandler | None
|
Async callable to execute tool calls.
Signature: |
None
|
mute_on_tool_call
|
bool
|
If True, mute the transport microphone during
tool execution to prevent barge-in that causes providers
(e.g. Gemini) to silently drop the tool result. Defaults
to False — use |
False
|
tool_result_max_length
|
int
|
Maximum character length of tool results before truncation. Large results (e.g. SVG payloads) can overflow the provider's context window. Defaults to 16384. |
16384
|
pipeline
|
AudioPipelineConfig | None
|
Optional |
None
|
recording
|
Any | None
|
Optional |
None
|
skills
|
SkillRegistry | None
|
Optional |
None
|
script_executor
|
ScriptExecutor | None
|
Optional |
None
|
skill_delivery_mode
|
str | None
|
How skill bodies reach the model.
|
None
|
tool_recovery
|
bool
|
If True, detect tool calls that the model speaks
as text (e.g. |
True
|
tool_search
|
bool | None
|
Auto-enable Tool Search when the catalogue is
large enough to exceed the realtime model's reliable
tool-selection window (Google: 10–20 active tools on
Gemini Live). Pass |
None
|
tool_search_pinned
|
list[str] | None
|
Tool names that should ALWAYS be
visible (never hidden behind search). Use for tools
the agent calls reflexively — e.g. |
None
|
tool_search_threshold
|
int
|
Auto-activation threshold and the cap on how many tools may be live at once. Defaults to 20 to match Google's published recommendation. |
20
|
wait_idle
async
¶
Wait until all sessions in the room are idle (not speaking).
An idle session has submitted its tool results, finished the provider response that follows them, and all audio has been forwarded to the transport. A queued transport such as SIP may still be playing that audio.
set_framework ¶
Set the framework reference for event routing.
Called automatically when the channel is registered with RoomKit.
on_trace ¶
Register a trace observer and bridge to the transport.
configure ¶
Update channel defaults for future sessions.
Active sessions are not affected — use reconfigure_session
for those.
start_audio_stream
async
¶
Open the realtime audio path on the provider.
Low-level escape hatch for opening the audio stream without
injecting any text. Most callers should use
inject_text(..., start_audio_stream=True) instead — that
composes the open + inject in a single call. No-op on providers
that don't need it.
inject_text
async
¶
Inject a text turn into the provider session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
VoiceSession
|
The active voice session. |
required |
text
|
str
|
Text to inject. |
required |
role
|
str
|
Role for the text ('user' or 'system'). |
'user'
|
silent
|
bool
|
If True, add to conversation context without requesting a response. The agent sees the text on its next turn but does not react immediately. |
False
|
start_audio_stream
|
bool
|
If True, open the realtime audio path on the provider before sending the text. Set this on the first inject in outbound flows where the app speaks first (e.g. SIP dial greetings); no-op on providers that don't need priming (OpenAI, xAI). |
False
|
inject_image
async
¶
Inject an image into the provider session for multimodal analysis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
VoiceSession
|
The active voice session. |
required |
image_data
|
bytes
|
Raw image bytes. |
required |
mime_type
|
str
|
MIME type of the image. |
'image/png'
|
prompt
|
str
|
Optional text prompt accompanying the image. |
''
|
silent
|
bool
|
If True, add to context without requesting a response. |
False
|
start_session
async
¶
Start a new realtime voice session.
Connects both the transport (client audio) and the provider (AI service), then fires a framework event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
room_id
|
str
|
The room to join. |
required |
participant_id
|
str
|
The participant's ID. |
required |
connection
|
Any
|
Protocol-specific connection (e.g. WebSocket). |
required |
metadata
|
dict[str, Any] | None
|
Optional session metadata. May include overrides for system_prompt, voice, tools, temperature. |
None
|
Returns:
| Type | Description |
|---|---|
VoiceSession
|
The created VoiceSession. |
end_session
async
¶
End a realtime voice session.
Disconnects both provider and transport, fires framework event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
VoiceSession
|
The session to end. |
required |
reconfigure_session
async
¶
reconfigure_session(session, *, system_prompt=None, voice=None, tools=None, temperature=None, provider_config=None)
Reconfigure an active session with new agent parameters.
Used during agent handoff to switch the AI personality, voice, and tools. Providers with session resumption (e.g. Gemini Live) preserve conversation history across the reconfiguration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
VoiceSession
|
The active session to reconfigure. |
required |
system_prompt
|
str | None
|
New system instructions for the AI. |
None
|
voice
|
str | None
|
New voice ID for audio output. |
None
|
tools
|
list[dict[str, Any]] | None
|
New tool/function definitions. |
None
|
temperature
|
float | None
|
New sampling temperature. |
None
|
provider_config
|
dict[str, Any] | None
|
Provider-specific configuration overrides. |
None
|
connect_session
async
¶
Accept a realtime voice session via process_inbound.
Delegates to :meth:start_session which handles provider/transport
connection, resampling, and framework events.
disconnect_session
async
¶
Clean up realtime sessions on remote disconnect.
update_binding ¶
Update cached bindings for all sessions in a room.
Called by the framework after mute/unmute/set_access so the
audio gate in _pipeline_on_audio_received (pipeline path)
or _forward_client_audio (direct path) sees the new state.
handle_inbound
async
¶
Not used directly — audio flows via start_session.
on_event
async
¶
React to events from other channels — TEXT INJECTION.
When a supervisor or other channel sends a message, extract the text and inject it into the provider session so the AI incorporates it. Skips events from this channel (self-loop prevention).
deliver
async
¶
No-op for realtime voice — content is injected via kit.deliver()'s
_deliver_to_realtime_voice path, which calls inject_text
directly. Events broadcast through channel.deliver() would double-
feed the session.
WhatsAppChannel ¶
Create a WhatsApp transport channel.
MessengerChannel ¶
Create a Facebook Messenger transport channel.
TeamsChannel ¶
Create a Microsoft Teams transport channel.
TelegramChannel ¶
Create a Telegram Bot transport channel.
WhatsAppPersonalChannel ¶
Create a WhatsApp Personal transport channel (neonize).
TransportChannel ¶
TransportChannel(channel_id, channel_type, *, provider=None, capabilities=None, recipient_key='recipient_id', defaults=None)
Bases: Channel
Generic transport channel driven by configuration rather than subclassing.
All transport channels (SMS, Email, WhatsApp, Messenger, HTTP) share the
same inbound/deliver logic. The only differences are data: which
ChannelType, which ChannelCapabilities, which metadata key holds the
recipient address, and which extra kwargs to pass to the provider's
send() method.
Use the factory functions (SMSChannel, EmailChannel, …) in
roomkit.channels for convenient construction.
Initialise a transport channel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel_id
|
str
|
Unique identifier for this channel instance. |
required |
channel_type
|
ChannelType
|
The channel type (SMS, email, etc.). |
required |
provider
|
Any
|
Provider that handles external delivery (e.g. ElasticEmailProvider). |
None
|
capabilities
|
ChannelCapabilities | None
|
Media and feature capabilities for this channel. |
None
|
recipient_key
|
str
|
Binding metadata key that holds the recipient address. |
'recipient_id'
|
defaults
|
dict[str, Any] | None
|
Default kwargs passed to |
None
|
handle_inbound
async
¶
Convert an inbound message into a room event.
deliver
async
¶
Deliver an event to the external recipient via the provider.
The recipient address is read from binding.metadata[recipient_key].
Extra kwargs are built from defaults: fixed values are passed as-is,
None defaults are resolved from binding metadata at delivery time.
WebSocket Streaming¶
StreamStart ¶
Bases: BaseModel
Sent when a streaming response begins.
StreamChunk ¶
Bases: BaseModel
Sent for each text delta during streaming.
StreamEnd ¶
Bases: BaseModel
Sent when a streaming response completes.
StreamMessage
module-attribute
¶
StreamMessage = StreamStart | StreamChunk | StreamEnd | StreamError
StreamSendFn
module-attribute
¶
StreamSendFn = Callable[[str, StreamMessage], Coroutine[Any, Any, None]]