@voicelayer/sdk 0.2.0 → 0.3.0

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 CHANGED
@@ -328,6 +328,14 @@ export DEEPGRAM_API_KEY=...
328
328
  node agent.ts start
329
329
  ```
330
330
 
331
+ ### Texts
332
+
333
+ The same worker answers texts — SMS replies, Discord, your website's chat widget, the dashboard playground. `.start()`
334
+ registers a second LiveKit name, `<name>::text`, beside the voice one; each message is dispatched to it and runs as
335
+ your agent: its tools, security, connectors and model, with the conversation so far. Over text `ctx.call.callerId` is
336
+ the sender, `ctx.call.metadata.mode` is `'text'`, and call-only methods (`handoff`, `endCall`, `ask`, DTMF) throw. In
337
+ production the text registration's health server listens on `VL_TEXT_TURN_PORT` (default 8082).
338
+
331
339
  ---
332
340
 
333
341
  ## What's *not* in this SDK
@@ -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";
83
82
  code: "upstream_timeout" | "upstream_error" | "bad_response" | "normalize_failed" | "unreachable";
84
83
  message: string;
84
+ kind: "brain.error";
85
85
  streamId: string;
86
86
  }, {
87
- kind: "brain.error";
88
87
  code: "upstream_timeout" | "upstream_error" | "bad_response" | "normalize_failed" | "unreachable";
89
88
  message: string;
89
+ kind: "brain.error";
90
90
  streamId: string;
91
91
  }>]>;
92
92
  type ConnectorUpFrame = z.infer<typeof ConnectorUpFrame>;
@@ -685,6 +685,10 @@ z.object({
685
685
  // fail registration outright (which agent.ts swallows → agent runs but never
686
686
  // registers/heartbeats).
687
687
  prompt: z.string().max(64e3).nullable().optional(),
688
+ // The text-turn protocol this worker speaks (burn-down G-4): it registers `<name>::text` and runs text turns as the
689
+ // agent. Absent = it can't (an older SDK, a puppet, a flow pool) — stored as null, so a downgrade stops text turns.
690
+ // Any version is accepted (a newer SDK never fails registration); the API decides which versions it dispatches to.
691
+ textTurns: z.number().int().min(1).max(1e3).optional(),
688
692
  // Opt into MCP exposure. When true the API upserts a matching agent_config
689
693
  // row keyed by (project_id, name, environment) so MCP / dashboard / REST
690
694
  // can list and inspect this agent's identity. When false / omitted, the
@@ -705,8 +709,8 @@ var AgentDTO = z.object({
705
709
  metadata: AgentMetadata,
706
710
  processSchema: ProcessSchemaDTO.nullable().optional(),
707
711
  // Whether this agent can run through the engine over text: a flow agent (its
708
- // compiled graph rides in processSchema.program) OR a code-first agent whose
709
- // base prompt was synced on register. Drives the dashboard's chat gate so it
712
+ // compiled graph rides in processSchema.program), a brain-connector agent, OR a
713
+ // code-first agent whose worker takes text turns (G-4). Drives the dashboard's chat gate so it
710
714
  // no longer hard-codes "flow only". Computed server-side; not stored. OPTIONAL
711
715
  // on the wire so a new worker validating a response from an OLD api pod during
712
716
  // a rolling deploy doesn't fail register/heartbeat on a missing field.
@@ -932,6 +936,50 @@ z.object({
932
936
  code: z.string().max(64).optional(),
933
937
  detail: z.string().max(500).optional()
934
938
  });
939
+ z.object({
940
+ mode: z.literal("text"),
941
+ turnId: z.string().uuid(),
942
+ projectId: z.string().min(1),
943
+ agentId: z.string().uuid()
944
+ });
945
+ var TextTurnHistoryEntry = z.object({
946
+ role: z.enum(["user", "assistant"]),
947
+ content: z.string().max(16e3)
948
+ });
949
+ z.object({
950
+ turnId: z.string().uuid(),
951
+ agentId: z.string().uuid(),
952
+ /** The Line the message came in on (`sms`, `discord`, `web`, `playground`, …). */
953
+ channel: z.string().min(1).max(40),
954
+ /** The sender on that Line (phone number, Discord user, widget visitor) — the agent's caller-scoped memory key. */
955
+ from: z.string().min(1).max(200),
956
+ /** The conversation this turn belongs to (stable across turns) — the tool context's call id. */
957
+ conversationKey: z.string().min(1).max(300),
958
+ history: z.array(TextTurnHistoryEntry).max(80),
959
+ text: z.string().min(1).max(8e3),
960
+ /** When the API stops waiting; the worker stops the run before it. */
961
+ deadlineAt: z.string().datetime()
962
+ });
963
+ var TextTurnUsage = z.object({
964
+ provider: z.string().min(1).max(60),
965
+ model: z.string().min(1).max(200),
966
+ inputTokens: z.number().int().nonnegative(),
967
+ outputTokens: z.number().int().nonnegative(),
968
+ /** Only a first-party worker's label is used; a customer's worker runs on its own key (the API decides). */
969
+ byok: z.boolean()
970
+ });
971
+ var TextTurnErrorCode = z.enum(["agent_unavailable", "agent_timeout"]);
972
+ z.union([
973
+ z.object({
974
+ agentId: z.string().uuid(),
975
+ replies: z.array(z.string().max(16e3)).max(20),
976
+ usage: z.array(TextTurnUsage).max(50).default([])
977
+ }),
978
+ z.object({
979
+ agentId: z.string().uuid(),
980
+ error: z.object({ code: TextTurnErrorCode, detail: z.string().max(500).optional() })
981
+ })
982
+ ]);
935
983
  var VoiceConfig = z.object({
936
984
  // Finite, vetted list — platform-level enum.
937
985
  provider: z.enum(["deepgram", "elevenlabs", "openai", "cartesia"]),