Overview
The widget and the voice agent communicate through the LiveKit data channel using topic-keyed JSON messages. Understanding this protocol is useful when:- Building custom agent logic that opens or controls forms
- Implementing client-event tools that the agent fires back to the browser
- Building your own widget or native-app integration against the same backend
Agent → Widget messages
Messages sent from the agent to the browser widget.Open a form
The agent sends this to open a form panel (optionally pre-filling fields).| Property | Value |
|---|---|
| Topic | form.{form-id} (e.g. form.book-demo) |
| Fallback topics | {form-id}.form, any topics defined on the form |
name values in the form definition. Any matching key is pre-filled. The payload can be empty ({}) to open the form with no pre-fills.
Legacy format (also supported):
Agent handoff
Sent when the agent transfers the session to a different AI character mid-call.| Property | Value |
|---|---|
| Topic | voice.agent_handoff |
Client-event tool
When you define a tool withkind: "client_event" and a topic in its config, the agent publishes to that topic. Your page JavaScript can subscribe to the LiveKit room’s data channel and handle the message.
| Property | Value |
|---|---|
| Topic | Whatever config.topic is set to in the tool definition |
Widget → Agent messages
Messages sent from the widget to the agent.Form state (continuous)
Published every ~250 ms (debounced) while a form is open. Lets the agent track what the user has filled in and guide them verbally.| Property | Value |
|---|---|
| Topic | form.state |
fields array gives the agent the full schema of the current step so it can build contextual prompts (e.g. “It looks like your email address isn’t complete yet.”).
Form submission confirmation
Published once after a successful form submit. Consumed by the agent to continue the conversation.| Property | Value |
|---|---|
| Topic | confirmation_topic from form def (default "voice.user_text") |
Form submission failure
Published when the form submit HTTP call fails.| Property | Value |
|---|---|
| Topic | form.state |
User text input
Published when the user types a message in the text input box (only visible whentextInputEnabled: true in audio preferences).
| Property | Value |
|---|---|
| Topic | voice.user_text |
Topic reference summary
| Topic | Direction | Description |
|---|---|---|
form.{form-id} | Agent → Widget | Open a form (optionally pre-filled) |
voice.agent_handoff | Agent → Widget | Transfer to a different character |
{custom_topic} | Agent → Widget | Client-event tool output |
form.state | Widget → Agent | Live form field values (250 ms debounce) |
voice.user_text (default) | Widget → Agent | Form submission confirmation or text input |
