React bindings for Scenaro voice sessions. Peer dependencies: 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 shared ScenaroSession 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.
PropTypeDefaultDescription
apiUrlstringAPI base URL (or pass client)
clientScenaroClientPre-built client instance
apiPathPrefixstring'/v1'Prepended to all endpoints
storagePrefixstring''Prefix for localStorage keys
storageStorageAdapter | nulllocalStorageCustom storage adapter
Throws if neither 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 a ScenaroProvider.

Options

UseScenaroSessionOptions — everything from StartSessionOptions plus React callbacks:
OptionTypeDescription
scenariostringPublication UUID (required)
languagestringBCP-47 — omit to use the scenario’s configured language
inputMode / outputMode'audio' | 'text'Default 'audio'
microphonebooleanEnable mic on connect (default true)
externalIdstring | nullStable visitor identifier
resumeConversationIdstringResume an earlier conversation
metadataRecord<string, unknown>Attached to the session
toolsRecord<string, ToolHandler>Frontend tool handlers
onMessage(message: ConversationMessage) => voidNew conversation message
onError(error: ScenaroError) => voidTyped error callback
onSessionEnd(info: SessionEndInfo) => voidSession ended (any reason)

Return value

FieldTypeContract
status'idle' | 'connecting' | 'connected' | 'reconnecting' | 'ended'Portable
agentState'idle' | 'listening' | 'thinking' | 'speaking'Portable
messagesConversationMessage[]Portable
configSessionConfig | nullPortable
conversationIdstring | nullPortable
errorScenaroError | nullPortable
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
roomRoom | nullEngine extension (LiveKit today) — see Transport extensions
rawConfigConfigPayload | nullWire-format config (restore_state, tool wiring)

Tool handlers

Plain functions. Return value is serialized back to the agent; throwing produces an ERROR 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.
PropTypeDescription
registryMap<string, ToolRegistryEntry>Feature registry
onResetBuckets() => voidCalled on session reset
clearHistoryOnSessionEndbooleanClear feature history on end
initialVisibilitybooleanPanel visible by default
initialPosition'left' | 'right' | 'mobile' | 'hidden'Panel position

useFeatures

Returns FeatureRuntimeContextValue:
MethodDescription
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

HookReturns
useScenaro(){ client, events, session }
useScenaroClient()ScenaroClient
useScenaroEvents()ScenaroEventBus