Sessions
Connect a browser voice agent
Connect microphone capture, playback, tools, and interruption handling in the browser.
Connect from a user gesture
import { connectBrowserRealtime } from "@ox/sdk/browser";
const call = await connectBrowserRealtime({
session,
workletBaseUrl: "https://www.amerint.co/worklets",
configuration: {
instructions: "Help customers schedule service. Confirm before booking.",
language: "en",
voice: "Ryan",
endpointing: { eagerness: "medium" },
reasoning: { model: "Qwen/Qwen3-Next-80B-A3B-Instruct", temperature: 0.3, max_output_tokens: 512 },
tools: [{
type: "function",
name: "find_appointments",
description: "Find open appointment times.",
parameters: { type: "object", properties: { date: { type: "string" } }, required: ["date"] },
}],
},
onToolCall: async ({ name, arguments: json }) => {
const args = JSON.parse(json);
if (name === "find_appointments") return findAppointmentsForSignedInUser(args);
throw new Error("Unknown tool");
},
});
call.on("event", console.log);
await call.start(); // microphone permission must follow a user gesture
Use the hosted preview bundle
The hosted private-preview ESM bundle is also available at https://www.amerint.co/voice-sdk/ox-realtime.js for applications that cannot install the package yet.
Understand the runtime boundary
The SDK owns AudioWorklet capture, windowed-sinc resampling, exact 80 ms framing, capture-age and socket backpressure rejection, adaptive output jitter buffering, and local plus server-confirmed barge-in. Binary client frames are exactly 2560 bytes of 16000 Hz mono PCM16. Binary server frames are 24000 Hz mono PCM16. JSON and base64 audio are not accepted on the public hop.
Tool execution remains customer-owned. The model emits response.function_call_arguments.done; the SDK invokes the allow-listed handler, submits conversation.item.create, and sends response.create so the agent can continue the same turn. Microphone capture stays live while the tool is pending. Results time out after 15 seconds and are limited to 65536 bytes.