@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/dist/index.js CHANGED
@@ -1796,6 +1796,46 @@ var init_call_result = __esm({
1796
1796
  });
1797
1797
  }
1798
1798
  });
1799
+ var WEBHOOK_EVENT_TYPES, CallWebhookDirection, CallWebhookOutcome, CallWebhookAttributes, Party;
1800
+ var init_webhook_events = __esm({
1801
+ "../contracts/src/webhook-events.ts"() {
1802
+ WEBHOOK_EVENT_TYPES = ["call.started", "call.ended", "recording.ready"];
1803
+ z.enum(WEBHOOK_EVENT_TYPES);
1804
+ CallWebhookDirection = z.enum(["inbound", "outbound", "web"]);
1805
+ CallWebhookOutcome = z.enum(["completed", "dropped", "failed", "no_answer", "other"]);
1806
+ CallWebhookAttributes = z.record(z.union([z.string(), z.number(), z.boolean()]));
1807
+ Party = z.string().min(1).nullable();
1808
+ z.object({
1809
+ callId: z.string().uuid(),
1810
+ startedAt: z.string().datetime(),
1811
+ agentId: z.string().nullable(),
1812
+ phoneNumberId: z.string().nullable(),
1813
+ callerE164: Party,
1814
+ toE164: Party,
1815
+ // Null when it can't be told yet: an inbound phone call and a web session look alike until the caller joins. When
1816
+ // set, it is the same value `call.ended` carries; `call.ended` always has one.
1817
+ direction: CallWebhookDirection.nullable()
1818
+ });
1819
+ z.object({
1820
+ callId: z.string().uuid(),
1821
+ durationMs: z.number().int().min(0),
1822
+ endedAt: z.string().datetime(),
1823
+ endReason: z.string(),
1824
+ agentId: z.string().nullable(),
1825
+ phoneNumberId: z.string().nullable(),
1826
+ callerE164: Party,
1827
+ toE164: Party,
1828
+ direction: CallWebhookDirection,
1829
+ outcome: CallWebhookOutcome,
1830
+ attributes: CallWebhookAttributes
1831
+ });
1832
+ z.object({
1833
+ callId: z.string().uuid(),
1834
+ recordingUrl: z.string().url(),
1835
+ status: z.enum(["starting", "active", "completed", "failed", "aborted"])
1836
+ });
1837
+ }
1838
+ });
1799
1839
  var PhoneNumberStatus, PhoneNumberProvider, PhoneNumberCapabilities, PhoneNumberRecord;
