@doweit/voice
v0.1.9
Published
Capability-first voice AI SDK. Register your JS functions, and Gemini Live calls them when users speak or type.
Maintainers
Readme
@doweit/voice
Capability-first voice AI SDK for the web. Expose your JavaScript functions, and Gemini Live decides when and how to call them based on what your users say or type.
Install
npm install @doweit/voiceRequires React 18+ (or 19). The SDK ships React components, so it is meant for React / Next.js apps.
Quick start (React / Next.js)
import { DoweitClient, DoweitWidget } from "@doweit/voice";
// 1. Create a client with your publishable key (from the Doweit dashboard).
const client = new DoweitClient({
publicKey: "dw_pub_...",
});
// 2. Tell the AI what your app can do.
client.register({
addToCart: {
description: "Add an item to the shopping cart.",
params: { itemId: { required: true }, qty: { required: true } },
handler: async ({ itemId, qty }) => {
await fetch(`/api/cart`, { method: "POST", body: JSON.stringify({ itemId, qty }) });
return { status: "ok" };
},
},
});
// 3. Drop the widget in. It initializes itself — no useEffect, no loading flag.
export default function App() {
return <DoweitWidget client={client} />;
}That's it. The chat bubble appears in the bottom-right corner. <DoweitWidget> calls client.init() for you on mount, shows a "Connecting…" state while it loads, and shows a clear error inside the panel if something goes wrong.
Next.js note: the widget is a client component. Put
"use client";at the top of the file that renders it (or render it from a client component).
Core concepts
- Capability-first: you describe what your app can do (
register), and the AI decides which capability matches the user's intent. No predefined intents, no string matching. - Hosted backend: the SDK talks only to the Doweit backend — no setup, no URL to configure. Your publishable key is safe to ship in the browser; it never touches Google directly.
- Manifest sync: on init, the SDK ships a snapshot of your registered actions to the Doweit dashboard so you can inspect and version them.
- Live state: use
client.bindState(() => ({ cart, page }))so the AI always sees the current UI without you injecting prompts.
Before it works: allow your domain
The SDK runs in your users' browsers and calls the Doweit backend cross-origin. For that to be permitted:
- Open your app in the Doweit dashboard.
- Add the domain(s) where you embed the widget to the domain whitelist (e.g.
app.yoursite.com). localhostis always allowed, so local development works with no setup.
If your domain is not whitelisted, the widget shows "Assistant unavailable" and the browser console logs a domain/CORS error.
API
new DoweitClient(config)
publicKey(required): your project's publishable key (dw_pub_...).baseUrl(optional): override the Doweit backend URL. Defaults to the Doweit hosted backend — you normally do not set this.language(optional): ISO code, e.g."en".
client.register(actions)
Register one or more capabilities:
client.register({
bookTable: {
description: "Reserve a table.",
params: { guests: { type: "number", required: true }, time: { required: true } },
scope: "global", // or a route prefix like "/restaurant"
dangerous: false, // if true, prompts the user for confirmation
handler: async (args) => { /* ... */ },
},
});client.bindState(getter)
Reactively expose current UI state to the AI:
client.bindState(() => ({ cart: getCart(), currentPage: location.pathname }));client.setUser({ userId, email })
Identify the end-user so memory persists across sessions.
client.use((action, next) => ...)
Middleware for validation, logging, or blocking dangerous calls.
client.enableNavigation(router)
Auto-registers a navigate action wired to your router (Next.js, React Router, etc.).
<DoweitWidget client={client} />
Drop-in chat bubble UI with voice + text. It initializes the client itself. Or use the useDoweitVoice(client) hook to build your own UI.
client.init()
Optional — the widget calls this for you. Call it manually only if you want to initialize before the widget mounts. It is idempotent and safe to call multiple times.
License
MIT © Doweit
