Skip to main content
@fishaudio/agent-client runs a live voice conversation with your agent from any web page: open the microphone, stream audio both ways, and react to typed events for transcripts, agent state, and tool calls. The SDK handles the realtime transport (WebRTC) internally — your code never touches connection plumbing. Using React? @fishaudio/agent-react wraps this SDK in hooks and a provider.

Install

Start a session

AgentSession.start() creates the session, connects, and opens the microphone in one call. Authenticate one of two ways:
  • agentId — for public agents. The SDK creates the session directly from the browser; no backend needed.
  • sessionToken — for private agents. Your backend calls POST /v1/agent/sessions with your API key and hands the JSON response to the browser; pass it through unchanged. See Authentication.

Options

Session lifecycle

A session moves through a fixed state machine, surfaced by the statusChange event and the session.status property:
States
When the session ends, disconnect fires with a reason (also available as session.endReason): Brief network drops don’t end the session: the SDK moves to reconnecting and back to connected automatically, reusing the same session.
Events are not replayed after a reconnect. Anything emitted while you were in reconnecting — transcript updates, tool events, errors — is dropped, not resent. Design your UI to tolerate gaps: tool toolCallCompleted / toolCallFailed events repeat the tool name and source, so a terminal event still renders even if you missed toolCallStarted.

Events

The session is a typed event emitter — subscribe with session.on(event, handler), remove with off, or use once.
Subscribe to events

Transcript semantics

Transcripts on both sides arrive as segments — one segment per utterance or response, identified by segmentId:
  • User segments: interim results replace the entire segment text (they never append). Render by upserting on segmentId; final: true marks the segment as finalized.
  • Agent segments: text streams in sync with audio playback — what you display matches what the user has actually heard. If the agent is interrupted, the segment finalizes containing only the words that were spoken.
  • The message event delivers only finalized messages from both sides, in order — use it when you want a simple transcript list without handling interim updates.

Agent modes

session.mode (and the modeChange event) tracks what the agent is doing, for driving an orb or status indicator: session.isSpeaking is a convenience boolean for the speaking mode. Mode does not react to the user’s own speech — for instant “the mic hears you” feedback, poll getInputVolume() locally.

Send text

Users can type instead of talking, in the same session:
Text input

Audio controls

Select specific devices at start with the audio option (inputDeviceId / outputDeviceId).
Audio visualizer

Client tools

Register handlers for tools of type client declared on the agent — the agent calls them mid-conversation and your return value goes back to the model:
Register a client tool
Handlers can be sync or async; a thrown error or a timeout (default 15 s) is returned to the agent as a tool error. See Client tools for declaration, naming rules, and dispatch semantics.

Errors

Failures surface as FishAgentError — thrown from AgentSession.start() when the session can’t be created, emitted on the error event otherwise. Each carries a code, an optional statusCode (set on session-creation HTTP errors), and cause.
provider_error and internal_error carry only the category code — raw provider or infrastructure details are never sent to the browser.
Handle errors

End the session

Hang up

Going further

React SDK

Hooks, provider, and visualizer components on top of this SDK.

Authentication

Mint session tokens from your backend for private agents.

Public agents

Backend-free sessions with origin allow-lists and rate limits.

Wire protocol

The wire-level events underneath the SDK.