react, react-dom,
livekit-client, @livekit/components-react — the latter two back the current
Transport implementation and are only required at runtime if you use
Transport extensions.
ScenaroProvider
Owns the sharedScenaroSession and the API client. Also injects
LiveKit’s RoomContext (the current Transport implementation) so
@livekit/components-react hooks work without extra wiring — see
Advanced: Transport extensions.
| Prop | Type | Default | Description |
|---|---|---|---|
apiUrl | string | — | API base URL (or pass client) |
client | ScenaroClient | — | Pre-built client instance |
apiPathPrefix | string | '/v1' | Prepended to all endpoints |
storagePrefix | string | '' | Prefix for localStorage keys |
storage | StorageAdapter | null | localStorage | Custom storage adapter |
client nor apiUrl is provided. The session’s transport listeners are
released automatically when the provider unmounts.
useScenaroSession
Single entry point for the session contract. Must be called under aScenaroProvider.
Options
UseScenaroSessionOptions — everything from StartSessionOptions
plus React callbacks:
| Option | Type | Description |
|---|---|---|
scenario | string | Publication UUID (required) |
language | string | BCP-47 — omit to use the scenario’s configured language |
inputMode / outputMode | 'audio' | 'text' | Default 'audio' |
microphone | boolean | Enable mic on connect (default true) |
externalId | string | null | Stable visitor identifier |
resumeConversationId | string | Resume an earlier conversation |
metadata | Record<string, unknown> | Attached to the session |
tools | Record<string, ToolHandler> | Frontend tool handlers |
onMessage | (message: ConversationMessage) => void | New conversation message |
onError | (error: ScenaroError) => void | Typed error callback |
onSessionEnd | (info: SessionEndInfo) => void | Session ended (any reason) |
Return value
| Field | Type | Contract |
|---|---|---|
status | 'idle' | 'connecting' | 'connected' | 'reconnecting' | 'ended' | Portable |
agentState | 'idle' | 'listening' | 'thinking' | 'speaking' | Portable |
messages | ConversationMessage[] | Portable |
config | SessionConfig | null | Portable |
conversationId | string | null | Portable |
error | ScenaroError | null | Portable |
start | (overrides?) => Promise<void> | Portable — overrides can’t change scenario |
end | () => Promise<void> | Portable |
sendText | (text: string) => Promise<void> | Portable |
setMicrophoneEnabled | (enabled: boolean) => Promise<void> | Portable |
room | Room | null | Engine extension (LiveKit today) — see Transport extensions |
rawConfig | ConfigPayload | null | Wire-format config (restore_state, tool wiring) |
Tool handlers
Plain functions. Return value is serialized back to the agent; throwing produces anERROR
response; exceeding the RPC timeout produces TIMEOUT and aborts context.signal.
FeatureProvider
Wires tool calls to UI components via an injectable registry. See Feature registry.| Prop | Type | Description |
|---|---|---|
registry | Map<string, ToolRegistryEntry> | Feature registry |
onResetBuckets | () => void | Called on session reset |
clearHistoryOnSessionEnd | boolean | Clear feature history on end |
initialVisibility | boolean | Panel visible by default |
initialPosition | 'left' | 'right' | 'mobile' | 'hidden' | Panel position |
useFeatures
ReturnsFeatureRuntimeContextValue:
| Method | Description |
|---|---|
executeTool(name, requestId, args) | Run a tool handler |
selectFeature(name) | Activate a feature panel |
setVisibility(visible, position) | Show/hide panel |
getFeatureComponent(name) | Get React component |
getToolMapping(toolName) | Resolve tool → feature |
navigateHistory(direction) | History back/forward |
reset() | Reset all state |
Context hooks
| Hook | Returns |
|---|---|
useScenaro() | { client, events, session } |
useScenaroClient() | ScenaroClient |
useScenaroEvents() | ScenaroEventBus |