@voicelayer/sdk 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -9
- package/dist/brain/index.d.ts +2 -2
- package/dist/brain/index.js +35 -0
- package/dist/index.d.ts +249 -249
- package/dist/index.js +63 -5
- package/dist/runtime/text-session.d.ts +1 -1
- package/dist/runtime/text-session.js +41 -0
- package/dist/{text-session-BB0dLLH2.d.ts → text-session-CtXihRr6.d.ts} +98 -98
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -32,7 +32,9 @@ export default await defineAgent({
|
|
|
32
32
|
node --import tsx agent.ts dev
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
The worker runs on **your** LiveKit project. Call a number you have connected to that project (a LiveKit SIP trunk plus a dispatch rule for the agent name `hello`), or join a room from LiveKit's Agents Playground, and the agent answers. STT, LLM, TTS, VAD, turn detection — defaults are picked for you. Swap them later with one config line.
|
|
36
|
+
|
|
37
|
+
> **What a self-hosted worker can and can't do today.** A number bought or imported in VoiceLayer can't reach a worker you run on your own LiveKit project: VoiceLayer numbers answer with **hosted flow agents** (built in the dashboard's flow builder) and **brain-connector agents** (your own LLM behind a VoiceLayer-hosted voice pipeline — see [Bring your own LLM](#bring-your-own-llm)). Your worker still registers with VoiceLayer, so it shows up in the dashboard with its calls and transcripts.
|
|
36
38
|
|
|
37
39
|
---
|
|
38
40
|
|
|
@@ -301,7 +303,7 @@ Each method receives `(args, ctx)`, so you can reach call state from inside a co
|
|
|
301
303
|
node --import tsx agent.ts dev
|
|
302
304
|
```
|
|
303
305
|
|
|
304
|
-
This boots the worker against your LiveKit project and registers the agent with the VoiceLayer control plane, so you can call
|
|
306
|
+
This boots the worker against your LiveKit project and registers the agent with the VoiceLayer control plane, so you can call a number connected to your LiveKit project and iterate on the same file you will deploy. Set the environment variables listed under [Production](#production) first.
|
|
305
307
|
|
|
306
308
|
> A headless harness for asserting on process capture without audio is not part of the public API yet. Today, iterate by calling the agent, or drive the flow from the Playground in the dashboard.
|
|
307
309
|
|
|
@@ -320,21 +322,28 @@ export LIVEKIT_URL=...
|
|
|
320
322
|
export LIVEKIT_API_KEY=...
|
|
321
323
|
export LIVEKIT_API_SECRET=...
|
|
322
324
|
|
|
323
|
-
# Provider keys for the models your agent uses
|
|
324
|
-
#
|
|
325
|
+
# Required. Provider keys for the models your agent uses. Your worker reads
|
|
326
|
+
# them from its own environment — provider keys saved in the VoiceLayer
|
|
327
|
+
# dashboard's Connections are NOT handed to a worker you run yourself.
|
|
325
328
|
export OPENAI_API_KEY=...
|
|
326
329
|
export DEEPGRAM_API_KEY=...
|
|
327
330
|
|
|
328
331
|
node agent.ts start
|
|
329
332
|
```
|
|
330
333
|
|
|
334
|
+
Agent names starting `voicelayer-` (and the names of VoiceLayer's own workers) are reserved; registering one is refused with `422 agent_name_reserved`.
|
|
335
|
+
|
|
331
336
|
### Texts
|
|
332
337
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
+
`.start()` also registers a second LiveKit name, `<name>::text`, beside the voice one. A text message dispatched to it
|
|
339
|
+
runs as your agent: its tools, security, connectors and model, with the conversation so far. Over text
|
|
340
|
+
`ctx.call.callerId` is the sender, `ctx.call.metadata.mode` is `'text'`, and call-only methods (`handoff`, `endCall`,
|
|
341
|
+
`ask`, DTMF) throw. In production the text registration's health server listens on `VL_TEXT_TURN_PORT` (default 8082).
|
|
342
|
+
|
|
343
|
+
> **Today** VoiceLayer dispatches text turns (SMS replies, Discord, the website chat widget, the dashboard playground)
|
|
344
|
+
> through its own LiveKit project, so they reach VoiceLayer-hosted workers only. A worker on your own LiveKit project
|
|
345
|
+
> doesn't receive them yet — the turn answers `agent_offline`. For texts on a VoiceLayer number, use a hosted flow
|
|
346
|
+
> agent or a brain-connector agent.
|
|
338
347
|
|
|
339
348
|
---
|
|
340
349
|
|
package/dist/brain/index.d.ts
CHANGED
|
@@ -79,14 +79,14 @@ declare const ConnectorUpFrame: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
|
|
|
79
79
|
code: z.ZodEnum<["upstream_timeout", "upstream_error", "bad_response", "normalize_failed", "unreachable"]>;
|
|
80
80
|
message: z.ZodString;
|
|
81
81
|
}, "strip", z.ZodTypeAny, {
|
|
82
|
+
kind: "brain.error";
|
|
82
83
|
code: "upstream_timeout" | "upstream_error" | "bad_response" | "normalize_failed" | "unreachable";
|
|
83
84
|
message: string;
|
|
84
|
-
kind: "brain.error";
|
|
85
85
|
streamId: string;
|
|
86
86
|
}, {
|
|
87
|
+
kind: "brain.error";
|
|
87
88
|
code: "upstream_timeout" | "upstream_error" | "bad_response" | "normalize_failed" | "unreachable";
|
|
88
89
|
message: string;
|
|
89
|
-
kind: "brain.error";
|
|
90
90
|
streamId: string;
|
|
91
91
|
}>]>;
|
|
92
92
|
type ConnectorUpFrame = z.infer<typeof ConnectorUpFrame>;
|
package/dist/brain/index.js
CHANGED
|
@@ -1782,6 +1782,41 @@ z.object({
|
|
|
1782
1782
|
toolCalls: z.array(ToolCallAudit),
|
|
1783
1783
|
mcpInteractions: z.array(McpInteractionAudit)
|
|
1784
1784
|
});
|
|
1785
|
+
var WEBHOOK_EVENT_TYPES = ["call.started", "call.ended", "recording.ready"];
|
|
1786
|
+
z.enum(WEBHOOK_EVENT_TYPES);
|
|
1787
|
+
var CallWebhookDirection = z.enum(["inbound", "outbound", "web"]);
|
|
1788
|
+
var CallWebhookOutcome = z.enum(["completed", "dropped", "failed", "no_answer", "other"]);
|
|
1789
|
+
var CallWebhookAttributes = z.record(z.union([z.string(), z.number(), z.boolean()]));
|
|
1790
|
+
var Party = z.string().min(1).nullable();
|
|
1791
|
+
z.object({
|
|
1792
|
+
callId: z.string().uuid(),
|
|
1793
|
+
startedAt: z.string().datetime(),
|
|
1794
|
+
agentId: z.string().nullable(),
|
|
1795
|
+
phoneNumberId: z.string().nullable(),
|
|
1796
|
+
callerE164: Party,
|
|
1797
|
+
toE164: Party,
|
|
1798
|
+
// Null when it can't be told yet: an inbound phone call and a web session look alike until the caller joins. When
|
|
1799
|
+
// set, it is the same value `call.ended` carries; `call.ended` always has one.
|
|
1800
|
+
direction: CallWebhookDirection.nullable()
|
|
1801
|
+
});
|
|
1802
|
+
z.object({
|
|
1803
|
+
callId: z.string().uuid(),
|
|
1804
|
+
durationMs: z.number().int().min(0),
|
|
1805
|
+
endedAt: z.string().datetime(),
|
|
1806
|
+
endReason: z.string(),
|
|
1807
|
+
agentId: z.string().nullable(),
|
|
1808
|
+
phoneNumberId: z.string().nullable(),
|
|
1809
|
+
callerE164: Party,
|
|
1810
|
+
toE164: Party,
|
|
1811
|
+
direction: CallWebhookDirection,
|
|
1812
|
+
outcome: CallWebhookOutcome,
|
|
1813
|
+
attributes: CallWebhookAttributes
|
|
1814
|
+
});
|
|
1815
|
+
z.object({
|
|
1816
|
+
callId: z.string().uuid(),
|
|
1817
|
+
recordingUrl: z.string().url(),
|
|
1818
|
+
status: z.enum(["starting", "active", "completed", "failed", "aborted"])
|
|
1819
|
+
});
|
|
1785
1820
|
var PhoneNumberStatus = z.enum([
|
|
1786
1821
|
"pending",
|
|
1787
1822
|
"active",
|