@kognitivedev/cloud-voice
v0.2.29
Published
Cloud voice agents SDK for Kognitive hosted voice APIs
Maintainers
Readme
@kognitivedev/cloud-voice
Cloud Voice Agents SDK for Kognitive hosted /api/cloud/voice/* APIs.
Create and publish agents in the Kognitive dashboard under Voice > Agents, then use the deploy page to generate origin-constrained kvp_* public embed keys. Browser code uses kvp_* keys only. Private kog_* project API keys stay server-side.
Server SDK
import { KognitiveCloudVoiceClient } from "@kognitivedev/cloud-voice";
const voice = new KognitiveCloudVoiceClient({
baseUrl: process.env.KOGNITIVE_API_URL!,
apiKey: process.env.KOGNITIVE_API_KEY,
});
await voice.agents.management.create({
name: "Support",
slug: "support",
config: {
instructions: "Help customers over voice.",
},
});
await voice.agents.management.publish("support");
// Idempotent create-or-update by slug. This is the preferred setup helper for
// scripts, deploy hooks, and customer provisioning flows.
const { agent, action } = await voice.agents.management.createOrUse("support", {
name: "Support",
publish: true,
config: {
instructions: "Help customers over voice.",
provider: "openai-realtime",
model: "gpt-realtime",
voice: "marin",
transport: "webrtc",
channels: {
web: true,
iframe: true,
script: true,
phone: true,
sip: false,
outbound: true,
},
humanization: {
openingMode: "auto",
openingStyle: "warm",
fillerStyle: "light",
backchannelFrequency: "low",
disfluency: "rare",
toolLatencyFillerMs: 700,
},
widget: {
title: "Talk to support",
subtitle: "Voice agent",
launcher: "button",
position: "bottom-right",
},
},
});
console.log(action, agent.slug);
const session = await voice.sessions.create("support", {
userId: "user_123",
channel: "web",
});Phone Calls
Cloud Phone uses the same Cloud Voice agent/session/event model for PSTN/SIP channels. Configure provider credentials and assign numbers in the dashboard under Voice > Phone Numbers.
Outbound calls are server-side and use private kog_* API keys:
const call = await voice.calls.create({
agent: "support",
fromNumberId: "number_123",
to: "+15551234567",
});Inbound calls are bound through phone numbers:
await voice.phone.numbers.create({
phoneNumber: "+15551234567",
inboundAgentSlug: "support",
inboundEnabled: true,
outboundEnabled: true,
});Live phone audio requires the Cloud Voice phone bridge:
cd apps/backend
bun run phone:bridgeThe bridge handles Twilio wss:// Media Streams and reports readiness through the SDK:
const bridge = await voice.phone.bridge.health();
console.log(bridge.online);Phone-call tools execute through managed Cloud Voice tools and optional per-call server tool bridges. Browser SDK tools do not run for phone calls because there is no browser parent page during PSTN execution.
Browser widget
Browser embeds use public kvp_* keys:
import { createVoiceWidget } from "@kognitivedev/cloud-voice/browser";
createVoiceWidget({
baseUrl: "https://dashboard.example.com",
publicKey: "kvp_...",
agent: "support",
target: "#voice-agent",
style: {
theme: "minimal",
accentColor: "#111111",
surfaceColor: "#fffdf8",
radius: "12px",
shadow: "none",
align: "center",
},
iframe: {
width: "380",
height: "620",
style: { borderRadius: "16px" },
},
});Client-side tools
Customer SDK tools execute in the app that embeds the widget. The SDK sends only the tool manifest/schema to Cloud Voice; function code stays in the browser.
createVoiceWidget({
baseUrl: "https://dashboard.example.com",
publicKey: "kvp_...",
agent: "support",
target: "#voice-agent",
tools: {
lookup_order: {
description: "Look up an order in this app.",
inputSchema: {
type: "object",
properties: { orderNumber: { type: "string" } },
required: ["orderNumber"],
},
execute: async ({ orderNumber }) => fetchOrder(orderNumber),
render: ({ input, output, state }) => {
if (state === "input-available") return "Looking up order...";
return `Order ${input.orderNumber}: ${output.status}`;
},
},
managed_tool_ui: ({ output, state }) => {
if (state !== "output-available") return "Running...";
return `Managed tool returned ${JSON.stringify(output)}`;
},
},
});Tools with execute are registered as client tools and run in the customer page through the iframe bridge. Renderer-only shorthand is local UI for tools executed elsewhere, such as managed cloud tools configured on the agent.
Iframe embed
<iframe
src="https://dashboard.example.com/voice/embed?publicKey=kvp_...&agent=support&theme=minimal&accent=%23111111&surface=%23fffdf8&radius=12px&shadow=none"
allow="microphone; autoplay"
width="380"
height="620"
style="border:0;border-radius:16px;max-width:100%;"
></iframe>Style options
createVoiceWidget({ style }) and iframe query params support:
theme:default,minimal,solid,glassaccentColor,backgroundColor,surfaceColor,textColor,mutedColorwidth,padding,gap,radius,panelRadius,buttonRadius,orbSizeshadow:none,soft,strongalign:center,top,bottomdensity:compact,comfortable
For iframe query params, use the shorter aliases where available: accent, bg, surface, text, and muted.
Phone server tools
Custom phone tools are normal Kognitive server tools exposed to the phone bridge for the lifetime of a call. Define them once in the customer app, register them on the Kognitive instance, and provide a per-call tool bridge URL when creating or binding a phone call.
import { Kognitive } from "@kognitivedev/core";
import { createTool } from "@kognitivedev/tools";
import { z } from "zod";
const lookupOrder = createTool({
id: "lookup_order",
description: "Look up an order by number",
inputSchema: z.object({
orderNumber: z.string(),
}),
execute: async ({ orderNumber }, ctx) => {
return db.orders.findByNumber(orderNumber);
},
});
export const kognitive = new Kognitive({
apiKey: process.env.KOGNITIVE_API_KEY,
baseUrl: process.env.KOGNITIVE_API_URL,
tools: [lookupOrder],
});Server tools work for inbound and outbound phone sessions when the call metadata includes the tool bridge URL. Browser SDK tools are separate: they run in the customer page and can render custom UI, but they cannot answer phone tool calls.
