@zrt/js-sdk
v0.1.0
Published
Build real-time AI voice agents in JavaScript / TypeScript. Zero Runtime runs the speech-to-speech pipeline (STT, LLM, TTS) for you.
Maintainers
Readme
ZRT — Zero Runtime JS SDK
Build real-time AI voice agents in JavaScript / TypeScript — without running the infrastructure. You write the agent (instructions, tools, logic); Zero Runtime runs the live speech-to-speech pipeline — speech-to-text → LLM → text-to-speech, with turn detection, denoising, and interruptions — at low latency in the cloud.
Write the agent. We run the runtime.
The ZRT JS SDK — build voice agents in JavaScript / TypeScript with idiomatic conventions (ESM, a clean options-object API) over the Zero Runtime.
A different kind of voice SDK
Most voice frameworks make you run the hard part — media servers, GPUs, turn-taking, autoscaling. No-code platforms hide all that but lock you into a dashboard. Zero Runtime is the middle: real TypeScript and your own providers, with none of the real-time infrastructure to operate.
| | Self-hosted frameworks | No-code platforms | Zero Runtime | |---|:---:|:---:|:---:| | Write real code + custom tools | ✅ | ❌ (dashboard) | ✅ | | Run media servers / GPUs / scaling | ❌ you run it | ✅ managed | ✅ managed | | Swap any STT / LLM / TTS provider | ✅ | limited | ✅ | | Low-latency speech-to-speech | you tune it | managed | managed |
Requirements
- Node.js 18+
- A ZRT auth token (from app.zeroruntime.ai)
- API key(s) for the providers you use (e.g. Deepgram, Google, Cartesia)
Install
npm install @zrt/js-sdkQuickstart
1. Set your environment
export ZRT_AUTH_TOKEN=<your-token> # from app.zeroruntime.ai
export DEEPGRAM_API_KEY=<key> # speech-to-text
export GOOGLE_API_KEY=<key> # LLM (Gemini)
export CARTESIA_API_KEY=<key> # text-to-speech2. Write your agent — agent.ts
import { Agent, Pipeline, Room, serve, invoke, functionTool } from '@zrt/js-sdk';
import { CartesiaTTS, DeepgramSTT, GoogleLLM, SileroVAD, TurnDetector } from '@zrt/js-sdk/plugins';
const AGENT_ID = 'assistant';
const getWeather = functionTool({
name: 'get_weather',
description: 'Get the current weather for a city.',
parameters: {
type: 'object',
properties: { city: { type: 'string', description: 'Name of the city to look up.' } },
required: ['city'],
},
execute: async ({ city }: { city: string }) => ({
city,
temperature_c: 28,
condition: 'Sunny',
humidity: 55,
}),
});
class Assistant extends Agent {
constructor() {
super(
'You are a friendly voice assistant. Keep replies short and natural. ' +
'When asked about the weather, call the get_weather tool.',
{
name: 'Assistant',
agentId: AGENT_ID,
tools: [getWeather],
pipeline: Pipeline({
stt: DeepgramSTT({ model: 'nova-2-conversationalai' }),
llm: GoogleLLM({ model: 'gemini-3-flash-preview', thinkingBudget: 0 }),
tts: CartesiaTTS({ model: 'sonic-3.5' }),
vad: SileroVAD(),
turnDetector: TurnDetector({ model: 'echo-large' }),
}),
},
);
}
async onEnter(): Promise<void> {
await this.session!.say("Hi! I'm your assistant. Ask me about the weather in any city.");
}
async onExit(): Promise<void> {
await this.session!.say('Thanks for calling. Goodbye!');
}
}
// Register the agent, then start a session once it is ready.
serve(new Assistant(), {
onReady: () => invoke(AGENT_ID, { room: Room({ playground: true }) }),
});3. Run it
npx tsx agent.tsThat's it — speech in → your agent → speech out, in real time.
How it works
| Piece | What it is |
|---|---|
| Agent | Your behavior — instructions, tools, what it says on enter/exit. |
| Pipeline | The voice stack: STT (hear) → LLM (think) → TTS (speak), plus VAD, turn detection, and denoising. |
| serve | Registers your agent with the Zero Runtime and serves dispatched sessions. |
| invoke | Starts a session for a registered agent — call it from anywhere. |
Give your agent tools
Tools are TypeScript functions the LLM can call. Because JavaScript has no runtime type
introspection, each is declared explicitly with functionTool({ name, description, parameters,
execute }) — the JSON-schema parameters describe the arguments — then passed to the agent
via tools: [...] (see get_weather in the quickstart above). Your tool runs in your worker;
the runtime calls it when the LLM decides to.
Providers
Mix and match — bring the best model for each stage, swap any one in a line:
- Speech-to-text (STT): Deepgram, AssemblyAI, Google, Azure, Gladia, NVIDIA, Sarvam
- LLM: OpenAI, Google Gemini, Anthropic Claude, AWS Bedrock, Groq, Cerebras, xAI Grok, Sarvam, CometAPI
- Text-to-speech (TTS): Cartesia, ElevenLabs, Google, AWS Polly, Azure, Rime, LMNT, Neuphonic, Hume AI, Inworld, Murf, Resemble, Smallest, Speechify, CambAI, NVIDIA, Papla
- Realtime speech-to-speech: OpenAI Realtime, Gemini Live, Ultravox, Azure Voice Live, xAI
- Turn detection: Namo · VAD: Silero · Denoise: RNNoise
import { ElevenLabsTTS, AnthropicLLM } from '@zrt/js-sdk/plugins'; // swap any providerAll providers are importable from the single @zrt/js-sdk/plugins entry point or individually from @zrt/js-sdk/plugins/<name> for
finer-grained imports.
Use cases
Phone & telephony agents, IVR replacement, customer-support voice bots, voice assistants, outbound/inbound call automation, and any real-time conversational AI.
API conventions
This SDK follows idiomatic JavaScript / TypeScript conventions:
- A consistent public API: every option uses the same naming style.
- Providers and components are created from a single options object, with no
new(GoogleLLM({ maxOutputTokens: 8192 })). - Tools are declared with an explicit
functionTool({ name, description, parameters, execute })descriptor. - Settings map cleanly to the runtime — option names, configuration keys, and event names are forwarded exactly as the Zero Runtime expects.
FAQ
How is this different from a voice-agent framework?
- Frameworks make you host and scale the real-time runtime (media, GPUs, turn-taking). ZRT runs that for you — you only write and deploy the agent.
How is it different from a no-code voice platform?
- You write real TypeScript with your own tools, logic, and providers — not a dashboard configuration. Full code control, zero infrastructure.
Can I use my own STT / LLM / TTS providers?
- Yes — mix any supported providers, and bring your own API keys.
What do I need to run it?
- A ZRT runtime endpoint + token and the provider keys for the stages you use.
Resources
- Docs: https://docs.zeroruntime.ai/
- Examples: https://github.com/ZeroRuntimeAI/zrt-js-sdk-examples
- Dashboard & tokens: https://app.zeroruntime.ai
- Also available for Python: https://pypi.org/project/zrt/
- Support: [email protected]
Copyright © 2026 Zujo Tech Pvt Ltd. All rights reserved.