1800
1840
  var init_numbers = __esm({
1801
1841
  "../contracts/src/numbers.ts"() {
@@ -4017,6 +4057,7 @@ var init_src = __esm({
4017
4057
  init_tests();
4018
4058
  init_call_review();
4019
4059
  init_call_result();
4060
+ init_webhook_events();
4020
4061
  init_numbers();
4021
4062
  init_project_limits();
4022
4063
  init_flow();
@@ -9352,6 +9393,12 @@ function createAgentEventEmitter() {
9352
9393
  var TextTurnReplyAccepted = z.object({ accepted: z.literal(true) });
9353
9394
  var DeleteAgentResponseSchema = z.object({ ok: z.literal(true) });
9354
9395
  var HEARTBEAT_FAILURE_DEGRADE_THRESHOLD = 3;
9396
+ function isAgentNameReservedError(err) {
9397
+ return err instanceof VoiceLayerHttpError && err.status === 422 && err.body?.error === "agent_name_reserved";
9398
+ }
9399
+ function agentNameReservedMessage(name) {
9400
+ return `[voicelayer] registration REFUSED: the agent name "${name}" is reserved for VoiceLayer's own workers (names starting "voicelayer-", the platform worker names, or ending "::text"). The agent will not appear online. Rename it in defineAgent({ name }) and restart.`;
9401
+ }
9355
9402
  var AgentsClient = class {
9356
9403
  constructor(transport, options = {}) {
9357
9404
  this.transport = transport;
@@ -9473,10 +9520,16 @@ var AgentsClient = class {
9473
9520
  ...input.mcpExposed !== void 0 ? { mcpExposed: input.mcpExposed } : {},
9474
9521
  metadata
9475
9522
  });
9476
- const response = await this.transport.request(
9477
- { method: "POST", path: "/v1/agents/register", body },
9478
- RegisterAgentResponse
9479
- );
9523
+ let response;
9524
+ try {
9525
+ response = await this.transport.request(
9526
+ { method: "POST", path: "/v1/agents/register", body },
9527
+ RegisterAgentResponse
9528
+ );
9529
+ } catch (err) {
9530
+ if (isAgentNameReservedError(err)) console.error(agentNameReservedMessage(body.name));
9531
+ throw err;
9532
+ }
9480
9533
  events.emit({ type: "registered", agent: response.agent });
9481
9534
  const cadence = opts.heartbeatIntervalMs ?? response.heartbeatIntervalMs ?? AGENT_HEARTBEAT_INTERVAL_MS;
9482
9535
  const state = {
@@ -9671,11 +9724,16 @@ var HeartbeatTicker = class {
9671
9724
  this.state.consecutiveFailures = 0;
9672
9725
  } catch (reErr) {
9673
9726
  this.state.consecutiveFailures += 1;
9727
+ const reserved = isAgentNameReservedError(reErr);
9728
+ if (reserved) {
9729
+ this.stopped = true;
9730
+ console.error(agentNameReservedMessage(this.state.registerInput.body.name));
9731
+ }
9674
9732
  this.opts.events.emit({
9675
9733
  type: "heartbeat_error",
9676
9734
  error: reErr instanceof Error ? reErr : new Error(String(reErr)),
9677
9735
  consecutiveFailures: this.state.consecutiveFailures,
9678
- willRetry: true
9736
+ willRetry: !reserved
9679
9737
  });
9680
9738
  }
9681
9739
  return;
@@ -1,4 +1,4 @@
1
- export { ab as GraphTraceEvent, ac as LiveTextConversation, ad as LiveTurnResult, ae as RunLiveTextOptions, u as RunTextSessionOptions, v as RunTextTranscriptOptions, V as TextSession, W as TextTranscriptResult, af as runLiveTextConversation, a8 as runTextSession, a9 as runTextTranscript, ag as runWithOpenAIScope } from '../text-session-BB0dLLH2.js';
1
+ export { ab as GraphTraceEvent, ac as LiveTextConversation, ad as LiveTurnResult, ae as RunLiveTextOptions, u as RunTextSessionOptions, v as RunTextTranscriptOptions, V as TextSession, W as TextTranscriptResult, af as runLiveTextConversation, a8 as runTextSession, a9 as runTextTranscript, ag as runWithOpenAIScope } from '../text-session-CtXihRr6.js';
2
2
  import '@livekit/agents';
3
3
  import 'zod';
4
4
  import 'openai';
@@ -1682,6 +1682,46 @@ var init_call_result = __esm({
1682
1682
  });
1683
1683
  }
1684
1684
  });
1685
+ var WEBHOOK_EVENT_TYPES, CallWebhookDirection, CallWebhookOutcome, CallWebhookAttributes, Party;
1686
+ var init_webhook_events = __esm({
1687
+ "../contracts/src/webhook-events.ts"() {
1688
+ WEBHOOK_EVENT_TYPES = ["call.started", "call.ended", "recording.ready"];
1689
+ z.enum(WEBHOOK_EVENT_TYPES);
1690
+ CallWebhookDirection = z.enum(["inbound", "outbound", "web"]);
1691
+ CallWebhookOutcome = z.enum(["completed", "dropped", "failed", "no_answer", "other"]);
1692
+ CallWebhookAttributes = z.record(z.union([z.string(), z.number(), z.boolean()]));
1693
+ Party = z.string().min(1).nullable();
1694
+ z.object({
1695
+ callId: z.string().uuid(),
1696
+ startedAt: z.string().datetime(),
1697
+ agentId: z.string().nullable(),
1698
+ phoneNumberId: z.string().nullable(),
1699
+ callerE164: Party,
1700
+ toE164: Party,
1701
+ // Null when it can't be told yet: an inbound phone call and a web session look alike until the caller joins. When
1702
+ // set, it is the same value `call.ended` carries; `call.ended` always has one.
1703
+ direction: CallWebhookDirection.nullable()
1704
+ });
1705
+ z.object({
1706
+ callId: z.string().uuid(),
1707
+ durationMs: z.number().int().min(0),
1708
+ endedAt: z.string().datetime(),
1709
+ endReason: z.string(),
1710
+ agentId: z.string().nullable(),
1711
+ phoneNumberId: z.string().nullable(),
1712
+ callerE164: Party,
1713
+ toE164: Party,
1714
+ direction: CallWebhookDirection,
1715
+ outcome: CallWebhookOutcome,
1716
+ attributes: CallWebhookAttributes
1717
+ });
1718
+ z.object({
1719
+ callId: z.string().uuid(),
1720
+ recordingUrl: z.string().url(),
1721
+ status: z.enum(["starting", "active", "completed", "failed", "aborted"])
1722
+ });
1723
+ }
1724
+ });
1685
1725
  var PhoneNumberStatus, PhoneNumberProvider, PhoneNumberCapabilities, PhoneNumberRecord;
1686
1726
  var init_numbers = __esm({
1687
1727
  "../contracts/src/numbers.ts"() {
@@ -3553,6 +3593,7 @@ var init_src = __esm({
3553
3593
  init_tests();
3554
3594
  init_call_review();
3555
3595
  init_call_result();
3596
+ init_webhook_events();
3556
3597
  init_numbers();
3557
3598
  init_project_limits();
3558
3599
  init_flow();