@voicelayer/sdk 0.4.1 → 0.5.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.
@@ -1,5 +1,6 @@
1
1
  import { JobContext, voice } from '@livekit/agents';
2
2
  import { z } from 'zod';
3
+ import { O as OnQuery } from './types-KqrAfY85.js';
3
4
  import OpenAI from 'openai';
4
5
 
5
6
  type SessionState = 'initializing' | 'idle' | 'listening' | 'thinking' | 'speaking';
@@ -14,6 +15,8 @@ interface UserInputEvent {
14
15
  }
15
16
  interface AgentTurnEvent {
16
17
  readonly text: string;
18
+ /** The caller cut the line off (barge-in). Its echo can land after the caller's turn, so it never takes the floor. */
19
+ readonly interrupted?: boolean;
17
20
  }
18
21
  interface DtmfEvent$1 {
19
22
  readonly digit: string;
@@ -240,7 +243,7 @@ interface UserTurn {
240
243
  }
241
244
  interface FakeSessionAdapter extends SessionAdapter {
242
245
  emitUserInput(e: UserInputEvent): void;
243
- emitAgentTurn(text: string): void;
246
+ emitAgentTurn(text: string, interrupted?: boolean): void;
244
247
  emitDtmf(digit: string): void;
245
248
  /** Drives 'state' with correct oldState/rawOldState AND runs the SAME
246
249
  * arm/cancel + idle-release as production. Unknown string => 'thinking'. */
@@ -366,6 +369,9 @@ declare const ProcessSchemaDTO: z.ZodObject<{
366
369
  max: z.ZodOptional<z.ZodNumber>;
367
370
  enum: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
368
371
  ask: z.ZodOptional<z.ZodString>;
372
+ /** false ⇒ written by the agent itself (a tool's output, an assignment), never said by the caller — the runtime
373
+ * doesn't extract it from their words. Absent ⇒ the caller may say it. */
374
+ fromCaller: z.ZodOptional<z.ZodBoolean>;
369
375
  }, "strip", z.ZodTypeAny, {
370
376
  type: "string" | "number" | "boolean" | "string[]" | "datetime" | "email" | "phone";
371
377
  name: string;
@@ -375,6 +381,7 @@ declare const ProcessSchemaDTO: z.ZodObject<{
375
381
  min?: number | undefined;
376
382
  max?: number | undefined;
377
383
  enum?: string[] | undefined;
384
+ fromCaller?: boolean | undefined;
378
385
  }, {
379
386
  type: "string" | "number" | "boolean" | "string[]" | "datetime" | "email" | "phone";
380
387
  name: string;
@@ -384,30 +391,36 @@ declare const ProcessSchemaDTO: z.ZodObject<{
384
391
  min?: number | undefined;
385
392
  max?: number | undefined;
386
393
  enum?: string[] | undefined;
394
+ fromCaller?: boolean | undefined;
387
395
  }>, "many">;
388
396
  completionGate: z.ZodObject<{
389
397
  requiredFields: z.ZodArray<z.ZodString, "many">;
390
398
  backendAck: z.ZodOptional<z.ZodObject<{
391
399
  url: z.ZodString;
392
400
  timeoutMs: z.ZodNumber;
401
+ allowPrivateNetwork: z.ZodOptional<z.ZodBoolean>;
393
402
  }, "strip", z.ZodTypeAny, {
394
403
  url: string;
395
404
  timeoutMs: number;
405
+ allowPrivateNetwork?: boolean | undefined;
396
406
  }, {
397
407
  url: string;
398
408
  timeoutMs: number;
409
+ allowPrivateNetwork?: boolean | undefined;
399
410
  }>>;
400
411
  }, "strip", z.ZodTypeAny, {
401
412
  requiredFields: string[];
402
413
  backendAck?: {
403
414
  url: string;
404
415
  timeoutMs: number;
416
+ allowPrivateNetwork?: boolean | undefined;
405
417
  } | undefined;
406
418
  }, {
407
419
  requiredFields: string[];
408
420
  backendAck?: {
409
421
  url: string;
410
422
  timeoutMs: number;
423
+ allowPrivateNetwork?: boolean | undefined;
411
424
  } | undefined;
412
425
  }>;
413
426
  triggers: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -458,6 +471,11 @@ declare const ProcessSchemaDTO: z.ZodObject<{
458
471
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
459
472
  auth: z.ZodEnum<["none", "connection"]>;
460
473
  connectionRef: z.ZodOptional<z.ZodString>;
474
+ /**
475
+ * Self-hosted workers only: allow a private / loopback address (a localhost service of your own). A platform
476
+ * worker (it holds the internal service token) never honours it.
477
+ */
478
+ allowPrivateNetwork: z.ZodOptional<z.ZodBoolean>;
461
479
  }, "strip", z.ZodTypeAny, {
462
480
  name: string;
463
481
  url: string;
@@ -465,6 +483,7 @@ declare const ProcessSchemaDTO: z.ZodObject<{
465
483
  input: Record<string, "string" | "number" | "boolean">;
466
484
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
467
485
  auth: "none" | "connection";
486
+ allowPrivateNetwork?: boolean | undefined;
468
487
  headers?: Record<string, string> | undefined;
469
488
  connectionRef?: string | undefined;
470
489
  }, {
@@ -474,9 +493,11 @@ declare const ProcessSchemaDTO: z.ZodObject<{
474
493
  input: Record<string, "string" | "number" | "boolean">;
475
494
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
476
495
  auth: "none" | "connection";
496
+ allowPrivateNetwork?: boolean | undefined;
477
497
  headers?: Record<string, string> | undefined;
478
498
  connectionRef?: string | undefined;
479
499
  }>, "many">>;
500
+ displayName: z.ZodOptional<z.ZodString>;
480
501
  speech: z.ZodOptional<z.ZodObject<{
481
502
  interruption: z.ZodOptional<z.ZodObject<{
482
503
  enabled: z.ZodOptional<z.ZodBoolean>;
@@ -646,6 +667,7 @@ declare const ProcessSchemaDTO: z.ZodObject<{
646
667
  backendAck?: {
647
668
  url: string;
648
669
  timeoutMs: number;
670
+ allowPrivateNetwork?: boolean | undefined;
649
671
  } | undefined;
650
672
  };
651
673
  fields: {
@@ -657,6 +679,7 @@ declare const ProcessSchemaDTO: z.ZodObject<{
657
679
  min?: number | undefined;
658
680
  max?: number | undefined;
659
681
  enum?: string[] | undefined;
682
+ fromCaller?: boolean | undefined;
660
683
  }[];
661
684
  handoff?: {
662
685
  fallback?: string | undefined;
@@ -695,9 +718,11 @@ declare const ProcessSchemaDTO: z.ZodObject<{
695
718
  input: Record<string, "string" | "number" | "boolean">;
696
719
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
697
720
  auth: "none" | "connection";
721
+ allowPrivateNetwork?: boolean | undefined;
698
722
  headers?: Record<string, string> | undefined;
699
723
  connectionRef?: string | undefined;
700
724
  }[] | undefined;
725
+ displayName?: string | undefined;
701
726
  program?: {
702
727
  v: 1;
703
728
  id: string;
@@ -730,6 +755,7 @@ declare const ProcessSchemaDTO: z.ZodObject<{
730
755
  backendAck?: {
731
756
  url: string;
732
757
  timeoutMs: number;
758
+ allowPrivateNetwork?: boolean | undefined;
733
759
  } | undefined;
734
760
  };
735
761
  fields: {
@@ -741,6 +767,7 @@ declare const ProcessSchemaDTO: z.ZodObject<{
741
767
  min?: number | undefined;
742
768
  max?: number | undefined;
743
769
  enum?: string[] | undefined;
770
+ fromCaller?: boolean | undefined;
744
771
  }[];
745
772
  handoff?: {
746
773
  fallback?: string | undefined;
@@ -779,9 +806,11 @@ declare const ProcessSchemaDTO: z.ZodObject<{
779
806
  input: Record<string, "string" | "number" | "boolean">;
780
807
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
781
808
  auth: "none" | "connection";
809
+ allowPrivateNetwork?: boolean | undefined;
782
810
  headers?: Record<string, string> | undefined;
783
811
  connectionRef?: string | undefined;
784
812
  }[] | undefined;
813
+ displayName?: string | undefined;
785
814
  program?: {
786
815
  v: 1;
787
816
  id: string;
@@ -854,6 +883,9 @@ declare const AgentDTO: z.ZodObject<{
854
883
  max: z.ZodOptional<z.ZodNumber>;
855
884
  enum: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
856
885
  ask: z.ZodOptional<z.ZodString>;
886
+ /** false ⇒ written by the agent itself (a tool's output, an assignment), never said by the caller — the runtime
887
+ * doesn't extract it from their words. Absent ⇒ the caller may say it. */
888
+ fromCaller: z.ZodOptional<z.ZodBoolean>;
857
889
  }, "strip", z.ZodTypeAny, {
858
890
  type: "string" | "number" | "boolean" | "string[]" | "datetime" | "email" | "phone";
859
891
  name: string;
@@ -863,6 +895,7 @@ declare const AgentDTO: z.ZodObject<{
863
895
  min?: number | undefined;
864
896
  max?: number | undefined;
865
897
  enum?: string[] | undefined;
898
+ fromCaller?: boolean | undefined;
866
899
  }, {
867
900
  type: "string" | "number" | "boolean" | "string[]" | "datetime" | "email" | "phone";
868
901
  name: string;
@@ -872,30 +905,36 @@ declare const AgentDTO: z.ZodObject<{
872
905
  min?: number | undefined;
873
906
  max?: number | undefined;
874
907
  enum?: string[] | undefined;
908
+ fromCaller?: boolean | undefined;
875
909
  }>, "many">;
876
910
  completionGate: z.ZodObject<{
877
911
  requiredFields: z.ZodArray<z.ZodString, "many">;
878
912
  backendAck: z.ZodOptional<z.ZodObject<{
879
913
  url: z.ZodString;
880
914
  timeoutMs: z.ZodNumber;
915
+ allowPrivateNetwork: z.ZodOptional<z.ZodBoolean>;
881
916
  }, "strip", z.ZodTypeAny, {
882
917
  url: string;
883
918
  timeoutMs: number;
919
+ allowPrivateNetwork?: boolean | undefined;
884
920
  }, {
885
921
  url: string;
886
922
  timeoutMs: number;
923
+ allowPrivateNetwork?: boolean | undefined;
887
924
  }>>;
888
925
  }, "strip", z.ZodTypeAny, {
889
926
  requiredFields: string[];
890
927
  backendAck?: {
891
928
  url: string;
892
929
  timeoutMs: number;
930
+ allowPrivateNetwork?: boolean | undefined;
893
931
  } | undefined;
894
932
  }, {
895
933
  requiredFields: string[];
896
934
  backendAck?: {
897
935
  url: string;
898
936
  timeoutMs: number;
937
+ allowPrivateNetwork?: boolean | undefined;
899
938
  } | undefined;
900
939
  }>;
901
940
  triggers: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -946,6 +985,11 @@ declare const AgentDTO: z.ZodObject<{
946
985
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
947
986
  auth: z.ZodEnum<["none", "connection"]>;
948
987
  connectionRef: z.ZodOptional<z.ZodString>;
988
+ /**
989
+ * Self-hosted workers only: allow a private / loopback address (a localhost service of your own). A platform
990
+ * worker (it holds the internal service token) never honours it.
991
+ */
992
+ allowPrivateNetwork: z.ZodOptional<z.ZodBoolean>;
949
993
  }, "strip", z.ZodTypeAny, {
950
994
  name: string;
951
995
  url: string;
@@ -953,6 +997,7 @@ declare const AgentDTO: z.ZodObject<{
953
997
  input: Record<string, "string" | "number" | "boolean">;
954
998
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
955
999
  auth: "none" | "connection";
1000
+ allowPrivateNetwork?: boolean | undefined;
956
1001
  headers?: Record<string, string> | undefined;
957
1002
  connectionRef?: string | undefined;
958
1003
  }, {
@@ -962,9 +1007,11 @@ declare const AgentDTO: z.ZodObject<{
962
1007
  input: Record<string, "string" | "number" | "boolean">;
963
1008
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
964
1009
  auth: "none" | "connection";
1010
+ allowPrivateNetwork?: boolean | undefined;
965
1011
  headers?: Record<string, string> | undefined;
966
1012
  connectionRef?: string | undefined;
967
1013
  }>, "many">>;
1014
+ displayName: z.ZodOptional<z.ZodString>;
968
1015
  speech: z.ZodOptional<z.ZodObject<{
969
1016
  interruption: z.ZodOptional<z.ZodObject<{
970
1017
  enabled: z.ZodOptional<z.ZodBoolean>;
@@ -1134,6 +1181,7 @@ declare const AgentDTO: z.ZodObject<{
1134
1181
  backendAck?: {
1135
1182
  url: string;
1136
1183
  timeoutMs: number;
1184
+ allowPrivateNetwork?: boolean | undefined;
1137
1185
  } | undefined;
1138
1186
  };
1139
1187
  fields: {
@@ -1145,6 +1193,7 @@ declare const AgentDTO: z.ZodObject<{
1145
1193
  min?: number | undefined;
1146
1194
  max?: number | undefined;
1147
1195
  enum?: string[] | undefined;
1196
+ fromCaller?: boolean | undefined;
1148
1197
  }[];
1149
1198
  handoff?: {
1150
1199
  fallback?: string | undefined;
@@ -1183,9 +1232,11 @@ declare const AgentDTO: z.ZodObject<{
1183
1232
  input: Record<string, "string" | "number" | "boolean">;
1184
1233
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
1185
1234
  auth: "none" | "connection";
1235
+ allowPrivateNetwork?: boolean | undefined;
1186
1236
  headers?: Record<string, string> | undefined;
1187
1237
  connectionRef?: string | undefined;
1188
1238
  }[] | undefined;
1239
+ displayName?: string | undefined;
1189
1240
  program?: {
1190
1241
  v: 1;
1191
1242
  id: string;
@@ -1218,6 +1269,7 @@ declare const AgentDTO: z.ZodObject<{
1218
1269
  backendAck?: {
1219
1270
  url: string;
1220
1271
  timeoutMs: number;
1272
+ allowPrivateNetwork?: boolean | undefined;
1221
1273
  } | undefined;
1222
1274
  };
1223
1275
  fields: {
@@ -1229,6 +1281,7 @@ declare const AgentDTO: z.ZodObject<{
1229
1281
  min?: number | undefined;
1230
1282
  max?: number | undefined;
1231
1283
  enum?: string[] | undefined;
1284
+ fromCaller?: boolean | undefined;
1232
1285
  }[];
1233
1286
  handoff?: {
1234
1287
  fallback?: string | undefined;
@@ -1267,9 +1320,11 @@ declare const AgentDTO: z.ZodObject<{
1267
1320
  input: Record<string, "string" | "number" | "boolean">;
1268
1321
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
1269
1322
  auth: "none" | "connection";
1323
+ allowPrivateNetwork?: boolean | undefined;
1270
1324
  headers?: Record<string, string> | undefined;
1271
1325
  connectionRef?: string | undefined;
1272
1326
  }[] | undefined;
1327
+ displayName?: string | undefined;
1273
1328
  program?: {
1274
1329
  v: 1;
1275
1330
  id: string;
@@ -1324,6 +1379,7 @@ declare const AgentDTO: z.ZodObject<{
1324
1379
  backendAck?: {
1325
1380
  url: string;
1326
1381
  timeoutMs: number;
1382
+ allowPrivateNetwork?: boolean | undefined;
1327
1383
  } | undefined;
1328
1384
  };
1329
1385
  fields: {
@@ -1335,6 +1391,7 @@ declare const AgentDTO: z.ZodObject<{
1335
1391
  min?: number | undefined;
1336
1392
  max?: number | undefined;
1337
1393
  enum?: string[] | undefined;
1394
+ fromCaller?: boolean | undefined;
1338
1395
  }[];
1339
1396
  handoff?: {
1340
1397
  fallback?: string | undefined;
@@ -1373,9 +1430,11 @@ declare const AgentDTO: z.ZodObject<{
1373
1430
  input: Record<string, "string" | "number" | "boolean">;
1374
1431
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
1375
1432
  auth: "none" | "connection";
1433
+ allowPrivateNetwork?: boolean | undefined;
1376
1434
  headers?: Record<string, string> | undefined;
1377
1435
  connectionRef?: string | undefined;
1378
1436
  }[] | undefined;
1437
+ displayName?: string | undefined;
1379
1438
  program?: {
1380
1439
  v: 1;
1381
1440
  id: string;
@@ -1428,6 +1487,7 @@ declare const AgentDTO: z.ZodObject<{
1428
1487
  backendAck?: {
1429
1488
  url: string;
1430
1489
  timeoutMs: number;
1490
+ allowPrivateNetwork?: boolean | undefined;
1431
1491
  } | undefined;
1432
1492
  };
1433
1493
  fields: {
@@ -1439,6 +1499,7 @@ declare const AgentDTO: z.ZodObject<{
1439
1499
  min?: number | undefined;
1440
1500
  max?: number | undefined;
1441
1501
  enum?: string[] | undefined;
1502
+ fromCaller?: boolean | undefined;
1442
1503
  }[];
1443
1504
  handoff?: {
1444
1505
  fallback?: string | undefined;
@@ -1477,9 +1538,11 @@ declare const AgentDTO: z.ZodObject<{
1477
1538
  input: Record<string, "string" | "number" | "boolean">;
1478
1539
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
1479
1540
  auth: "none" | "connection";
1541
+ allowPrivateNetwork?: boolean | undefined;
1480
1542
  headers?: Record<string, string> | undefined;
1481
1543
  connectionRef?: string | undefined;
1482
1544
  }[] | undefined;
1545
+ displayName?: string | undefined;
1483
1546
  program?: {
1484
1547
  v: 1;
1485
1548
  id: string;
@@ -1510,6 +1573,57 @@ declare const AgentDTO: z.ZodObject<{
1510
1573
  }>;
1511
1574
  type AgentDTO = z.infer<typeof AgentDTO>;
1512
1575
 
1576
+ /** Policy embedded in AgentConfig — caps + UX wording. */
1577
+ declare const ConsultationPolicy: z.ZodObject<{
1578
+ enabled: z.ZodDefault<z.ZodBoolean>;
1579
+ defaultTimeoutMs: z.ZodDefault<z.ZodNumber>;
1580
+ maxTimeoutMs: z.ZodDefault<z.ZodNumber>;
1581
+ maxCumulativeHoldMs: z.ZodDefault<z.ZodNumber>;
1582
+ holdPhrase: z.ZodDefault<z.ZodString>;
1583
+ fallbackPhrase: z.ZodDefault<z.ZodString>;
1584
+ callEndFallback: z.ZodDefault<z.ZodString>;
1585
+ urgencyOverrides: z.ZodOptional<z.ZodObject<{
1586
+ low: z.ZodOptional<z.ZodNumber>;
1587
+ normal: z.ZodOptional<z.ZodNumber>;
1588
+ high: z.ZodOptional<z.ZodNumber>;
1589
+ }, "strip", z.ZodTypeAny, {
1590
+ low?: number | undefined;
1591
+ high?: number | undefined;
1592
+ normal?: number | undefined;
1593
+ }, {
1594
+ low?: number | undefined;
1595
+ high?: number | undefined;
1596
+ normal?: number | undefined;
1597
+ }>>;
1598
+ }, "strip", z.ZodTypeAny, {
1599
+ enabled: boolean;
1600
+ defaultTimeoutMs: number;
1601
+ maxTimeoutMs: number;
1602
+ maxCumulativeHoldMs: number;
1603
+ holdPhrase: string;
1604
+ fallbackPhrase: string;
1605
+ callEndFallback: string;
1606
+ urgencyOverrides?: {
1607
+ low?: number | undefined;
1608
+ high?: number | undefined;
1609
+ normal?: number | undefined;
1610
+ } | undefined;
1611
+ }, {
1612
+ enabled?: boolean | undefined;
1613
+ defaultTimeoutMs?: number | undefined;
1614
+ maxTimeoutMs?: number | undefined;
1615
+ maxCumulativeHoldMs?: number | undefined;
1616
+ holdPhrase?: string | undefined;
1617
+ fallbackPhrase?: string | undefined;
1618
+ callEndFallback?: string | undefined;
1619
+ urgencyOverrides?: {
1620
+ low?: number | undefined;
1621
+ high?: number | undefined;
1622
+ normal?: number | undefined;
1623
+ } | undefined;
1624
+ }>;
1625
+ type ConsultationPolicy = z.infer<typeof ConsultationPolicy>;
1626
+
1513
1627
  declare const FlowProgram: z.ZodObject<{
1514
1628
  v: z.ZodLiteral<1>;
1515
1629
  id: z.ZodString;
@@ -1653,6 +1767,7 @@ interface GateSpec {
1653
1767
  readonly backendAck?: {
1654
1768
  readonly url: string;
1655
1769
  readonly timeoutMs: number;
1770
+ readonly allowPrivateNetwork?: boolean;
1656
1771
  };
1657
1772
  }
1658
1773
  /**
@@ -1938,20 +2053,719 @@ declare function dtmfDigitToCode(digit: string): number | null;
1938
2053
  /** Inverse of dtmfDigitToCode. Returns null for codes outside 0..15. */
1939
2054
  declare function dtmfCodeToDigit(code: number): string | null;
1940
2055
 
2056
+ interface ReadinessResult {
2057
+ readonly ok: boolean;
2058
+ /** Human-readable explanation when ok=false. Surfaced in metadata. */
2059
+ readonly detail?: string;
2060
+ }
2061
+ interface ReadinessProbe {
2062
+ readonly name: string;
2063
+ check(): Promise<ReadinessResult>;
2064
+ }
2065
+ /** Aggregate result the SDK records in metadata.readiness. */
2066
+ interface ReadinessReport {
2067
+ readonly probe: string;
2068
+ readonly ok: boolean;
2069
+ readonly detail?: string;
2070
+ }
2071
+ /**
2072
+ * Run all probes in parallel. A probe that throws is reported as not-ok with
2073
+ * the error message as detail; one bad probe never sinks the others.
2074
+ */
2075
+ declare function runProbes(probes: readonly ReadinessProbe[]): Promise<ReadinessReport[]>;
2076
+ /** Probe that passes iff process.env[name] is non-empty after trimming. */
2077
+ declare function envProbe(name: string): ReadinessProbe;
2078
+ /**
2079
+ * Probe wrapping an arbitrary async function. Returning a value (or void)
2080
+ * means ok; throwing means not-ok. Compact escape hatch — promote to a real
2081
+ * probe class when reuse appears.
2082
+ */
2083
+ declare function asyncProbe(name: string, fn: () => Promise<unknown>): ReadinessProbe;
2084
+ /**
2085
+ * Probe that fetches a URL and considers any 2xx/3xx response ok. Useful for
2086
+ * upstream health-checks (e.g. an LLM gateway's /healthz). Default 3s timeout.
2087
+ */
2088
+ declare function urlProbe(name: string, url: string, opts?: {
2089
+ timeoutMs?: number;
2090
+ method?: 'GET' | 'HEAD';
2091
+ }): ReadinessProbe;
2092
+
2093
+ declare class VoiceLayerError extends Error {
2094
+ readonly name: string;
2095
+ }
2096
+ declare class VoiceLayerAuthError extends VoiceLayerError {
2097
+ readonly status: number;
2098
+ readonly name: string;
2099
+ constructor(message: string, status: number);
2100
+ }
2101
+ declare class VoiceLayerNetworkError extends VoiceLayerError {
2102
+ readonly name: string;
2103
+ readonly cause?: unknown;
2104
+ constructor(message: string, cause?: unknown);
2105
+ }
2106
+ declare class VoiceLayerValidationError extends VoiceLayerError {
2107
+ readonly issues: unknown;
2108
+ readonly name: string;
2109
+ constructor(message: string, issues: unknown);
2110
+ }
2111
+ declare class VoiceLayerHttpError extends VoiceLayerError {
2112
+ readonly status: number;
2113
+ readonly body: unknown;
2114
+ readonly name: string;
2115
+ constructor(message: string, status: number, body: unknown);
2116
+ }
2117
+
2118
+ type AgentLifecycleEvent = {
2119
+ type: 'registered';
2120
+ agent: AgentDTO;
2121
+ } | {
2122
+ type: 'readiness';
2123
+ report: readonly ReadinessReport[];
2124
+ allOk: boolean;
2125
+ } | {
2126
+ type: 'heartbeat';
2127
+ agent: AgentDTO;
2128
+ } | {
2129
+ type: 'heartbeat_error';
2130
+ error: VoiceLayerError | Error;
2131
+ consecutiveFailures: number;
2132
+ willRetry: boolean;
2133
+ } | {
2134
+ type: 'heartbeat_recovered';
2135
+ afterFailures: number;
2136
+ } | {
2137
+ type: 're_registered';
2138
+ agent: AgentDTO;
2139
+ reason: 'agent_not_found';
2140
+ } | {
2141
+ type: 'status_changed';
2142
+ status: AgentStatus;
2143
+ detail?: string;
2144
+ } | {
2145
+ type: 'metadata_updated';
2146
+ } | {
2147
+ type: 'deregistered';
2148
+ reason: 'manual' | 'signal';
2149
+ };
2150
+ type AgentEventListener = (event: AgentLifecycleEvent) => void;
2151
+ interface AgentEventEmitter {
2152
+ on(listener: AgentEventListener): () => void;
2153
+ /** @internal — used by the lifecycle to publish events. */
2154
+ emit(event: AgentLifecycleEvent): void;
2155
+ }
2156
+
2157
+ /** Primitive field types accepted in a process definition. */
2158
+ type ProcessFieldType = 'string' | 'string[]' | 'number' | 'boolean' | 'datetime' | 'email' | 'phone';
2159
+ interface ProcessField {
2160
+ readonly type: ProcessFieldType;
2161
+ readonly required?: boolean;
2162
+ /** Regex pattern for `string` / `string[]` items. */
2163
+ readonly pattern?: RegExp;
2164
+ /** Inclusive lower bound on a number or array length. */
2165
+ readonly min?: number;
2166
+ /** Inclusive upper bound on a number or array length. */
2167
+ readonly max?: number;
2168
+ /** One of N — restricts the captured value to this set. */
2169
+ readonly enum?: readonly string[];
2170
+ /** Override the auto-generated prompt for capturing this field. */
2171
+ readonly ask?: string;
2172
+ /** Override the field-extraction hint shown to the LLM. */
2173
+ readonly extract?: string;
2174
+ /** false ⇒ the agent writes this field itself (a tool's output, an assignment); it is never extracted from the
2175
+ * caller's words. Default true. */
2176
+ readonly fromCaller?: boolean;
2177
+ }
2178
+ type CompletionStrategy = 'all-required-captured' | 'all-captured' | {
2179
+ custom: (data: Record<string, unknown>, ctx: AgentContext) => boolean | Promise<boolean>;
2180
+ };
2181
+ interface ProcessBackendAck {
2182
+ /** URL to POST captured data to. The call cannot complete until this 2xx's. */
2183
+ readonly url: string;
2184
+ /** Capped at 10 s whatever is set here — the call's completion waits on it. */
2185
+ readonly timeoutMs?: number;
2186
+ readonly headers?: Readonly<Record<string, string>>;
2187
+ /**
2188
+ * Self-hosted workers only: allow a private / loopback URL (your own localhost service). Off by default. A platform
2189
+ * worker (it holds INTERNAL_SERVICE_TOKEN) never honours it.
2190
+ */
2191
+ readonly allowPrivateNetwork?: boolean;
2192
+ }
2193
+ interface ProcessDefinition<T extends Record<string, ProcessField> = Record<string, ProcessField>> {
2194
+ /** Field schema. Order is preserved when the SDK auto-asks for fields. */
2195
+ readonly collect: T;
2196
+ /** When the call can end. Defaults to 'all-required-captured'. */
2197
+ readonly completeWhen?: CompletionStrategy;
2198
+ /** Optional external system that must ACK before completion. */
2199
+ readonly backendAck?: ProcessBackendAck;
2200
+ /** Fires once all completion conditions are met. */
2201
+ readonly onComplete?: (data: InferProcessData<T>, ctx: AgentContext) => Promise<void> | void;
2202
+ /** Fires whenever a field is captured (good for live CRM updates). */
2203
+ readonly onField?: <K extends keyof T>(field: K, value: InferFieldValue<T[K]>, ctx: AgentContext) => Promise<void> | void;
2204
+ }
2205
+ /** Inferred TS type for the data bag a process produces. */
2206
+ type InferProcessData<T extends Record<string, ProcessField>> = {
2207
+ [K in keyof T]: T[K]['required'] extends true ? InferFieldValue<T[K]> : InferFieldValue<T[K]> | undefined;
2208
+ };
2209
+ type InferFieldValue<F extends ProcessField> = F['type'] extends 'string' ? string : F['type'] extends 'string[]' ? string[] : F['type'] extends 'number' ? number : F['type'] extends 'boolean' ? boolean : F['type'] extends 'datetime' ? Date : F['type'] extends 'email' ? string : F['type'] extends 'phone' ? string : never;
2210
+ type TriggerCondition = RegExp | `signal:${string}` | ((text: string, ctx: AgentContext) => boolean | Promise<boolean>);
2211
+ type TriggerAction = 'handoff' | 'endCall' | {
2212
+ say: string;
2213
+ } | {
2214
+ run: (ctx: AgentContext) => Promise<void> | void;
2215
+ }
2216
+ /** Jump the flow-graph cursor to a node id. Only meaningful under the graph
2217
+ * interpreter (the flat goals+rails path has no cursor and ignores it). */
2218
+ | {
2219
+ goto: string;
2220
+ };
2221
+ interface TriggerDefinition {
2222
+ readonly on: TriggerCondition;
2223
+ readonly then: TriggerAction;
2224
+ /** If set, the trigger only fires while the named field is uncaptured. */
2225
+ readonly onlyWhile?: string;
2226
+ }
2227
+ interface HandoffConfig {
2228
+ /** Default human number when a trigger says { then: 'handoff' }. */
2229
+ readonly fallback: string;
2230
+ /** Map signal/trigger names to specific destinations. */
2231
+ readonly routes?: Readonly<Record<string, string>>;
2232
+ /** Build the briefing text passed to the human agent (or PSTN whisper). */
2233
+ readonly briefing?: (args: {
2234
+ readonly data: Record<string, unknown>;
2235
+ readonly transcript: TranscriptHandle;
2236
+ readonly call: AgentContext['call'];
2237
+ }) => string | Promise<string>;
2238
+ /**
2239
+ * 'warm' (default) dials the human into the room as a conference, lets the
2240
+ * agent brief them live, then drops the agent — caller + human stay
2241
+ * connected. 'cold' is a blind SIP REFER: the caller is transferred away
2242
+ * immediately. Warm falls back to cold when no outbound trunk is configured.
2243
+ */
2244
+ readonly mode?: 'warm' | 'cold';
2245
+ }
2246
+ interface TranscriptHandle {
2247
+ /** Last N turns as `speaker: text` lines. */
2248
+ tail(n: number): string;
2249
+ full(): string;
2250
+ }
2251
+ /**
2252
+ * Memory scope. `'participant'` and `'caller'` are synonyms — `'caller'`
2253
+ * is the historical name from the 1:1 era; new code should prefer
2254
+ * `'participant'`, which makes the multi-party semantics explicit.
2255
+ */
2256
+ type MemoryScope = 'call' | 'caller' | 'participant' | 'account' | 'platform';
2257
+ interface MemoryConfig {
2258
+ /** Which scope to persist to. Defaults to 'caller'. */
2259
+ readonly scope?: MemoryScope;
2260
+ readonly retentionDays?: number;
2261
+ /** Fields auto-redacted on write. Recognized: ssn, dob, email, phone, ccn. */
2262
+ readonly piiFields?: readonly string[];
2263
+ /** Opt in to cross-tenant aggregate memory (anonymized). */
2264
+ readonly platformOptIn?: boolean;
2265
+ }
2266
+ /**
2267
+ * Multi-participant configuration. Optional — when omitted, the agent runs
2268
+ * in 1:1 mode (one human + one agent) and the SDK still populates
2269
+ * `ctx.room.participants` so participant-aware code paths work.
2270
+ */
2271
+ interface ParticipantsConfig {
2272
+ /**
2273
+ * Fires when a human participant joins the room. In 1:1 calls this
2274
+ * fires once at session start for the caller. In multi-party calls it
2275
+ * fires per join.
2276
+ */
2277
+ readonly onJoin?: (participant: Participant, ctx: AgentContext) => Promise<void> | void;
2278
+ /** Fires when a participant disconnects (hangup, transfer, kick). */
2279
+ readonly onLeave?: (participant: Participant, ctx: AgentContext) => Promise<void> | void;
2280
+ /**
2281
+ * Synchronously enrich a participant's attribute bag before `onJoin`
2282
+ * fires. Useful for phone-number → language lookups, etc. The returned
2283
+ * map is merged into `participant.attributes`.
2284
+ */
2285
+ readonly attributes?: (participant: Participant) => Readonly<Record<string, string>> | Promise<Readonly<Record<string, string>>>;
2286
+ /**
2287
+ * Reject participants beyond this count. Default: unlimited. The cap
2288
+ * is enforced by the worker when wiring participant lifecycle.
2289
+ */
2290
+ readonly max?: number;
2291
+ }
2292
+ /**
2293
+ * A connector instance. Created by per-system factories like `salesforce()`,
2294
+ * `twilio()`, etc. The factory returns an opaque handle that the SDK wires
2295
+ * into `ctx.connectors` and (when `expose: true`) into the LLM tool list.
2296
+ */
2297
+ interface ConnectorInstance<TName extends string = string, TApi = unknown> {
2298
+ readonly __connector: true;
2299
+ readonly name: TName;
2300
+ readonly api: TApi;
2301
+ /** If true, every method on `api` becomes an LLM-callable tool. */
2302
+ readonly expose?: boolean;
2303
+ }
2304
+ type ComplianceTag = 'tcpa' | 'hipaa' | 'pci' | 'gdpr' | 'soc2';
2305
+ /**
2306
+ * Duck-typed pipeline component markers. The SDK never inspects these — they
2307
+ * are passed through to LiveKit's AgentSession as-is. Three ways to satisfy:
2308
+ *
2309
+ * 1. SDK factory: `deepgram.tts({ model: 'aura-2' })`
2310
+ * 2. Wrapped LK: `wrap(new TTS({...}), { trace: true })`
2311
+ * 3. User-built: class MyTTS extends BaseTTS { ... } // BaseTTS
2312
+ * // re-exported
2313
+ * // from the SDK
2314
+ *
2315
+ * Anything implementing the duck-type — even a plain object — is accepted.
2316
+ */
2317
+ interface STTProvider {
2318
+ readonly __vlPipeline?: 'stt';
2319
+ }
2320
+ interface LLMProvider {
2321
+ readonly __vlPipeline?: 'llm';
2322
+ }
2323
+ interface TTSProvider {
2324
+ readonly __vlPipeline?: 'tts';
2325
+ }
2326
+ interface VADProvider {
2327
+ readonly __vlPipeline?: 'vad';
2328
+ }
2329
+ interface TurnDetectorProvider {
2330
+ readonly __vlPipeline?: 'turn';
2331
+ }
2332
+ /**
2333
+ * Speech-to-speech / realtime model marker (OpenAI Realtime, Gemini Live).
2334
+ * A realtime model handles STT + LLM + TTS + turn-taking server-side, so when
2335
+ * `models.realtime` is set the SDK builds the AgentSession around it and
2336
+ * ignores the stt/llm/tts slots.
2337
+ */
2338
+ interface RealtimeProvider {
2339
+ readonly __vlPipeline?: 'realtime';
2340
+ }
2341
+ /**
2342
+ * Lazy form so users can pick a provider per call (e.g. by caller locale).
2343
+ * The factory runs once per call, before AgentSession is constructed, so it
2344
+ * receives the call envelope (callerId, to, metadata) rather than the full
2345
+ * AgentContext (which depends on AgentSession existing).
2346
+ */
2347
+ type ProviderFactory<T> = (call: CallInfo) => T | Promise<T>;
2348
+ interface ModelConfig {
2349
+ /**
2350
+ * String form: 'openai/gpt-4o' (resolves via SDK defaults).
2351
+ * Instance form: any LLMProvider (LK plugin, wrap()-ed, or user-built).
2352
+ * Factory form: `(ctx) => provider` for per-call selection.
2353
+ */
2354
+ readonly llm?: string | LLMProvider | ProviderFactory<LLMProvider>;
2355
+ readonly stt?: string | STTProvider | ProviderFactory<STTProvider>;
2356
+ readonly tts?: string | TTSProvider | ProviderFactory<TTSProvider>;
2357
+ /** VAD has no string form — always pass an instance or factory. */
2358
+ readonly vad?: VADProvider | ProviderFactory<VADProvider>;
2359
+ readonly turnDetector?: TurnDetectorProvider | ProviderFactory<TurnDetectorProvider>;
2360
+ /**
2361
+ * Speech-to-speech / realtime model. When set, the STT→LLM→TTS pipeline is
2362
+ * bypassed: the realtime model drives the whole turn. No string form — pass
2363
+ * an instance (`openai.realtime({ voice: 'alloy' })`) or a per-call factory.
2364
+ */
2365
+ readonly realtime?: RealtimeProvider | ProviderFactory<RealtimeProvider>;
2366
+ /** Spoken language; defaults to 'en-US'. Used by string-form defaults. */
2367
+ readonly language?: string;
2368
+ }
2369
+ /**
2370
+ * Answering-machine detection mode for outbound calls. Mirrors
2371
+ * `OutboundConfig.amd` in @voicelayer/agent-spec.
2372
+ *
2373
+ * 'off' — never run AMD; treat every answer as a human.
2374
+ * 'detect' — leave the voicemail message (or hang up) the moment
2375
+ * a machine greeting is recognised.
2376
+ * 'detectMessageEnd' — recognise the machine, then wait for the greeting to
2377
+ * finish (an explicit "after the tone"-style cue or the
2378
+ * greeting going quiet) before leaving the message.
2379
+ */
2380
+ type AmdMode = 'off' | 'detect' | 'detectMessageEnd';
2381
+ /**
2382
+ * Outbound-only behavior. AMD never runs on inbound calls (the runtime gates
2383
+ * on the dispatch-metadata `direction`), so these knobs are inert unless the
2384
+ * call was placed via the outbound path.
2385
+ */
2386
+ interface OutboundCallConfig {
2387
+ /** Answering-machine detection mode. Defaults to 'off'. */
2388
+ readonly amd?: AmdMode;
2389
+ /**
2390
+ * Spoken (via TTS) when a machine is detected. When unset, the agent hangs
2391
+ * up on detection instead of leaving a message.
2392
+ */
2393
+ readonly voicemailScript?: string;
2394
+ }
2395
+ /**
2396
+ * Barge-in tuning. The pipeline allows interruptions by default (LK defaults:
2397
+ * any speech ≥500ms cuts the agent off). These knobs tune that behavior per
2398
+ * agent WITHOUT switching to puppet/hostControlled mode — e.g. a senior-living
2399
+ * help desk wants `minWords: 2` so backchannels ("mm-hm", "okay") don't
2400
+ * truncate the agent mid-sentence, while a fast-paced escalation desk keeps
2401
+ * the zero-word default. Set `enabled: false` to make the agent
2402
+ * non-interruptible (kiosk / broadcast announcements).
2403
+ */
2404
+ interface InterruptionConfig {
2405
+ /** Allow the caller to barge in over agent speech. Default true. */
2406
+ readonly enabled?: boolean;
2407
+ /** Words the caller must say before it counts as an interruption. Default 0
2408
+ * (any speech interrupts). 2–3 filters out backchannels. */
2409
+ readonly minWords?: number;
2410
+ /** Minimum caller speech duration (ms) to count as an interruption. Default 500. */
2411
+ readonly minDuration?: number;
2412
+ }
2413
+ /**
2414
+ * End-of-turn detection tuning: how long the pipeline waits after the caller
2415
+ * stops speaking before treating the turn as finished. Raise `minDelay` for
2416
+ * callers who pause mid-thought (e.g. elderly speakers); lower it for
2417
+ * fast-paced lines.
2418
+ */
2419
+ interface EndpointingConfig {
2420
+ /** Minimum silence (ms) before the caller's turn is considered done. Default 500. */
2421
+ readonly minDelay?: number;
2422
+ /** Hard ceiling (ms) after which the turn ends regardless. Default 3000. */
2423
+ readonly maxDelay?: number;
2424
+ }
2425
+ /**
2426
+ * Speech polish. `pronunciations` rewrites brand names / acronyms / jargon to
2427
+ * a spoken form before TTS (e.g. `{ VoiceLayer: 'Voice Layer', API: 'A P I' }`)
2428
+ * via applyPronunciations(). `backgroundAudio` plays ambient room tone under
2429
+ * the agent so silence feels less dead (a URL or a named preset).
2430
+ * `interruption` + `endpointing` tune barge-in and turn-taking per agent.
2431
+ */
2432
+ interface SpeechConfig {
2433
+ readonly pronunciations?: Readonly<Record<string, string>>;
2434
+ readonly backgroundAudio?: string | {
2435
+ readonly url?: string;
2436
+ readonly volume?: number;
2437
+ };
2438
+ readonly interruption?: InterruptionConfig;
2439
+ readonly endpointing?: EndpointingConfig;
2440
+ }
2441
+ /** What caused the call to end. Surfaced to `endCall.onEnd` + logs. */
2442
+ type EndCallTrigger =
2443
+ /** The LLM invoked the built-in `end_call` tool. */
2444
+ 'tool'
2445
+ /** An external controller (MCP host) sent a `hangup` command. */
2446
+ | 'host'
2447
+ /** The dead-air backstop fired (`idleHangupMs` of silence while idle). */
2448
+ | 'idle'
2449
+ /** The hard per-call ceiling fired (`maxCallDurationMs` elapsed). */
2450
+ | 'max_duration'
2451
+ /** The last non-agent participant left the room. */
2452
+ | 'participant-left'
2453
+ /** A flow/graph run finished and asked to hang up. */
2454
+ | 'flow'
2455
+ /** The realtime engine closed / disconnected under the session. */
2456
+ | 'engine-closed'
2457
+ /** `ctx.endCall()` called directly from user code. */
2458
+ | 'user';
2459
+ /** Passed to `endCall.onEnd` describing the teardown about to happen. */
2460
+ interface EndCallInfo {
2461
+ /** Why the call is ending (e.g. the `end_call` tool's `reason`). */
2462
+ readonly reason?: string;
2463
+ /** What triggered the hang-up. */
2464
+ readonly trigger: EndCallTrigger;
2465
+ /** The teardown strategy that will run (after the policy is resolved). */
2466
+ readonly teardown: 'room' | 'agent';
2467
+ }
2468
+ /**
2469
+ * Controls how the agent ENDS a call. The SDK — not the agent prompt or an
2470
+ * external puppet driver — owns teardown, so a hang-up is reliable even when
2471
+ * the realtime transport has died mid-wrap.
2472
+ *
2473
+ * Defaults are "best case" and active without opt-in: the whole LiveKit room
2474
+ * is deleted (which drops the SIP/PSTN leg too, so the carrier gets a BYE),
2475
+ * a guarantee-watchdog re-attempts teardown if the first try doesn't land, and
2476
+ * a dead-air backstop hangs up after the line has been silent too long. Every
2477
+ * knob is overridable; set a field to `false` to disable that guard.
2478
+ */
2479
+ interface EndCallPolicy {
2480
+ /**
2481
+ * Teardown strategy. `'room'` (default) deletes the LiveKit room via the
2482
+ * room service — this removes the SIP participant too, so the call actually
2483
+ * disconnects on the carrier side. `'agent'` only drops the agent's own
2484
+ * participant (leaves any SIP leg up); use it only when something else owns
2485
+ * the room lifecycle.
2486
+ */
2487
+ readonly teardown?: 'room' | 'agent';
2488
+ /**
2489
+ * After a hang-up is requested, keep re-attempting teardown until the room
2490
+ * is actually gone or this many ms elapse. Guards against a teardown call
2491
+ * that silently doesn't land (transport race, transient room-service error).
2492
+ * Default 4000. `false` disables (single best-effort attempt).
2493
+ */
2494
+ readonly guaranteeMs?: number | false;
2495
+ /**
2496
+ * Dead-air backstop: when the agent is idle (waiting on the caller) and the
2497
+ * line stays silent — no agent turn, no caller speech — for this many ms,
2498
+ * end the call. Catches a wedged session whose normal `end_call` never ran.
2499
+ * Only armed while the agent is idle, so it never interrupts agent speech or
2500
+ * a long tool call. Default 20000. `false` disables.
2501
+ */
2502
+ readonly idleHangupMs?: number | false;
2503
+ /**
2504
+ * Hard call ceiling: hang up once the call has run this many ms from when
2505
+ * the session becomes ready, regardless of activity. Catches runaway calls
2506
+ * that never end naturally (stuck loops, hijacked keys dialing premium
2507
+ * numbers). Fires with trigger `'max_duration'`. Default 3600000 (60
2508
+ * minutes). `false` disables.
2509
+ */
2510
+ readonly maxCallDurationMs?: number | false;
2511
+ /**
2512
+ * Hook fired the moment a hang-up is decided, just before teardown — for
2513
+ * every trigger (tool, host, idle, max_duration, engine-closed, …). Return
2514
+ * `false` to take over teardown yourself (the SDK then does nothing — the
2515
+ * call will NOT end unless you end it). Returning anything else (or nothing)
2516
+ * runs the default teardown. Throwing is caught + logged, then the default
2517
+ * teardown still runs (safe by default).
2518
+ *
2519
+ * EXCEPT a host hangup (`trigger: 'host'` — MCP `call_hangup`): the host is
2520
+ * the operator, so the hook is told (with the host's reason) and given 2
2521
+ * seconds, but can't keep the call open; the room is always deleted, even
2522
+ * after an earlier hang-up was vetoed and whatever `teardown` says (0.2.0).
2523
+ */
2524
+ readonly onEnd?: (ctx: AgentContext, info: EndCallInfo) => boolean | void | Promise<boolean | void>;
2525
+ }
2526
+ type ShorthandPrimitive = 'string' | 'number' | 'boolean';
2527
+ type ToolInputShape = Record<string, ShorthandPrimitive> | z.ZodTypeAny;
2528
+ interface ToolDefinition<I = unknown, R = unknown> {
2529
+ readonly description: string;
2530
+ readonly input: ToolInputShape;
2531
+ readonly run: (input: I, ctx: AgentContext) => Promise<R> | R;
2532
+ /**
2533
+ * Capability this tool requires. Action Guard hard-blocks the call if not
2534
+ * declared (PRD §B.5 — "no soft failures, ever"). Defaults to
2535
+ * `tool.<name>` when omitted; passing a domain-scoped string
2536
+ * (`crm.write`, `payment.refund`) lets multiple tools share a capability
2537
+ * for centralised policy.
2538
+ */
2539
+ readonly capability?: string;
2540
+ }
2541
+ /**
2542
+ * Optional security adapters. The SDK always enforces the local-only synchronous
2543
+ * guards (PRD §B.2 input regex, §B.3 system seal + PII tokenisation, §B.4
2544
+ * markdown strip + PII partial-mask, §B.5 capability check). Setting any of
2545
+ * these augments the local floor with external services. Each is independently
2546
+ * optional — none has to be live for the floor guards to function.
2547
+ *
2548
+ * URLs can also come from env (`SECURITY_LLM_GUARD_URL`,
2549
+ * `SECURITY_PRESIDIO_ANALYZER_URL`, `SECURITY_PRESIDIO_ANONYMIZER_URL`,
2550
+ * `SECURITY_OPA_URL`, `SECURITY_OPA_DECISION_PATH`); explicit config wins.
2551
+ */
2552
+ interface SecurityConfig {
2553
+ /** Disable the primitive entirely. Use only for tests. Production code MUST NOT set this. */
2554
+ readonly disabled?: boolean;
2555
+ /** External LLM-Guard adapter for richer injection detection. */
2556
+ readonly llmGuardUrl?: string;
2557
+ /** Presidio analyzer URL for PII detection beyond local regex. */
2558
+ readonly presidioAnalyzerUrl?: string;
2559
+ /** Presidio anonymizer URL — if set, output is redacted before TTS. */
2560
+ readonly presidioAnonymizerUrl?: string;
2561
+ /** OPA decision API base URL (e.g. `http://opa:8181`). */
2562
+ readonly opaUrl?: string;
2563
+ /** OPA decision path (e.g. `voicelayer/security/decision`). */
2564
+ readonly opaDecisionPath?: string;
2565
+ /** Per-request timeout for security adapter calls. */
2566
+ readonly adapterTimeoutMs?: number;
2567
+ }
2568
+ /**
2569
+ * Marks an agent as a *flow-runtime* worker: instead of a fixed process it
2570
+ * resolves the deployed flow from the dispatch metadata (`agentId`) at call
2571
+ * time, fetches that agent's compiled process_schema, and boots from it. One
2572
+ * process serves many flows (the shared pool). See defineFlowRuntime().
2573
+ */
2574
+ interface FlowRuntimeConfig {
2575
+ /** Prepended to the flow's compiled say/confirm prompt fragments. */
2576
+ readonly basePrompt?: string;
2577
+ /** Spoken (verbatim) before hanging up when a flow call's schema cannot be
2578
+ * loaded. A failed flow boot NEVER silently answers as a generic assistant. */
2579
+ readonly bootFailureMessage?: string;
2580
+ }
2581
+ /** Output content-moderation guard config (P5). Mirrors @voicelayer/plugin-guard's
2582
+ * GuardConfig; the pure inspector lives in runtime/guard.ts. */
2583
+ interface GuardConfig {
2584
+ /** Flag content longer than this many characters. Default 8000. */
2585
+ readonly maxLength?: number;
2586
+ /** Substrings that flag content (case-insensitive). Default none. */
2587
+ readonly bannedSubstrings?: readonly string[];
2588
+ }
2589
+ interface AgentConfig<TProcess extends Record<string, ProcessField> = Record<string, ProcessField>> {
2590
+ /** Lowercase, kebab-case identifier. Used for LiveKit dispatch + presence. */
2591
+ readonly name: string;
2592
+ /** System prompt the LLM sees. */
2593
+ readonly prompt: string;
2594
+ /** Fixed opening line, spoken instantly via TTS at the start of the default
2595
+ * conversation flow — NO LLM. Eliminates the dead air of an LLM-generated
2596
+ * greeting (the first generateReply must process the whole system prompt).
2597
+ * Absent → the SDK falls back to an LLM-generated greeting. */
2598
+ readonly greeting?: string;
2599
+ /** Agent-level Instructions (the routing/decision layer): plain-language guidance
2600
+ * for WHEN the agent acts, appended below the persona under a `# Routing` header.
2601
+ * Interpolated with {{ }} by the process runtime. Optional. */
2602
+ readonly routingInstructions?: string;
2603
+ /** Capability tags surfaced in the dashboard. */
2604
+ readonly capabilities?: readonly string[];
2605
+ /** Semantic version. Defaults to AGENT_VERSION env or '0.0.0'. */
2606
+ readonly version?: string;
2607
+ /** dev / stg / prd. Defaults to AGENT_ENVIRONMENT env or 'dev'. */
2608
+ readonly environment?: AgentEnvironment;
2609
+ readonly process?: ProcessDefinition<TProcess>;
2610
+ readonly triggers?: Readonly<Record<string, TriggerDefinition>>;
2611
+ readonly handoff?: HandoffConfig;
2612
+ readonly memory?: MemoryConfig;
2613
+ readonly participants?: ParticipantsConfig;
2614
+ readonly connectors?: Readonly<Record<string, ConnectorInstance>>;
2615
+ readonly compliance?: readonly ComplianceTag[];
2616
+ readonly models?: ModelConfig;
2617
+ readonly outbound?: OutboundCallConfig;
2618
+ readonly speech?: SpeechConfig;
2619
+ readonly endCall?: EndCallPolicy;
2620
+ readonly tools?: Readonly<Record<string, ToolDefinition>>;
2621
+ /** Per-agent registry-tool scoping (stored ToolBinding names, applied at
2622
+ * boot). Non-empty → only these dashboard HTTP tools attach; absent/[] →
2623
+ * every enabled registry tool attaches (the historical default). */
2624
+ readonly toolBindings?: readonly string[];
2625
+ readonly security?: SecurityConfig;
2626
+ /** Output content-moderation guard (P5). When set, each assistant turn is
2627
+ * inspected and a violation is recorded as an engine.guard.blocked event on
2628
+ * the call timeline. OBSERVE-ONLY on voice — it audits, it does not unsay a
2629
+ * spoken turn. Absent → no guard. */
2630
+ readonly guard?: GuardConfig;
2631
+ /**
2632
+ * Per-call ConsultationPolicy used by the built-in `ask_host` tool. When
2633
+ * omitted the SDK uses the contract defaults (30s per-consult, 120s
2634
+ * cumulative). Plan-first calls override this at boot from
2635
+ * `plan.draftConfig.consultation`. See
2636
+ * packages/contracts/src/consultation.ts for the schema + semantics.
2637
+ */
2638
+ readonly consultation?: ConsultationPolicy;
2639
+ /**
2640
+ * Use your existing text agent as the LLM. When set (and `models.llm` is
2641
+ * unset), defineAgent wires the pipeline's LLM slot to this function: the
2642
+ * caller's STT transcript is passed to `onQuery`, and its returned text (or
2643
+ * streamed pieces) is spoken by TTS. The "two lines, keep your stack" path.
2644
+ *
2645
+ * Equivalent to `models: { llm: connector.llm({ onQuery }) }`. For a remote
2646
+ * brain instead, use `connector.llm({ url })` (direct) or a tunnel transport.
2647
+ * See docs/specs/voice-brain-connector/.
2648
+ */
2649
+ readonly onQuery?: OnQuery;
2650
+ readonly onUtterance?: (text: string, ctx: AgentContext) => Promise<void> | void;
2651
+ readonly onFieldCaptured?: (field: string, value: unknown, ctx: AgentContext) => Promise<void> | void;
2652
+ readonly onCallEnd?: (outcome: CallOutcomeSummary, ctx: AgentContext) => Promise<void> | void;
2653
+ readonly onEvent?: (event: AgentLifecycleEvent) => void;
2654
+ /** Replace the default conversation loop. The SDK does NOT auto-greet. */
2655
+ readonly onCall?: (ctx: AgentContext) => Promise<void>;
2656
+ readonly readiness?: readonly ReadinessProbe[];
2657
+ /**
2658
+ * Run as a remote-controlled (puppet) agent: no autonomous LLM loop, no
2659
+ * process/triggers pipeline. STT utterances are still published to
2660
+ * `call-events:{callId}` via the existing transcript-segments sync, and
2661
+ * the SDK subscribes to `call-control:{room}` to receive `say`,
2662
+ * `hangup`, `dtmf` commands from an external driver (typically the MCP
2663
+ * server invoked by a coding agent).
2664
+ *
2665
+ * When this is on, `process`, `triggers`, `onUtterance`, `onCall` are
2666
+ * ignored. `tools`, `connectors`, `memory` still work.
2667
+ */
2668
+ readonly puppetMode?: boolean;
2669
+ /**
2670
+ * Host-controlled autonomous agent (the "smart puppet"). UNLIKE puppetMode,
2671
+ * the agent keeps its REAL LLM and drives the conversation itself from its
2672
+ * prompt (the per-call `intent` is appended at boot). Since 0.2.0 EVERY
2673
+ * agent listens on its call's control channel (the MCP host can interject
2674
+ * with `say`, `hangup` or send `dtmf`, and answer `ask_host`), so this flag
2675
+ * now only shapes turn handling for a host-driven call. Use this for an agent that takes a customer's
2676
+ * intent and runs the call like a human secretary, asking the host for any
2677
+ * info it's missing. Mutually exclusive in spirit with puppetMode (which is
2678
+ * the older NoOp "dumb mouth").
2679
+ */
2680
+ readonly hostControlled?: boolean;
2681
+ /** When set, this agent boots each call from a deployed flow's process_schema. */
2682
+ readonly flowRuntime?: FlowRuntimeConfig;
2683
+ /**
2684
+ * Opt a hand-coded (non-flow) agent into the dashboard-driven pipeline: on
2685
+ * each call the SDK fetches this agent's PUBLISHED configuration (a saved
2686
+ * dashboard draft applies only once the owner publishes it) and applies
2687
+ * the operator-selected voice / model / STT over the coded defaults. The
2688
+ * pipeline *mode* (cascade vs realtime) stays pinned to what the code
2689
+ * declares — a stale `mode=realtime` in the dashboard can't flip a
2690
+ * cascade-only worker. Flow agents (`flowRuntime`) get this implicitly and
2691
+ * may additionally switch mode; this flag is the SDK opt-in. The agent id is
2692
+ * read from dispatch metadata (the inbound router injects it from
2693
+ * phone_numbers.agentId), so it's a no-op for calls without one.
2694
+ */
2695
+ readonly pipelineFromConfig?: boolean;
2696
+ /**
2697
+ * Opt this agent into MCP-layer visibility. When true, on register the API
2698
+ * also writes an `agent_config` row keyed by (project_id, name,
2699
+ * environment) so MCP / dashboard / REST can list and inspect this agent
2700
+ * (and, post-step-7, drive call_say / call_send_guidance / etc against
2701
+ * its live calls).
2702
+ *
2703
+ * Defaults to true so newly-registered agents show up in dashboards and
2704
+ * MCP-host listings without opt-in. Pass `false` for autonomous-only
2705
+ * agents that should stay invisible to MCP. See
2706
+ * docs/architecture/contracts-design.md §2b.
2707
+ */
2708
+ readonly mcpExposed?: boolean;
2709
+ }
2710
+ interface CallOutcomeSummary {
2711
+ readonly reason: 'completed' | 'handoff' | 'caller_hung_up' | 'agent_hung_up' | 'error';
2712
+ readonly durationMs: number;
2713
+ readonly processCompleted: boolean;
2714
+ readonly fieldsCaptured: number;
2715
+ readonly handoffOccurred: boolean;
2716
+ }
2717
+ /**
2718
+ * Identity helper that gives users a typed `defineProcess` entry point with
2719
+ * full inference on `onComplete`'s `data` argument.
2720
+ *
2721
+ * defineProcess({
2722
+ * collect: { name: { type: 'string', required: true } },
2723
+ * onComplete: (data) => { data.name // string },
2724
+ * })
2725
+ */
2726
+ declare function defineProcess<T extends Record<string, ProcessField>>(def: ProcessDefinition<T>): ProcessDefinition<T>;
2727
+
1941
2728
  /** What the agent passes into recordEvent — id/at filled in by the runtime. */
1942
2729
  interface RecordEventInput {
1943
2730
  readonly kind: string;
1944
2731
  readonly source?: ProcessLifecycleEvent['source'];
1945
2732
  readonly data?: Record<string, unknown>;
1946
2733
  }
2734
+ /** What the current step (a flow's graph step) tells the extractor about a caller turn. Absent ⇒ no step (a plain
2735
+ * agent): every field the caller may say is extracted, as before. */
2736
+ interface IngestOptions {
2737
+ /** The phone / number field the step is collecting — its value may be split across this step's turns (G-26). */
2738
+ readonly numberField?: string;
2739
+ /** The fields the step names (an ask's slot, the slots an llm step's exits read, a playbook's required fields).
2740
+ * Before the completion gate every field the caller may say is extracted (volunteered out of order counts); after
2741
+ * it, only these — a confirm's "yes" costs no extractor call. A value the caller gave for a field named here
2742
+ * changes only on an explicit correction; a value the flow set is open. (process-completion.test.ts) */
2743
+ readonly stepFields?: readonly string[];
2744
+ /** The field the step just asked the caller for — this turn is the answer. The extractor runs first, as for any
2745
+ * field; when it returns nothing for a free-text field (a `string` with no pattern or enum, the caller may say it:
2746
+ * a message, a name, notes, a reason) and the turn isn't filler ("Yes, please.", "Okay."), the turn itself is the
2747
+ * value — so caller text the model refuses as an instruction ("this is a test, please ignore") is still captured,
2748
+ * at no extra model call. (burn-down G-26, owner retest 2026-10-02; flow-graph-free-text.test.ts) */
2749
+ readonly answering?: string;
2750
+ }
1947
2751
  interface ProcessRuntime {
1948
2752
  /** Add field-collection guidance to the system prompt. */
1949
2753
  augmentPrompt(basePrompt: string): string;
1950
2754
  /** Run on each finalized caller utterance. */
1951
- ingest(utterance: string, ctx: AgentContext): Promise<void>;
2755
+ ingest(utterance: string, ctx: AgentContext, opts?: IngestOptions): Promise<void>;
2756
+ /** A declared field, as a step needs to know it (absent for an unknown field, and on a runtime with no fields):
2757
+ * its type; free text (a `string`, no pattern, no enum); whether the caller may say it (not `fromCaller: false`). */
2758
+ fieldInfo?(name: string): {
2759
+ readonly type: ProcessField['type'];
2760
+ readonly freeText: boolean;
2761
+ readonly fromCaller: boolean;
2762
+ } | undefined;
2763
+ /** Where a captured value came from: the caller's words (the extractor, or a free-text answer), or the agent (a set
2764
+ * node, a tool, prefill — captureField). Undefined when not captured. A model reads caller values fenced (§B.9). */
2765
+ origin?(name: string): 'caller' | 'agent' | undefined;
1952
2766
  /** Read the current captured data bag (used by handoff briefings). */
1953
2767
  getData(): Record<string, unknown>;
1954
- /** True if the process completion gate has fired. */
2768
+ /** True once the completion gate has been satisfied (and onComplete fired). Capture continues after it. */
1955
2769
  isComplete(): boolean;
1956
2770
  /**
1957
2771
  * Capture a field directly — bypasses the LLM extractor. Used by
@@ -1974,6 +2788,59 @@ interface ProcessRuntime {
1974
2788
  subscribe(listener: (snap: ProcessSnapshot$1) => void): () => void;
1975
2789
  }
1976
2790
 
2791
+ interface AgentToolSpec {
2792
+ readonly name: string;
2793
+ readonly description: string;
2794
+ readonly input: Record<string, 'string' | 'number' | 'boolean'>;
2795
+ }
2796
+ interface AgentToolCall {
2797
+ readonly name: string;
2798
+ readonly args: Record<string, unknown>;
2799
+ readonly ok: boolean;
2800
+ readonly status: number;
2801
+ readonly data: unknown;
2802
+ }
2803
+ interface AgentTurnRequest {
2804
+ /** Fully composed node prompt (goal + instructions + slots + gate status). */
2805
+ readonly instructions: string;
2806
+ /** In-node conversation so far (the runner is stateless across turns). */
2807
+ readonly transcript: ReadonlyArray<{
2808
+ readonly role: 'assistant' | 'user';
2809
+ readonly text: string;
2810
+ }>;
2811
+ /** Registry tools scoped to this node. */
2812
+ readonly tools: ReadonlyArray<AgentToolSpec>;
2813
+ /** Named exits (the node's ports). Empty → the exit tool is not offered. */
2814
+ readonly exits: ReadonlyArray<{
2815
+ readonly id: string;
2816
+ readonly description: string;
2817
+ }>;
2818
+ /** Slot names the exit tool may report as captured (fed back to the slot store). */
2819
+ readonly captureVars: ReadonlyArray<string>;
2820
+ /** Execute one scoped tool by name (the registry proxy). */
2821
+ readonly runTool: (name: string, args: Record<string, unknown>) => Promise<{
2822
+ ok: boolean;
2823
+ status: number;
2824
+ data: unknown;
2825
+ }>;
2826
+ readonly model?: string;
2827
+ readonly temperature?: number;
2828
+ readonly maxToolCalls?: number;
2829
+ }
2830
+ interface AgentTurnResult {
2831
+ /** What to speak this turn ('' when the model exited without a closing line). */
2832
+ readonly say: string;
2833
+ /** Structured completion, when the model called the exit tool. */
2834
+ readonly exit?: {
2835
+ readonly port: string;
2836
+ readonly vars: Record<string, string>;
2837
+ };
2838
+ /** Every tool invocation made this turn, in order. */
2839
+ readonly toolCalls: ReadonlyArray<AgentToolCall>;
2840
+ }
2841
+ /** Run one caller-turn of the agent loop. null → unavailable/error (fail safe). */
2842
+ type AgentRunner = (req: AgentTurnRequest) => Promise<AgentTurnResult | null>;
2843
+
1977
2844
  /** How the whole flow run finished. */
1978
2845
  type FlowOutcome = {
1979
2846
  readonly kind: 'completed';
@@ -1990,6 +2857,159 @@ type FlowOutcome = {
1990
2857
  readonly nodeId: string;
1991
2858
  readonly message: string;
1992
2859
  };
2860
+ /** Knowledge-base retrieval (rag node). Default impl POSTs /v1/knowledge/search. */
2861
+ type KnowledgeResolver = (q: {
2862
+ readonly query: string;
2863
+ readonly limit?: number;
2864
+ readonly minScore?: number;
2865
+ readonly filterMetadata?: Record<string, unknown>;
2866
+ }) => Promise<{
2867
+ readonly found: boolean;
2868
+ readonly chunks: ReadonlyArray<{
2869
+ readonly content: string;
2870
+ readonly score: number;
2871
+ readonly metadata?: Record<string, unknown>;
2872
+ }>;
2873
+ }>;
2874
+ /** Resolve a stored vault connection ref to auth headers (connection-auth tools).
2875
+ * Only used by the LOCAL fallback tool path; when a ToolExecutor is wired the
2876
+ * credential is resolved server-side and never reaches this worker. */
2877
+ type SecretResolver = (connectionRef: string) => Promise<{
2878
+ ok: true;
2879
+ headers: Record<string, string>;
2880
+ } | {
2881
+ ok: false;
2882
+ reason: string;
2883
+ }>;
2884
+ /** Execute a flow `tool` node's HTTP call SERVER-SIDE. The platform endpoint
2885
+ * renders the caller-controlled `{key}` placeholders, blocks private/loopback/
2886
+ * metadata hosts (SSRF), and attaches the vault credential AFTER the URL passes
2887
+ * the guard — so the credential never reaches this worker and a poisoned URL
2888
+ * can't exfiltrate it. Injected only when the worker holds the internal service
2889
+ * token; absent → the tool executor falls back to a local fetch (dev/self-host). */
2890
+ type ToolExecutor = (req: {
2891
+ readonly name: string;
2892
+ readonly url: string;
2893
+ readonly method: string;
2894
+ readonly headers?: Record<string, string>;
2895
+ readonly input?: Record<string, unknown>;
2896
+ readonly auth?: 'connection';
2897
+ readonly connectionRef?: string;
2898
+ }) => Promise<{
2899
+ readonly ok: boolean;
2900
+ readonly status: number;
2901
+ readonly data: unknown;
2902
+ }>;
2903
+ /** Evaluate a sandboxed code/expression node (server-side; never on the call path). */
2904
+ type CodeResolver = (src: {
2905
+ readonly expression: string;
2906
+ readonly scope: Record<string, unknown>;
2907
+ }) => Promise<{
2908
+ ok: true;
2909
+ outputs: Record<string, unknown>;
2910
+ next?: string;
2911
+ } | {
2912
+ ok: false;
2913
+ error: string;
2914
+ }>;
2915
+ /** Silently pick one of a classify node's options (intent routing); returns the
2916
+ * chosen option id, or null if undecided. Default impl is a small LLM call. */
2917
+ type ClassifyResolver = (input: {
2918
+ readonly instructions: string;
2919
+ readonly options: ReadonlyArray<{
2920
+ id: string;
2921
+ label: string;
2922
+ }>;
2923
+ readonly lastUtterance?: string;
2924
+ readonly slots: Record<string, unknown>;
2925
+ }) => Promise<string | null>;
2926
+ /** Resolve a reusable library playbook by name to the bits the playbook executor
2927
+ * needs: its instructions, the union of its exit conditions' required variables
2928
+ * (the completeness gate), and — when the library entry carries them — its tool
2929
+ * bindings and model knobs (all optional, additive). null when not found. */
2930
+ type PlaybookResolver = (name: string) => Promise<{
2931
+ instructions: string;
2932
+ requiredFields: string[];
2933
+ tools?: string[];
2934
+ model?: string;
2935
+ temperature?: number;
2936
+ exits?: Array<{
2937
+ id: string;
2938
+ description: string;
2939
+ }>;
2940
+ } | null>;
2941
+ /** The project's HTTP-tools registry, scoped for the agent loop: list the tool
2942
+ * specs (for the LLM's schema) and execute one by NAME — execution proxies to
2943
+ * the server-side endpoint, so the URL/credential never reach this worker. */
2944
+ interface RegistryToolsResolver {
2945
+ catalog(): Promise<ReadonlyArray<AgentToolSpec>>;
2946
+ run(name: string, args: Record<string, unknown>): Promise<{
2947
+ ok: boolean;
2948
+ status: number;
2949
+ data: unknown;
2950
+ }>;
2951
+ }
2952
+ /** Resolve a reusable component (subflow node) by ref to a compiled FlowProgram the
2953
+ * interpreter can run inline. null when the referenced flow isn't found / unpublished
2954
+ * (the subflow executor then degrades to a recorded no-op and advances). */
2955
+ type FlowResolver = (ref: string) => Promise<FlowProgram | null>;
2956
+ /** Side-effect surface injected once by runFlowProgram. Every member is optional;
2957
+ * a missing resolver makes its executor degrade to a recorded no-op (never throws,
2958
+ * never blocks the call). Kept off AgentContext so the contract stays small and
2959
+ * executors stay unit-testable with fakes. */
2960
+ interface GraphResolvers {
2961
+ readonly knowledge?: KnowledgeResolver;
2962
+ readonly secrets?: SecretResolver;
2963
+ /** Server-side SSRF-guarded HTTP tool executor (tool node). When present the
2964
+ * tool executor routes through it instead of fetching locally. */
2965
+ readonly toolExecutor?: ToolExecutor;
2966
+ readonly code?: CodeResolver;
2967
+ readonly classify?: ClassifyResolver;
2968
+ readonly playbooks?: PlaybookResolver;
2969
+ readonly flows?: FlowResolver;
2970
+ /** LLM-with-tools loop for agent (playbook) nodes with tool scope. */
2971
+ readonly agentRunner?: AgentRunner;
2972
+ /** Name-referenced project tool registry (catalog + server-side execute). */
2973
+ readonly registryTools?: RegistryToolsResolver;
2974
+ }
2975
+
2976
+ /** A library playbook as GET /v1/playbooks (and the API's PlaybooksService) lists it — the fields a flow reads. */
2977
+ interface PlaybookLibraryEntry {
2978
+ readonly name: string;
2979
+ readonly instructions?: string;
2980
+ readonly model?: string | null;
2981
+ readonly temperature?: number | null;
2982
+ readonly tools?: ReadonlyArray<string | {
2983
+ readonly toolName?: string;
2984
+ }>;
2985
+ readonly exitConditions?: ReadonlyArray<{
2986
+ readonly id?: string;
2987
+ readonly name?: string;
2988
+ readonly description?: string;
2989
+ readonly requiredVariables?: readonly string[];
2990
+ }>;
2991
+ }
2992
+ /** What a playbook step needs from a library entry: its instructions + the union of its exit conditions' required
2993
+ * variables (the completeness gate), and — when the entry carries them — tool bindings, model knobs, exits. One
2994
+ * mapping for the voice worker (over HTTP) and a host that reads its own library (the API's text engine). */
2995
+ declare function toPlaybookResolution(pb: PlaybookLibraryEntry): NonNullable<Awaited<ReturnType<PlaybookResolver>>>;
2996
+
2997
+ type HostLookup = (hostname: string) => Promise<ReadonlyArray<{
2998
+ readonly address: string;
2999
+ readonly family: number;
3000
+ }>>;
3001
+ /**
3002
+ * Turn the private-network opt-in off for this whole process, for good. A host running OTHER people's flows (the
3003
+ * VoiceLayer API's text engine) calls this at boot: there, a private address is the platform's own network, whatever
3004
+ * an author wrote. There is deliberately no way to turn it back on.
3005
+ */
3006
+ declare function denyPrivateNetwork(): void;
3007
+ /**
3008
+ * Whether an author's `allowPrivateNetwork` from a stored schema (a schema tool, a backendAck) is honoured in this
3009
+ * process. It takes a POSITIVE opt-in by whoever runs the worker — `VL_ALLOW_PRIVATE_NETWORK=1` — never the absence of
3010
+ * something; and never on a platform worker (INTERNAL_SERVICE_TOKEN) or after denyPrivateNetwork().
3011
+ */
3012
+ declare function privateNetworkOptInHonoured(): boolean;
1993
3013
 
1994
3014
  /**
1995
3015
  * Run `fn` with `client` as the internal helpers' OpenAI client. The scope follows the async work `fn` starts (an
@@ -2023,6 +3043,18 @@ interface RunTextSessionOptions {
2023
3043
  /** Fires when the interpreter finishes a turn and blocks for the next user
2024
3044
  * message — the per-turn boundary used by the live driver below. */
2025
3045
  readonly onAwaitInput?: () => void;
3046
+ /**
3047
+ * The project-scoped services the flow's data steps call (tool / rag / subflow / playbook / registry tool), built by
3048
+ * the host for the conversation's project. A step whose resolver is absent records why and takes its no-op path. A
3049
+ * multi-tenant host MUST pass a `toolExecutor` (its server-side SSRF-guarded executor): without one a tool step
3050
+ * fetches from this process — guarded (safe-fetch.ts), but with no connection auth and none of the host's audit.
3051
+ */
3052
+ readonly resolvers?: GraphResolvers;
3053
+ /**
3054
+ * `false` — this host runs other people's flows: no step may reach a private address, whatever an author opted
3055
+ * into. Applies to the whole process and can't be undone (denyPrivateNetwork); there is no `true`.
3056
+ */
3057
+ readonly allowPrivateNetwork?: false;
2026
3058
  }
2027
3059
  interface TextSession {
2028
3060
  /** Feed an inbound user message (a final turn). */
@@ -2050,6 +3082,8 @@ interface RunTextTranscriptOptions {
2050
3082
  readonly generate?: (instructions?: string) => Promise<string>;
2051
3083
  readonly call?: RunTextSessionOptions['call'];
2052
3084
  readonly maxSteps?: number;
3085
+ readonly resolvers?: GraphResolvers;
3086
+ readonly allowPrivateNetwork?: false;
2053
3087
  }
2054
3088
  interface TextTranscriptResult {
2055
3089
  readonly replies: readonly string[];
@@ -2096,4 +3130,4 @@ type RunLiveTextOptions = Omit<RunTextSessionOptions, 'onAgentText' | 'onAwaitIn
2096
3130
  * interpreter blocks for the next message, or the flow ends. */
2097
3131
  declare function runLiveTextConversation(opts: RunLiveTextOptions): LiveTextConversation;
2098
3132
 
2099
- export { type UserStateEvent as $, AgentDTO as A, type SessionEvent as B, type CallInfo as C, type DtmfEvent as D, type EndCallControllerHandle as E, type FakeSessionAdapter as F, type SessionEventMap as G, type SessionFactory as H, type InboundOptions as I, type SessionFactoryInput as J, type SessionOutbound as K, LK_AGENT_STATE_MAP as L, type MemoryHandle as M, NON_BUSY_STATES as N, type SessionState as O, type Participant as P, type SpeechResult as Q, type RespondOptions as R, type SayOptions as S, type SpeechTarget as T, type StateChangeEvent as U, type TextSession as V, type TextTranscriptResult as W, type TtsVoiceConfig as X, type TurnEvent as Y, type Unsubscribe as Z, type UserInputEvent as _, AgentStatus as a, type UserTurn as a0, applySpeechTurnHandling as a1, dtmfCodeToDigit as a2, dtmfDigitToCode as a3, duck as a4, mute as a5, normalizeState as a6, passthrough as a7, runTextSession as a8, runTextTranscript as a9, transform as aa, type GraphTraceEvent as ab, type LiveTextConversation as ac, type LiveTurnResult as ad, type RunLiveTextOptions as ae, runLiveTextConversation as af, runWithOpenAIScope as ag, AgentEnvironment as b, type AgentContext as c, ProcessSchemaDTO as d, type AgentTurnEvent as e, type AudioProfile as f, type AudioSurface as g, type ChannelKind as h, type DtmfHandler as i, type EndCallOutcome as j, type FloorControlConfig as k, type MetricsEvent as l, ParticipantId as m, type ParticipantKind as n, type ParticipantSet as o, type ProcessSnapshot as p, type Room as q, type RouteEntry as r, type RoutingRule as s, type RoutingSnapshot as t, type RunTextSessionOptions as u, type RunTextTranscriptOptions as v, type SendDtmfOptions as w, type SessionAdapter as x, type SessionCapabilities as y, type SessionErrorEvent as z };
3133
+ export { NON_BUSY_STATES as $, AgentEnvironment as A, type DtmfHandler as B, type ConnectorInstance as C, type DtmfEvent as D, type EndCallControllerHandle as E, type EndCallInfo as F, type EndCallOutcome as G, type HandoffConfig as H, type EndCallPolicy as I, type EndCallTrigger as J, type EndpointingConfig as K, type LLMProvider as L, type ModelConfig as M, type FakeSessionAdapter as N, type FloorControlConfig as O, ProcessSchemaDTO as P, type InboundOptions as Q, type ReadinessProbe as R, type STTProvider as S, type TTSProvider as T, type InferProcessData as U, type VADProvider as V, type InterruptionConfig as W, LK_AGENT_STATE_MAP as X, type MemoryHandle as Y, type MemoryScope as Z, type MetricsEvent as _, type AgentLifecycleEvent as a, urlProbe as a$, type Participant as a0, ParticipantId as a1, type ParticipantKind as a2, type ParticipantSet as a3, type ParticipantsConfig as a4, type ProcessBackendAck as a5, type ProcessFieldType as a6, type ProcessSnapshot as a7, type ReadinessReport as a8, type ReadinessResult as a9, type TriggerAction as aA, type TriggerCondition as aB, type TtsVoiceConfig as aC, type TurnEvent as aD, type Unsubscribe as aE, type UserInputEvent as aF, type UserStateEvent as aG, type UserTurn as aH, VoiceLayerAuthError as aI, VoiceLayerError as aJ, VoiceLayerHttpError as aK, VoiceLayerNetworkError as aL, VoiceLayerValidationError as aM, applySpeechTurnHandling as aN, asyncProbe as aO, defineProcess as aP, dtmfCodeToDigit as aQ, dtmfDigitToCode as aR, duck as aS, envProbe as aT, mute as aU, normalizeState as aV, passthrough as aW, runProbes as aX, runTextSession as aY, runTextTranscript as aZ, transform as a_, type RespondOptions as aa, type Room as ab, type RouteEntry as ac, type RoutingRule as ad, type RoutingSnapshot as ae, type RunTextSessionOptions as af, type RunTextTranscriptOptions as ag, type SayOptions as ah, type SecurityConfig as ai, type SendDtmfOptions as aj, type SessionAdapter as ak, type SessionCapabilities as al, type SessionErrorEvent as am, type SessionEvent as an, type SessionEventMap as ao, type SessionFactory as ap, type SessionFactoryInput as aq, type SessionOutbound as ar, type SessionState as as, type ShorthandPrimitive as at, type SpeechResult as au, type SpeechTarget as av, type StateChangeEvent as aw, type TextSession as ax, type TextTranscriptResult as ay, type ToolInputShape as az, AgentDTO as b, type FlowResolver as b0, type GraphResolvers as b1, type GraphTraceEvent as b2, type KnowledgeResolver as b3, type LiveTextConversation as b4, type LiveTurnResult as b5, type PlaybookLibraryEntry as b6, type PlaybookResolver as b7, type RegistryToolsResolver as b8, type RunLiveTextOptions as b9, denyPrivateNetwork as ba, privateNetworkOptInHonoured as bb, runLiveTextConversation as bc, runWithOpenAIScope as bd, toPlaybookResolution as be, type AgentEventEmitter as c, type AgentContext as d, type AgentConfig as e, type ProcessField as f, type ProviderFactory as g, type RealtimeProvider as h, type TurnDetectorProvider as i, type ProcessDefinition as j, type TriggerDefinition as k, type MemoryConfig as l, type ToolDefinition as m, type SpeechConfig as n, type ToolExecutor as o, type HostLookup as p, type AgentEventListener as q, type AgentTurnEvent as r, type AudioProfile as s, type AudioSurface as t, type CallInfo as u, type CallOutcomeSummary as v, type ChannelKind as w, type CompletionStrategy as x, type ComplianceTag as y, ConsultationPolicy as z };