@voicelayer/sdk 0.3.1 → 0.4.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.
@@ -654,7 +654,7 @@ var init_consultation = __esm({
654
654
  });
655
655
  }
656
656
  });
657
- var CallEventKind, OP_CALL_EVENT_KIND, OpCallEventKind, commandId, SayCommand, HangupCommand, DtmfCommand, InstructCommand;
657
+ var CallEventKind, OP_CALL_EVENT_KIND, OpCallEventKind, commandId, SayCommand, HangupCommand, DtmfCommand, InstructCommand, InjectContextCommand;
658
658
  var init_call_events = __esm({
659
659
  "../contracts/src/call-events.ts"() {
660
660
  init_consultation();
@@ -677,7 +677,10 @@ var init_call_events = __esm({
677
677
  // presses a key on their leg; `dtmf.sent` fires when our agent (or a
678
678
  // programmatic caller via /v1/calls/:id/dtmf) emits one outbound.
679
679
  "dtmf.received",
680
- "dtmf.sent"
680
+ "dtmf.sent",
681
+ // A host's runtime intervention (burn-down G-6): call_say / call_send_guidance / call_inject_context / call_instruct,
682
+ // with masked args and the API key — written by the API only, never through the worker's /events endpoint.
683
+ "mcp.interaction"
681
684
  ]);
682
685
  OP_CALL_EVENT_KIND = /^(tool|handoff|lookup|record|notify|engine)\.[a-z0-9_]{1,48}(\.[a-z0-9_]{1,48})?$/;
683
686
  OpCallEventKind = z.string().regex(OP_CALL_EVENT_KIND);
@@ -723,7 +726,7 @@ var init_call_events = __esm({
723
726
  payload: z.unknown(),
724
727
  ts: z.string().datetime()
725
728
  });
726
- z.enum(["say", "hangup", "dtmf", "instruct", "guidance"]);
729
+ z.enum(["say", "hangup", "dtmf", "instruct", "inject_context", "guidance"]);
727
730
  commandId = z.string().uuid().optional();
728
731
  SayCommand = z.object({
729
732
  kind: z.literal("say"),
@@ -746,20 +749,26 @@ var init_call_events = __esm({
746
749
  InstructCommand = z.object({
747
750
  kind: z.literal("instruct"),
748
751
  commandId,
749
- text: z.string().min(1)
752
+ text: z.string().min(1).max(4e3)
753
+ });
754
+ InjectContextCommand = z.object({
755
+ kind: z.literal("inject_context"),
756
+ commandId,
757
+ text: z.string().min(1).max(4e3)
750
758
  });
751
759
  z.discriminatedUnion("kind", [
752
760
  SayCommand,
753
761
  HangupCommand,
754
762
  DtmfCommand,
755
763
  InstructCommand,
764
+ InjectContextCommand,
756
765
  GuidanceCommand
757
766
  ]);
758
767
  z.object({
759
768
  commandId: z.string().uuid(),
760
769
  outcome: z.enum(["applied", "refused", "failed"]),
761
770
  // machine code: output_blocked · not_supported · unknown_consultation · no_consultation · invalid_command ·
762
- // say_unavailable · dtmf_unavailable
771
+ // say_unavailable · dtmf_unavailable · context_full · instructions_unavailable
763
772
  code: z.string().max(64).optional(),
764
773
  detail: z.string().max(500).optional()
765
774
  });
@@ -1609,40 +1618,6 @@ var init_call_review = __esm({
1609
1618
  });
1610
1619
  }
1611
1620
  });
1612
- var ToolExposure;
1613
- var init_agent_tools = __esm({
1614
- "../contracts/src/agent-tools.ts"() {
1615
- ToolExposure = z.enum(["agent", "mcp"]);
1616
- z.object({
1617
- name: z.string().min(1).max(64).regex(/^[a-z][a-z0-9_]*$/, "snake_case"),
1618
- // The string that routes the LLM/orchestrator to invoke this tool.
1619
- description: z.string().min(1).max(2e3),
1620
- // Zod serialized to JSON Schema at registration time. Persisted as
1621
- // JSON Schema; SDK and dashboard rehydrate to Zod when needed.
1622
- inputSchema: z.record(z.unknown()),
1623
- // When present, the runtime validates the handler's return value.
1624
- outputSchema: z.record(z.unknown()).optional(),
1625
- exposedVia: z.array(ToolExposure).min(1),
1626
- // ── Tool/Plugin SDK (PRD P0.2). All optional for back-compat. ──
1627
- // Latency class (PRD §4.6.3). Runtime defaults to 'in_call' when omitted.
1628
- mode: z.enum(["in_call", "async_only"]).optional(),
1629
- // Hard timeout for an in-call tool (ms).
1630
- timeoutMs: z.number().int().min(50).max(6e4).optional(),
1631
- // 'connection' resolves a credential from the vault by `connectionRef`.
1632
- auth: z.enum(["none", "connection"]).optional(),
1633
- connectionRef: z.string().max(128).optional(),
1634
- // Retry policy for safe/async verbs.
1635
- retry: z.object({
1636
- maxAttempts: z.number().int().min(1).max(5),
1637
- backoffMs: z.number().int().min(0).max(6e4)
1638
- }).optional(),
1639
- // Normalized result kinds the flow/decision layer branches on (result.kind).
1640
- resultKinds: z.array(z.string().min(1).max(64)).max(24).optional(),
1641
- // Free-form dashboard metadata (icon, group, etc.). No `category` enum.
1642
- metadata: z.record(z.unknown()).optional()
1643
- });
1644
- }
1645
- });
1646
1621
  var TranscriptTurn, ConsultationAudit, ToolCallAudit, McpInteractionAudit;
1647
1622
  var init_call_result = __esm({
1648
1623
  "../contracts/src/call-result.ts"() {
@@ -1662,24 +1637,28 @@ var init_call_result = __esm({
1662
1637
  latencyMs: z.number().int().min(0)
1663
1638
  });
1664
1639
  ToolCallAudit = z.object({
1640
+ invocationId: z.string(),
1665
1641
  toolName: z.string(),
1666
- // Verbatim args the LLM produced. May contain PII — see open question O2
1667
- // in docs/architecture/contracts-design.md §5.
1668
- args: z.record(z.unknown()),
1669
- result: z.unknown(),
1642
+ args: z.string(),
1643
+ result: z.string().optional(),
1670
1644
  startedAt: z.string().datetime(),
1671
1645
  durationMs: z.number().int().min(0),
1672
1646
  ok: z.boolean(),
1647
+ // refused by the Action Guard before it ran
1648
+ blocked: z.boolean(),
1673
1649
  errorMessage: z.string().optional()
1674
1650
  });
1675
1651
  McpInteractionAudit = z.object({
1676
1652
  // One of the four runtime tools — closed set, no growth allowed.
1677
1653
  tool: z.enum(["call_say", "call_send_guidance", "call_inject_context", "call_instruct"]),
1678
- // Args verbatim — see open question O2.
1654
+ // Args with PII masked (burn-down G-6, owner decision: the audit never keeps a raw value).
1679
1655
  args: z.record(z.unknown()),
1680
1656
  ts: z.string().datetime(),
1681
1657
  // Attribution. The API key that drove the orchestrator session.
1682
- apiKeyId: z.string()
1658
+ apiKeyId: z.string(),
1659
+ // 'applied' = the agent confirmed it; 'unknown' = sent, but no confirmation in time (a 504 to the host — it may have
1660
+ // been applied).
1661
+ outcome: z.enum(["applied", "unknown"])
1683
1662
  });
1684
1663
  z.object({
1685
1664
  callId: z.string().uuid(),
@@ -3512,7 +3491,6 @@ var init_src = __esm({
3512
3491
  init_evaluations();
3513
3492
  init_tests();
3514
3493
  init_call_review();
3515
- init_agent_tools();
3516
3494
  init_call_result();
3517
3495
  init_numbers();
3518
3496
  init_project_limits();
@@ -4458,7 +4436,10 @@ ${text}`
4458
4436
  await handle.waitForPlayout();
4459
4437
  graphLog("said", { chars: text.length, interrupted: handle.interrupted });
4460
4438
  }
4461
- async function genReply(deps, instructions) {
4439
+ async function genReply(deps, nodeInstructions) {
4440
+ const instructions = deps.realtime && deps.live ? `${deps.live.full()}
4441
+
4442
+ ${nodeInstructions}` : nodeInstructions;
4462
4443
  if (deps.ctx.adapter) {
4463
4444
  await deps.ctx.adapter.generateReply({ instructions });
4464
4445
  return;
@@ -5120,7 +5101,9 @@ ${collected}`);
5120
5101
  let turnResult;
5121
5102
  try {
5122
5103
  turnResult = await runner({
5123
- instructions: parts.join("\n\n"),
5104
+ // an out-of-band completion: it sees none of the agent's instructions, so the host's layers (and the seal —
5105
+ // the caller's words are in these instructions) ride in front (burn-down G-6)
5106
+ instructions: [deps.live?.additions(), ...parts].filter(Boolean).join("\n\n"),
5124
5107
  transcript,
5125
5108
  tools: agentTools,
5126
5109
  exits: exitOptions,
@@ -5277,6 +5260,7 @@ ${collected}`);
5277
5260
  ...deps.history ? { history: deps.history } : {},
5278
5261
  ...deps.realtime ? { realtime: true } : {},
5279
5262
  ...deps.resolvers ? { resolvers: deps.resolvers } : {},
5263
+ ...deps.live ? { live: deps.live } : {},
5280
5264
  depth: depth + 1
5281
5265
  });
5282
5266
  deps.events.note("subflow.exit", { node: node.id, ref, outcome: outcome.kind });
@@ -5380,7 +5364,8 @@ async function runFlowGraph(program, deps) {
5380
5364
  ...deps.realtime ? { realtime: true } : {},
5381
5365
  ...deps.resolvers ? { resolvers: deps.resolvers } : {},
5382
5366
  ...deps.depth !== void 0 ? { depth: deps.depth } : {},
5383
- ...deps.busy ? { busy: deps.busy } : {}
5367
+ ...deps.busy ? { busy: deps.busy } : {},
5368
+ ...deps.live ? { live: deps.live } : {}
5384
5369
  });
5385
5370
  } catch (err) {
5386
5371
  const message = err instanceof Error ? err.message : String(err);
@@ -5784,7 +5769,8 @@ async function runFlowProgram(program, ctx, opts) {
5784
5769
  ...opts.maxNodeVisits !== void 0 ? { maxNodeVisits: opts.maxNodeVisits } : {},
5785
5770
  ...opts.realtime ? { realtime: true } : {},
5786
5771
  ...opts.resolvers ? { resolvers: opts.resolvers } : {},
5787
- ...opts.busy ? { busy: opts.busy } : {}
5772
+ ...opts.busy ? { busy: opts.busy } : {},
5773
+ ...opts.live ? { live: opts.live } : {}
5788
5774
  });
5789
5775
  graphLog("outcome", outcome);
5790
5776
  return outcome;
@@ -6648,7 +6634,9 @@ function createTextSessionAdapter(transport) {
6648
6634
  canBargeIn: false,
6649
6635
  canReceiveDtmf: false,
6650
6636
  canPublishDtmf: false,
6651
- canResolveSpeaker: true
6637
+ canResolveSpeaker: true,
6638
+ // a text turn has no live session to steer
6639
+ canUpdateInstructions: false
6652
6640
  };
6653
6641
  const adapter = {
6654
6642
  capabilities,
@@ -6691,6 +6679,9 @@ function createTextSessionAdapter(transport) {
6691
6679
  await transport.send(text);
6692
6680
  return { interrupted: false };
6693
6681
  },
6682
+ async setInstructions() {
6683
+ throw new Error("setInstructions unsupported: canUpdateInstructions=false");
6684
+ },
6694
6685
  async enqueueSay(text) {
6695
6686
  fire("agent_turn", { text });
6696
6687
  await transport.send(text);