@talqing/sdk/browser is the React layer that joins a voice or video call from
a web page. It wraps LiveKit so you never type livekit-client yourself, and it
carries the pieces a Talqing call needs on top of a room: the token mint,
userdata over RPC, images, screen share, the avatar track and frontend actions.
This page is the reference. For the end-to-end integration — minting the token
on your server, the first working component — read
web calls and
web call features.
Install
livekit-client and @livekit/components-react come with the package. react
and react-dom are peer dependencies — ^18.3.1 or ^19 — and are used by
this entrypoint only; the API client at @talqing/sdk renders nothing.
The three rules
One session is one call.useTalqingSession builds one Room and one token
source. Start it when the component mounts and end it on the way out. To place a
second call, mount a second session — render the call component while a call is
up and drop it to hang up — and give it a key that changes per call.
A finished session cannot be restarted. Its token names the room that call
used, and the API refuses a second call rejoining it. start() on a spent
session does not give you a new call.
Screen share must start from a click. getDisplayMedia requires a transient
user activation, so start() has to run inside a real user gesture. An agent
can ask for a screen; it can never take one.
Joining a call
useTalqingSession
Room and the token source, and returns LiveKit’s session object —
{ room, isConnected, connectionState, start, end, waitUntilConnected, … }.
callOptions is everything POST /v1/calls/token accepts except agent_id:
contact_key, userdata, vars, agent_version, agent_override,
agent_team. onTokenDetails receives the whole token response — including
conversation_id, session_id, the minted contact_key and any warnings —
the moment it is minted.
contact_key — your own id for the person — if the agent should recognise a
returning caller. Each call mints its own key when you leave it out, so two calls
from the same person arrive as two strangers and an agent set to carry past
conversations has nothing to carry.
roomOptions is LiveKit’s own RoomOptions, spread over the audio capture
defaults below. Override audioCaptureDefaults there if you must.
TalqingSessionProvider
useTalqingImages reads — and mounts LiveKit’s audio renderer so the agent is
audible. Pass audio={false} only if you are rendering the audio element
yourself.
useTalqingConnection
room is what useTalqingImages takes;
end() hangs up.
createTalqingTokenSource
useTalqingSession builds internally. Reach for it only if you are
managing your own Room.
It mints once per source and caches the in-flight promise, which is load-bearing:
POST /v1/calls/token files the session row the call is later read back from,
and LiveKit asks its token source three times per call — to warm the connection,
to connect, and once more as the call ends. Without the cache, the third mint
filed a session nobody ever joined, which sat in the workspace’s call list
forever. A failed mint is kept out of the cache so the surface can offer the call
again. Freshness comes from a new source per call, never from re-minting inside
one.
TALQING_AUDIO_CAPTURE_DEFAULTS
useTalqingSession unless your roomOptions overrides
audioCaptureDefaults. Echo cancellation is what stops the agent hearing its own
speech through the caller’s microphone and interrupting itself — a call without
it is broken in a way that sounds like a bad model, which is why it is a default
rather than something each app has to remember.
Media
useTalqingAgent
state is disconnected, connecting, pre-connect-buffering, initializing,
idle, listening, thinking, speaking or failed. isFinished is true
once the client has disconnected from the agent, expectedly or not.
useTalqingMessages
messages belongs to the live session only; the stored transcript, with tool
calls and cost, is on GET /v1/calls/{session_id}.
setTalqingBrowserLogLevel
"debug" is the first move on a
connection problem you cannot see.
Images
A caller attaches a photo mid-call and the agent sees it. The bytes go over a LiveKit byte stream addressed to the agent; the agent acknowledges over RPC, and the idsend returns is the id that acknowledgement carries, so there is nothing
to correlate by hand.
The agent deliberately does not speak when a photo lands. The caller is
mid-conversation and about to say what it is for, so the image goes into the
model’s view for their next turn.
useTalqingImages
Room rather than reading context, because a byte stream and an RPC
handler are room-level things — pass useTalqingConnection().room, or the Room
you built yourself.
send validates, downscales, sends, and resolves once the bytes are on their
way. The outcome arrives on sent, which is what a thumbnail should render.
Each entry is a TalqingSentImage:
unknown is the state people forget: the agent going away mid-upload, where no
acknowledgement is ever coming. It is set after 30 seconds of silence, with
“we did not hear back — the agent may not have received it”.
talqingImageRejection
null when the file is fine. Refuses anything that is
not JPEG, PNG or WebP (“that file is not a JPEG, PNG or WebP”) and anything
over 10 MB (“images are 10 MB or smaller”). The server re-validates
regardless — this exists so the common mistakes cost nothing to catch.
talqingDownscaleImage
useTalqingImages.send calls
it for you.
talqingImageDataUrl
data: URL a text message carries —
POST /v1/conversations/messages takes images: [{ data_url, filename }], and
this produces the data_url. It doubles as a thumbnail src, so there is no
object URL to create and revoke. Throws the sentence to show if the file is
refused.
Image constants
Screen share
useTalqingScreenShare
enabled is whether a screen is being shared right now; pending is true while
the browser picker is open or the track is publishing. stop() ends it, and the
agent is told it can no longer see on its next turn.
Userdata
Read and write the live session’s userdata from the page, over RPC to the agent. See userdata for what it is.useTalqingUserdata
Error("room is not connected") when
there is no room.
setTalqingUserdata and getTalqingUserdata
Room you hold. They find the agent
participant and call talqing.client.userdata_set / talqing.client.userdata_get
on it. With no agent connected, set resolves
{ ok: false, error: "agent participant is not connected" } while get
throws — a write that did not land is a state you can render, a read that
returned nothing is not.
Omit keys on get to fetch the whole bag.
Frontend RPC
A tool’sfrontend_rpc operation calls back into your page mid-call — to
highlight a product, open a form, or move the user along. See
frontend RPC for the tool side.
useTalqingRpcHandlers
talqing.frontend_rpc method on the room and dispatches by the
envelope’s method. A "*" key catches everything unmatched — and when the
wildcard handles a call, data.payload is the whole envelope (method and
payload) rather than just the payload, so the handler can tell what it caught.
An unknown method with no wildcard throws TalqingRpcError code 1404 back to
the agent; anything else your handler throws goes back as code 1500 with its
message.
Each handler receives a TalqingRpcInvocation:
and must return a
string (or a promise of one), which is what the agent
receives.
enabled: false to hold off.
useTalqingFrontendRpcs
at as the timestamp it arrived.
Always answers the agent "ok". Use it to render whatever the agent asked for
without writing a handler per method.
TalqingRpcError
1500.
Video
useTalqingAvatarTrack
undefined until one is published.
TalqingVideoTrack
Exported types
Web calls
The token, the join, and a complete integration.
Web call features
Images, screen share, userdata and frontend actions in context.