Scenaro voice agents call frontend tools over Transport RPC (LiveKit RPC today — see
Transport). The SDK offers two ways to handle those calls. This page
explains when to use each — similar to how Vapi separates
client-side tools (browser effects) from
server tools (model needs the result).
Do not register the same RPC method name in both patterns — behavior will conflict.
Decision tree
Use when: the handler returns data to the agent and does not need a feature panel, history,
or overlay UI.
Registration: pass tools to useScenaroSession (or session.start({ tools }) headless).
Handler signature:
The SDK:
- Registers RPC methods on connect
- Wraps your return value as
{ requestId, code: 'OK', data }
- Aborts
context.signal after 10 seconds (RPC_TIMEOUTS.FRONTEND_TOOL_MS)
- Returns
{ code: 'TIMEOUT' } to the agent on timeout
Use when: the tool drives a UI feature panel — search results, product detail, comparison,
shopping list — with history, visibility, and component rendering.
Registration: FeatureProvider with a Map<string, ToolRegistryEntry> keyed by feature type
(e.g. collection-items-search).
Handler signature (different from session tools):
FeatureProvider internally mounts useFeatureToolRpc, which:
- Listens for
config on the event bus
- Registers RPC methods for tools listed in the wire config
- Emits
tool:execute → runs executeTool → responds to the agent
See Feature registry and custom feature recipe.
Local FeatureManager vs SDK FeatureProvider
Both patterns exist in the Scenaro monorepo:
| SDK FeatureProvider | Local FeatureManager |
|---|
| Used by | platform-spa live page | All 7 experience apps |
| Session hook | useScenaroSession | useScenaroSession (via thin adapter) |
| Tool RPC | SDK useFeatureToolRpc | Local AgentListener → engine handle registerRpcMethod |
| Feature state | SDK useFeatures() | Local useFeatures() in vendored runtime |
| When to choose | Greenfield app, no vendored copy | Migrating existing experience with local runtime |
Experience apps typically keep a thin adapter at src/lib/scenaro-sdk/hooks/useScenarioSession.js
that maps connect → start(), isConnected → status === 'connected', etc. The local
FeatureManager + AgentListener handle tool RPC independently of SDK FeatureProvider.
You do not need to migrate to SDK FeatureProvider unless you want to drop the vendored
feature runtime.
Config: curated vs raw
After the config handshake you get two views:
| Field | Type | Use for |
|---|
config | SessionConfig | Features list, collections, avatar/dictation flags |
rawConfig | ConfigPayload | restore_state, tool wiring, snake_case backend fields |
On the event bus, events.on('config', …) receives the raw ConfigPayload. On the session,
session.on('config', …) receives the curated SessionConfig.
RPC flow (both patterns)
Topics not exposed as SDK helpers
Some protocol topics exist but have no high-level SDK API yet. Use the engine handle (room)
- manual data listeners if needed:
| Topic | Purpose |
|---|
assistant:interrupt | Stop agent speech |
state:update | Session checkpoints |
dictation:transcript | STT partials |
event:fire | Custom analytics events |
See Protocol topics.
Next steps