@livekit/agents 1.0.35 → 1.0.36-dev.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.
Files changed (131) hide show
  1. package/dist/index.cjs +3 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +1 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +1 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/inference/interruption/AdaptiveInterruptionDetector.cjs +152 -0
  9. package/dist/inference/interruption/AdaptiveInterruptionDetector.cjs.map +1 -0
  10. package/dist/inference/interruption/AdaptiveInterruptionDetector.d.cts +50 -0
  11. package/dist/inference/interruption/AdaptiveInterruptionDetector.d.ts +50 -0
  12. package/dist/inference/interruption/AdaptiveInterruptionDetector.d.ts.map +1 -0
  13. package/dist/inference/interruption/AdaptiveInterruptionDetector.js +125 -0
  14. package/dist/inference/interruption/AdaptiveInterruptionDetector.js.map +1 -0
  15. package/dist/inference/interruption/InterruptionStream.cjs +310 -0
  16. package/dist/inference/interruption/InterruptionStream.cjs.map +1 -0
  17. package/dist/inference/interruption/InterruptionStream.d.cts +57 -0
  18. package/dist/inference/interruption/InterruptionStream.d.ts +57 -0
  19. package/dist/inference/interruption/InterruptionStream.d.ts.map +1 -0
  20. package/dist/inference/interruption/InterruptionStream.js +288 -0
  21. package/dist/inference/interruption/InterruptionStream.js.map +1 -0
  22. package/dist/inference/interruption/defaults.cjs +76 -0
  23. package/dist/inference/interruption/defaults.cjs.map +1 -0
  24. package/dist/inference/interruption/defaults.d.cts +14 -0
  25. package/dist/inference/interruption/defaults.d.ts +14 -0
  26. package/dist/inference/interruption/defaults.d.ts.map +1 -0
  27. package/dist/inference/interruption/defaults.js +42 -0
  28. package/dist/inference/interruption/defaults.js.map +1 -0
  29. package/dist/inference/interruption/errors.cjs +2 -0
  30. package/dist/inference/interruption/errors.cjs.map +1 -0
  31. package/dist/inference/interruption/errors.d.cts +2 -0
  32. package/dist/inference/interruption/errors.d.ts +2 -0
  33. package/dist/inference/interruption/errors.d.ts.map +1 -0
  34. package/dist/inference/interruption/errors.js +1 -0
  35. package/dist/inference/interruption/errors.js.map +1 -0
  36. package/dist/inference/interruption/http_transport.cjs +57 -0
  37. package/dist/inference/interruption/http_transport.cjs.map +1 -0
  38. package/dist/inference/interruption/http_transport.d.cts +23 -0
  39. package/dist/inference/interruption/http_transport.d.ts +23 -0
  40. package/dist/inference/interruption/http_transport.d.ts.map +1 -0
  41. package/dist/inference/interruption/http_transport.js +33 -0
  42. package/dist/inference/interruption/http_transport.js.map +1 -0
  43. package/dist/inference/interruption/index.cjs +34 -0
  44. package/dist/inference/interruption/index.cjs.map +1 -0
  45. package/dist/inference/interruption/index.d.cts +5 -0
  46. package/dist/inference/interruption/index.d.ts +5 -0
  47. package/dist/inference/interruption/index.d.ts.map +1 -0
  48. package/dist/inference/interruption/index.js +7 -0
  49. package/dist/inference/interruption/index.js.map +1 -0
  50. package/dist/inference/interruption/interruption.cjs +85 -0
  51. package/dist/inference/interruption/interruption.cjs.map +1 -0
  52. package/dist/inference/interruption/interruption.d.cts +48 -0
  53. package/dist/inference/interruption/interruption.d.ts +48 -0
  54. package/dist/inference/interruption/interruption.d.ts.map +1 -0
  55. package/dist/inference/interruption/interruption.js +59 -0
  56. package/dist/inference/interruption/interruption.js.map +1 -0
  57. package/dist/inference/utils.cjs +15 -2
  58. package/dist/inference/utils.cjs.map +1 -1
  59. package/dist/inference/utils.d.cts +1 -0
  60. package/dist/inference/utils.d.ts +1 -0
  61. package/dist/inference/utils.d.ts.map +1 -1
  62. package/dist/inference/utils.js +13 -1
  63. package/dist/inference/utils.js.map +1 -1
  64. package/dist/inference/utils.test.cjs +20 -0
  65. package/dist/inference/utils.test.cjs.map +1 -0
  66. package/dist/inference/utils.test.js +19 -0
  67. package/dist/inference/utils.test.js.map +1 -0
  68. package/dist/stream/stream_channel.cjs +3 -0
  69. package/dist/stream/stream_channel.cjs.map +1 -1
  70. package/dist/stream/stream_channel.d.cts +3 -2
  71. package/dist/stream/stream_channel.d.ts +3 -2
  72. package/dist/stream/stream_channel.d.ts.map +1 -1
  73. package/dist/stream/stream_channel.js +3 -0
  74. package/dist/stream/stream_channel.js.map +1 -1
  75. package/dist/telemetry/trace_types.cjs +15 -0
  76. package/dist/telemetry/trace_types.cjs.map +1 -1
  77. package/dist/telemetry/trace_types.d.cts +5 -0
  78. package/dist/telemetry/trace_types.d.ts +5 -0
  79. package/dist/telemetry/trace_types.d.ts.map +1 -1
  80. package/dist/telemetry/trace_types.js +10 -0
  81. package/dist/telemetry/trace_types.js.map +1 -1
  82. package/dist/utils/ws_transport.cjs +51 -0
  83. package/dist/utils/ws_transport.cjs.map +1 -0
  84. package/dist/utils/ws_transport.d.cts +9 -0
  85. package/dist/utils/ws_transport.d.ts +9 -0
  86. package/dist/utils/ws_transport.d.ts.map +1 -0
  87. package/dist/utils/ws_transport.js +17 -0
  88. package/dist/utils/ws_transport.js.map +1 -0
  89. package/dist/utils/ws_transport.test.cjs +212 -0
  90. package/dist/utils/ws_transport.test.cjs.map +1 -0
  91. package/dist/utils/ws_transport.test.js +211 -0
  92. package/dist/utils/ws_transport.test.js.map +1 -0
  93. package/dist/voice/agent_activity.cjs +49 -0
  94. package/dist/voice/agent_activity.cjs.map +1 -1
  95. package/dist/voice/agent_activity.d.cts +14 -0
  96. package/dist/voice/agent_activity.d.ts +14 -0
  97. package/dist/voice/agent_activity.d.ts.map +1 -1
  98. package/dist/voice/agent_activity.js +49 -0
  99. package/dist/voice/agent_activity.js.map +1 -1
  100. package/dist/voice/agent_session.cjs +12 -1
  101. package/dist/voice/agent_session.cjs.map +1 -1
  102. package/dist/voice/agent_session.d.cts +3 -0
  103. package/dist/voice/agent_session.d.ts +3 -0
  104. package/dist/voice/agent_session.d.ts.map +1 -1
  105. package/dist/voice/agent_session.js +12 -1
  106. package/dist/voice/agent_session.js.map +1 -1
  107. package/dist/voice/audio_recognition.cjs +124 -2
  108. package/dist/voice/audio_recognition.cjs.map +1 -1
  109. package/dist/voice/audio_recognition.d.cts +32 -1
  110. package/dist/voice/audio_recognition.d.ts +32 -1
  111. package/dist/voice/audio_recognition.d.ts.map +1 -1
  112. package/dist/voice/audio_recognition.js +127 -2
  113. package/dist/voice/audio_recognition.js.map +1 -1
  114. package/package.json +2 -1
  115. package/src/index.ts +2 -0
  116. package/src/inference/interruption/AdaptiveInterruptionDetector.ts +166 -0
  117. package/src/inference/interruption/InterruptionStream.ts +397 -0
  118. package/src/inference/interruption/defaults.ts +33 -0
  119. package/src/inference/interruption/errors.ts +0 -0
  120. package/src/inference/interruption/http_transport.ts +61 -0
  121. package/src/inference/interruption/index.ts +4 -0
  122. package/src/inference/interruption/interruption.ts +88 -0
  123. package/src/inference/utils.test.ts +31 -0
  124. package/src/inference/utils.ts +15 -0
  125. package/src/stream/stream_channel.ts +6 -2
  126. package/src/telemetry/trace_types.ts +7 -0
  127. package/src/utils/ws_transport.test.ts +282 -0
  128. package/src/utils/ws_transport.ts +22 -0
  129. package/src/voice/agent_activity.ts +61 -0
  130. package/src/voice/agent_session.ts +22 -2
  131. package/src/voice/audio_recognition.ts +161 -1
package/dist/index.cjs CHANGED
@@ -67,6 +67,7 @@ __reExport(index_exports, require("./utils.cjs"), module.exports);
67
67
  __reExport(index_exports, require("./vad.cjs"), module.exports);
68
68
  __reExport(index_exports, require("./version.cjs"), module.exports);
69
69
  __reExport(index_exports, require("./worker.cjs"), module.exports);
70
+ __reExport(index_exports, require("./inference/interruption/index.cjs"), module.exports);
70
71
  // Annotate the CommonJS export names for ESM import in node:
71
72
  0 && (module.exports = {
72
73
  cli,
@@ -93,6 +94,7 @@ __reExport(index_exports, require("./worker.cjs"), module.exports);
93
94
  ...require("./utils.cjs"),
94
95
  ...require("./vad.cjs"),
95
96
  ...require("./version.cjs"),
96
- ...require("./worker.cjs")
97
+ ...require("./worker.cjs"),
98
+ ...require("./inference/interruption/index.cjs")
97
99
  });
98
100
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * LiveKit Agents is a framework for building realtime programmable participants that run on\n * servers.\n *\n * @see {@link https://docs.livekit.io/agents/overview | LiveKit Agents documentation}\n * @packageDocumentation\n */\nimport * as cli from './cli.js';\nimport * as inference from './inference/index.js';\nimport * as ipc from './ipc/index.js';\nimport * as llm from './llm/index.js';\nimport * as metrics from './metrics/index.js';\nimport * as stream from './stream/index.js';\nimport * as stt from './stt/index.js';\nimport * as telemetry from './telemetry/index.js';\nimport * as tokenize from './tokenize/index.js';\nimport * as tts from './tts/index.js';\nimport * as voice from './voice/index.js';\n\nexport * from './_exceptions.js';\nexport * from './audio.js';\nexport * from './connection_pool.js';\nexport * from './generator.js';\nexport * from './inference_runner.js';\nexport * from './job.js';\nexport * from './log.js';\nexport * from './plugin.js';\nexport * from './transcription.js';\nexport * from './types.js';\nexport * from './utils.js';\nexport * from './vad.js';\nexport * from './version.js';\nexport * from './worker.js';\n\nexport { cli, inference, ipc, llm, metrics, stream, stt, telemetry, tokenize, tts, voice };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA,UAAqB;AACrB,gBAA2B;AAC3B,UAAqB;AACrB,UAAqB;AACrB,cAAyB;AACzB,aAAwB;AACxB,UAAqB;AACrB,gBAA2B;AAC3B,eAA0B;AAC1B,UAAqB;AACrB,YAAuB;AAEvB,0BAAc,6BAvBd;AAwBA,0BAAc,uBAxBd;AAyBA,0BAAc,iCAzBd;AA0BA,0BAAc,2BA1Bd;AA2BA,0BAAc,kCA3Bd;AA4BA,0BAAc,qBA5Bd;AA6BA,0BAAc,qBA7Bd;AA8BA,0BAAc,wBA9Bd;AA+BA,0BAAc,+BA/Bd;AAgCA,0BAAc,uBAhCd;AAiCA,0BAAc,uBAjCd;AAkCA,0BAAc,qBAlCd;AAmCA,0BAAc,yBAnCd;AAoCA,0BAAc,wBApCd;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * LiveKit Agents is a framework for building realtime programmable participants that run on\n * servers.\n *\n * @see {@link https://docs.livekit.io/agents/overview | LiveKit Agents documentation}\n * @packageDocumentation\n */\nimport * as cli from './cli.js';\nimport * as inference from './inference/index.js';\nimport * as ipc from './ipc/index.js';\nimport * as llm from './llm/index.js';\nimport * as metrics from './metrics/index.js';\nimport * as stream from './stream/index.js';\nimport * as stt from './stt/index.js';\nimport * as telemetry from './telemetry/index.js';\nimport * as tokenize from './tokenize/index.js';\nimport * as tts from './tts/index.js';\nimport * as voice from './voice/index.js';\n\nexport * from './_exceptions.js';\nexport * from './audio.js';\nexport * from './connection_pool.js';\nexport * from './generator.js';\nexport * from './inference_runner.js';\nexport * from './job.js';\nexport * from './log.js';\nexport * from './plugin.js';\nexport * from './transcription.js';\nexport * from './types.js';\nexport * from './utils.js';\nexport * from './vad.js';\nexport * from './version.js';\nexport * from './worker.js';\n\nexport * from './inference/interruption/index.js';\n\nexport { cli, inference, ipc, llm, metrics, stream, stt, telemetry, tokenize, tts, voice };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA,UAAqB;AACrB,gBAA2B;AAC3B,UAAqB;AACrB,UAAqB;AACrB,cAAyB;AACzB,aAAwB;AACxB,UAAqB;AACrB,gBAA2B;AAC3B,eAA0B;AAC1B,UAAqB;AACrB,YAAuB;AAEvB,0BAAc,6BAvBd;AAwBA,0BAAc,uBAxBd;AAyBA,0BAAc,iCAzBd;AA0BA,0BAAc,2BA1Bd;AA2BA,0BAAc,kCA3Bd;AA4BA,0BAAc,qBA5Bd;AA6BA,0BAAc,qBA7Bd;AA8BA,0BAAc,wBA9Bd;AA+BA,0BAAc,+BA/Bd;AAgCA,0BAAc,uBAhCd;AAiCA,0BAAc,uBAjCd;AAkCA,0BAAc,qBAlCd;AAmCA,0BAAc,yBAnCd;AAoCA,0BAAc,wBApCd;AAsCA,0BAAc,8CAtCd;","names":[]}
package/dist/index.d.cts CHANGED
@@ -30,5 +30,6 @@ export * from './utils.js';
30
30
  export * from './vad.js';
31
31
  export * from './version.js';
32
32
  export * from './worker.js';
33
+ export * from './inference/interruption/index.js';
33
34
  export { cli, inference, ipc, llm, metrics, stream, stt, telemetry, tokenize, tts, voice };
34
35
  //# sourceMappingURL=index.d.ts.map
package/dist/index.d.ts CHANGED
@@ -30,5 +30,6 @@ export * from './utils.js';
30
30
  export * from './vad.js';
31
31
  export * from './version.js';
32
32
  export * from './worker.js';
33
+ export * from './inference/interruption/index.js';
33
34
  export { cli, inference, ipc, llm, metrics, stream, stt, telemetry, tokenize, tts, voice };
34
35
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAE1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAE5B,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAE1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAE5B,cAAc,mCAAmC,CAAC;AAElD,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -23,6 +23,7 @@ export * from "./utils.js";
23
23
  export * from "./vad.js";
24
24
  export * from "./version.js";
25
25
  export * from "./worker.js";
26
+ export * from "./inference/interruption/index.js";
26
27
  export {
27
28
  cli,
28
29
  inference,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * LiveKit Agents is a framework for building realtime programmable participants that run on\n * servers.\n *\n * @see {@link https://docs.livekit.io/agents/overview | LiveKit Agents documentation}\n * @packageDocumentation\n */\nimport * as cli from './cli.js';\nimport * as inference from './inference/index.js';\nimport * as ipc from './ipc/index.js';\nimport * as llm from './llm/index.js';\nimport * as metrics from './metrics/index.js';\nimport * as stream from './stream/index.js';\nimport * as stt from './stt/index.js';\nimport * as telemetry from './telemetry/index.js';\nimport * as tokenize from './tokenize/index.js';\nimport * as tts from './tts/index.js';\nimport * as voice from './voice/index.js';\n\nexport * from './_exceptions.js';\nexport * from './audio.js';\nexport * from './connection_pool.js';\nexport * from './generator.js';\nexport * from './inference_runner.js';\nexport * from './job.js';\nexport * from './log.js';\nexport * from './plugin.js';\nexport * from './transcription.js';\nexport * from './types.js';\nexport * from './utils.js';\nexport * from './vad.js';\nexport * from './version.js';\nexport * from './worker.js';\n\nexport { cli, inference, ipc, llm, metrics, stream, stt, telemetry, tokenize, tts, voice };\n"],"mappings":"AAWA,YAAY,SAAS;AACrB,YAAY,eAAe;AAC3B,YAAY,SAAS;AACrB,YAAY,SAAS;AACrB,YAAY,aAAa;AACzB,YAAY,YAAY;AACxB,YAAY,SAAS;AACrB,YAAY,eAAe;AAC3B,YAAY,cAAc;AAC1B,YAAY,SAAS;AACrB,YAAY,WAAW;AAEvB,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * LiveKit Agents is a framework for building realtime programmable participants that run on\n * servers.\n *\n * @see {@link https://docs.livekit.io/agents/overview | LiveKit Agents documentation}\n * @packageDocumentation\n */\nimport * as cli from './cli.js';\nimport * as inference from './inference/index.js';\nimport * as ipc from './ipc/index.js';\nimport * as llm from './llm/index.js';\nimport * as metrics from './metrics/index.js';\nimport * as stream from './stream/index.js';\nimport * as stt from './stt/index.js';\nimport * as telemetry from './telemetry/index.js';\nimport * as tokenize from './tokenize/index.js';\nimport * as tts from './tts/index.js';\nimport * as voice from './voice/index.js';\n\nexport * from './_exceptions.js';\nexport * from './audio.js';\nexport * from './connection_pool.js';\nexport * from './generator.js';\nexport * from './inference_runner.js';\nexport * from './job.js';\nexport * from './log.js';\nexport * from './plugin.js';\nexport * from './transcription.js';\nexport * from './types.js';\nexport * from './utils.js';\nexport * from './vad.js';\nexport * from './version.js';\nexport * from './worker.js';\n\nexport * from './inference/interruption/index.js';\n\nexport { cli, inference, ipc, llm, metrics, stream, stt, telemetry, tokenize, tts, voice };\n"],"mappings":"AAWA,YAAY,SAAS;AACrB,YAAY,eAAe;AAC3B,YAAY,SAAS;AACrB,YAAY,SAAS;AACrB,YAAY,aAAa;AACzB,YAAY,YAAY;AACxB,YAAY,SAAS;AACrB,YAAY,eAAe;AAC3B,YAAY,cAAc;AAC1B,YAAY,SAAS;AACrB,YAAY,WAAW;AAEvB,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAEd,cAAc;","names":[]}
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var AdaptiveInterruptionDetector_exports = {};
30
+ __export(AdaptiveInterruptionDetector_exports, {
31
+ AdaptiveInterruptionDetector: () => AdaptiveInterruptionDetector
32
+ });
33
+ module.exports = __toCommonJS(AdaptiveInterruptionDetector_exports);
34
+ var import_events = __toESM(require("events"), 1);
35
+ var import_web = require("stream/web");
36
+ var import_InterruptionStream = require("./InterruptionStream.cjs");
37
+ var import_defaults = require("./defaults.cjs");
38
+ var import_interruption = require("./interruption.cjs");
39
+ class AdaptiveInterruptionDetector extends import_events.default {
40
+ options;
41
+ label;
42
+ streams;
43
+ // TODO: Union of InterruptionHttpStream | InterruptionWebSocketStream
44
+ constructor(options = {}) {
45
+ super();
46
+ const {
47
+ maxAudioDuration,
48
+ baseUrl,
49
+ apiKey,
50
+ apiSecret,
51
+ useProxy: useProxyArg,
52
+ audioPrefixDuration,
53
+ threshold,
54
+ detectionInterval,
55
+ inferenceTimeout,
56
+ minInterruptionDuration
57
+ } = { ...import_defaults.interruptionOptionDefaults, ...options };
58
+ if (maxAudioDuration > 3) {
59
+ throw new Error("maxAudioDuration must be less than or equal to 3.0 seconds");
60
+ }
61
+ const lkBaseUrl = baseUrl ?? process.env.LIVEKIT_REMOTE_EOT_URL ?? import_defaults.DEFAULT_BASE_URL;
62
+ let lkApiKey = apiKey ?? "";
63
+ let lkApiSecret = apiSecret ?? "";
64
+ let useProxy;
65
+ if (lkBaseUrl === import_defaults.DEFAULT_BASE_URL) {
66
+ lkApiKey = apiKey ?? process.env.LIVEKIT_INFERENCE_API_KEY ?? process.env.LIVEKIT_API_KEY ?? "";
67
+ if (!lkApiKey) {
68
+ throw new Error(
69
+ "apiKey is required, either as argument or set LIVEKIT_API_KEY environmental variable"
70
+ );
71
+ }
72
+ lkApiSecret = apiSecret ?? process.env.LIVEKIT_INFERENCE_API_SECRET ?? process.env.LIVEKIT_API_SECRET ?? "";
73
+ if (!lkApiSecret) {
74
+ throw new Error(
75
+ "apiSecret is required, either as argument or set LIVEKIT_API_SECRET environmental variable"
76
+ );
77
+ }
78
+ useProxy = true;
79
+ } else {
80
+ useProxy = useProxyArg ?? false;
81
+ }
82
+ this.options = {
83
+ sampleRate: import_defaults.SAMPLE_RATE,
84
+ threshold,
85
+ minFrames: Math.ceil(minInterruptionDuration * import_defaults.FRAMES_PER_SECOND),
86
+ maxAudioDuration,
87
+ audioPrefixDuration,
88
+ detectionInterval,
89
+ inferenceTimeout,
90
+ baseUrl: lkBaseUrl,
91
+ apiKey: lkApiKey,
92
+ apiSecret: lkApiSecret,
93
+ useProxy,
94
+ minInterruptionDuration
95
+ };
96
+ this.label = `${this.constructor.name}`;
97
+ this.streams = /* @__PURE__ */ new WeakSet();
98
+ console.info("adaptive interruption detector initialized", {
99
+ baseUrl: this.options.baseUrl,
100
+ detectionInterval: this.options.detectionInterval,
101
+ audioPrefixDuration: this.options.audioPrefixDuration,
102
+ maxAudioDuration: this.options.maxAudioDuration,
103
+ minFrames: this.options.minFrames,
104
+ threshold: this.options.threshold,
105
+ inferenceTimeout: this.options.inferenceTimeout,
106
+ useProxy: this.options.useProxy
107
+ });
108
+ }
109
+ /**
110
+ * Creates a new InterruptionStreamBase for internal use.
111
+ * The stream can receive audio frames and sentinels via pushFrame().
112
+ * Use this when you need direct access to the stream for pushing frames.
113
+ */
114
+ createStream() {
115
+ const stream = new import_InterruptionStream.InterruptionStreamBase(this, {});
116
+ this.streams.add(stream);
117
+ return stream;
118
+ }
119
+ /**
120
+ * Creates a new interruption stream and returns a ReadableStream of InterruptionEvents.
121
+ * This is a convenience method for consuming interruption events without needing
122
+ * to manage the underlying stream directly.
123
+ */
124
+ stream() {
125
+ const httpStream = this.createStream();
126
+ const transformer = new import_web.TransformStream({
127
+ transform: (chunk, controller) => {
128
+ if (chunk.type === import_interruption.InterruptionEventType.INTERRUPTION) {
129
+ this.emit("interruptionDetected");
130
+ } else if (chunk.type === import_interruption.InterruptionEventType.OVERLAP_SPEECH_ENDED) {
131
+ this.emit("overlapSpeechDetected");
132
+ }
133
+ controller.enqueue(chunk);
134
+ }
135
+ });
136
+ const stream = httpStream.stream.pipeThrough(transformer);
137
+ return stream;
138
+ }
139
+ updateOptions(options) {
140
+ if (options.threshold !== void 0) {
141
+ this.options.threshold = options.threshold;
142
+ }
143
+ if (options.minInterruptionDuration !== void 0) {
144
+ this.options.minFrames = Math.ceil(options.minInterruptionDuration * import_defaults.FRAMES_PER_SECOND);
145
+ }
146
+ }
147
+ }
148
+ // Annotate the CommonJS export names for ESM import in node:
149
+ 0 && (module.exports = {
150
+ AdaptiveInterruptionDetector
151
+ });
152
+ //# sourceMappingURL=AdaptiveInterruptionDetector.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/inference/interruption/AdaptiveInterruptionDetector.ts"],"sourcesContent":["import type { TypedEventEmitter } from '@livekit/typed-emitter';\nimport EventEmitter from 'events';\nimport { type ReadableStream, TransformStream } from 'stream/web';\nimport { InterruptionStreamBase } from './InterruptionStream.js';\nimport {\n DEFAULT_BASE_URL,\n FRAMES_PER_SECOND,\n SAMPLE_RATE,\n interruptionOptionDefaults,\n} from './defaults.js';\nimport {\n type InterruptionDetectionError,\n type InterruptionEvent,\n InterruptionEventType,\n} from './interruption.js';\n\ntype InterruptionCallbacks = {\n interruptionDetected: () => void;\n overlapSpeechDetected: () => void;\n error: (error: InterruptionDetectionError) => void;\n};\n\nexport interface InterruptionOptions {\n sampleRate: number;\n threshold: number;\n minFrames: number;\n maxAudioDuration: number;\n audioPrefixDuration: number;\n detectionInterval: number;\n inferenceTimeout: number;\n minInterruptionDuration: number;\n baseUrl: string;\n apiKey: string;\n apiSecret: string;\n useProxy: boolean;\n}\n\nexport type AdaptiveInterruptionDetectorOptions = Partial<InterruptionOptions>;\n\nexport class AdaptiveInterruptionDetector extends (EventEmitter as new () => TypedEventEmitter<InterruptionCallbacks>) {\n options: InterruptionOptions;\n private label: string;\n private streams: WeakSet<object>; // TODO: Union of InterruptionHttpStream | InterruptionWebSocketStream\n\n constructor(options: AdaptiveInterruptionDetectorOptions = {}) {\n super();\n\n const {\n maxAudioDuration,\n baseUrl,\n apiKey,\n apiSecret,\n useProxy: useProxyArg,\n audioPrefixDuration,\n threshold,\n detectionInterval,\n inferenceTimeout,\n minInterruptionDuration,\n } = { ...interruptionOptionDefaults, ...options };\n\n if (maxAudioDuration > 3.0) {\n throw new Error('maxAudioDuration must be less than or equal to 3.0 seconds');\n }\n\n const lkBaseUrl = baseUrl ?? process.env.LIVEKIT_REMOTE_EOT_URL ?? DEFAULT_BASE_URL;\n let lkApiKey = apiKey ?? '';\n let lkApiSecret = apiSecret ?? '';\n let useProxy: boolean;\n\n // use LiveKit credentials if using the default base URL (inference)\n if (lkBaseUrl === DEFAULT_BASE_URL) {\n lkApiKey =\n apiKey ?? process.env.LIVEKIT_INFERENCE_API_KEY ?? process.env.LIVEKIT_API_KEY ?? '';\n if (!lkApiKey) {\n throw new Error(\n 'apiKey is required, either as argument or set LIVEKIT_API_KEY environmental variable',\n );\n }\n\n lkApiSecret =\n apiSecret ??\n process.env.LIVEKIT_INFERENCE_API_SECRET ??\n process.env.LIVEKIT_API_SECRET ??\n '';\n if (!lkApiSecret) {\n throw new Error(\n 'apiSecret is required, either as argument or set LIVEKIT_API_SECRET environmental variable',\n );\n }\n\n useProxy = true;\n } else {\n useProxy = useProxyArg ?? false;\n }\n\n this.options = {\n sampleRate: SAMPLE_RATE,\n threshold,\n minFrames: Math.ceil(minInterruptionDuration * FRAMES_PER_SECOND),\n maxAudioDuration,\n audioPrefixDuration,\n detectionInterval,\n inferenceTimeout,\n baseUrl: lkBaseUrl,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n useProxy,\n minInterruptionDuration,\n };\n\n this.label = `${this.constructor.name}`;\n this.streams = new WeakSet();\n\n console.info('adaptive interruption detector initialized', {\n baseUrl: this.options.baseUrl,\n detectionInterval: this.options.detectionInterval,\n audioPrefixDuration: this.options.audioPrefixDuration,\n maxAudioDuration: this.options.maxAudioDuration,\n minFrames: this.options.minFrames,\n threshold: this.options.threshold,\n inferenceTimeout: this.options.inferenceTimeout,\n useProxy: this.options.useProxy,\n });\n }\n\n /**\n * Creates a new InterruptionStreamBase for internal use.\n * The stream can receive audio frames and sentinels via pushFrame().\n * Use this when you need direct access to the stream for pushing frames.\n */\n createStream(): InterruptionStreamBase {\n const stream = new InterruptionStreamBase(this, {});\n this.streams.add(stream);\n return stream;\n }\n\n /**\n * Creates a new interruption stream and returns a ReadableStream of InterruptionEvents.\n * This is a convenience method for consuming interruption events without needing\n * to manage the underlying stream directly.\n */\n stream(): ReadableStream<InterruptionEvent> {\n const httpStream = this.createStream();\n const transformer = new TransformStream<InterruptionEvent, InterruptionEvent>({\n transform: (chunk, controller) => {\n if (chunk.type === InterruptionEventType.INTERRUPTION) {\n this.emit('interruptionDetected'); // TODO payload\n } else if (chunk.type === InterruptionEventType.OVERLAP_SPEECH_ENDED) {\n this.emit('overlapSpeechDetected'); // TODO payload\n }\n controller.enqueue(chunk);\n },\n });\n const stream = httpStream.stream.pipeThrough(transformer);\n return stream;\n }\n\n updateOptions(options: { threshold?: number; minInterruptionDuration?: number }): void {\n if (options.threshold !== undefined) {\n this.options.threshold = options.threshold;\n }\n if (options.minInterruptionDuration !== undefined) {\n this.options.minFrames = Math.ceil(options.minInterruptionDuration * FRAMES_PER_SECOND);\n }\n }\n}\n"],"mappings":"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","names":["EventEmitter"]}
@@ -0,0 +1,50 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ import type { TypedEventEmitter } from '@livekit/typed-emitter';
3
+ import { type ReadableStream } from 'stream/web';
4
+ import { InterruptionStreamBase } from './InterruptionStream.js';
5
+ import { type InterruptionDetectionError, type InterruptionEvent } from './interruption.js';
6
+ type InterruptionCallbacks = {
7
+ interruptionDetected: () => void;
8
+ overlapSpeechDetected: () => void;
9
+ error: (error: InterruptionDetectionError) => void;
10
+ };
11
+ export interface InterruptionOptions {
12
+ sampleRate: number;
13
+ threshold: number;
14
+ minFrames: number;
15
+ maxAudioDuration: number;
16
+ audioPrefixDuration: number;
17
+ detectionInterval: number;
18
+ inferenceTimeout: number;
19
+ minInterruptionDuration: number;
20
+ baseUrl: string;
21
+ apiKey: string;
22
+ apiSecret: string;
23
+ useProxy: boolean;
24
+ }
25
+ export type AdaptiveInterruptionDetectorOptions = Partial<InterruptionOptions>;
26
+ declare const AdaptiveInterruptionDetector_base: new () => TypedEventEmitter<InterruptionCallbacks>;
27
+ export declare class AdaptiveInterruptionDetector extends AdaptiveInterruptionDetector_base {
28
+ options: InterruptionOptions;
29
+ private label;
30
+ private streams;
31
+ constructor(options?: AdaptiveInterruptionDetectorOptions);
32
+ /**
33
+ * Creates a new InterruptionStreamBase for internal use.
34
+ * The stream can receive audio frames and sentinels via pushFrame().
35
+ * Use this when you need direct access to the stream for pushing frames.
36
+ */
37
+ createStream(): InterruptionStreamBase;
38
+ /**
39
+ * Creates a new interruption stream and returns a ReadableStream of InterruptionEvents.
40
+ * This is a convenience method for consuming interruption events without needing
41
+ * to manage the underlying stream directly.
42
+ */
43
+ stream(): ReadableStream<InterruptionEvent>;
44
+ updateOptions(options: {
45
+ threshold?: number;
46
+ minInterruptionDuration?: number;
47
+ }): void;
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=AdaptiveInterruptionDetector.d.ts.map
@@ -0,0 +1,50 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ import type { TypedEventEmitter } from '@livekit/typed-emitter';
3
+ import { type ReadableStream } from 'stream/web';
4
+ import { InterruptionStreamBase } from './InterruptionStream.js';
5
+ import { type InterruptionDetectionError, type InterruptionEvent } from './interruption.js';
6
+ type InterruptionCallbacks = {
7
+ interruptionDetected: () => void;
8
+ overlapSpeechDetected: () => void;
9
+ error: (error: InterruptionDetectionError) => void;
10
+ };
11
+ export interface InterruptionOptions {
12
+ sampleRate: number;
13
+ threshold: number;
14
+ minFrames: number;
15
+ maxAudioDuration: number;
16
+ audioPrefixDuration: number;
17
+ detectionInterval: number;
18
+ inferenceTimeout: number;
19
+ minInterruptionDuration: number;
20
+ baseUrl: string;
21
+ apiKey: string;
22
+ apiSecret: string;
23
+ useProxy: boolean;
24
+ }
25
+ export type AdaptiveInterruptionDetectorOptions = Partial<InterruptionOptions>;
26
+ declare const AdaptiveInterruptionDetector_base: new () => TypedEventEmitter<InterruptionCallbacks>;
27
+ export declare class AdaptiveInterruptionDetector extends AdaptiveInterruptionDetector_base {
28
+ options: InterruptionOptions;
29
+ private label;
30
+ private streams;
31
+ constructor(options?: AdaptiveInterruptionDetectorOptions);
32
+ /**
33
+ * Creates a new InterruptionStreamBase for internal use.
34
+ * The stream can receive audio frames and sentinels via pushFrame().
35
+ * Use this when you need direct access to the stream for pushing frames.
36
+ */
37
+ createStream(): InterruptionStreamBase;
38
+ /**
39
+ * Creates a new interruption stream and returns a ReadableStream of InterruptionEvents.
40
+ * This is a convenience method for consuming interruption events without needing
41
+ * to manage the underlying stream directly.
42
+ */
43
+ stream(): ReadableStream<InterruptionEvent>;
44
+ updateOptions(options: {
45
+ threshold?: number;
46
+ minInterruptionDuration?: number;
47
+ }): void;
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=AdaptiveInterruptionDetector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdaptiveInterruptionDetector.d.ts","sourceRoot":"","sources":["../../../src/inference/interruption/AdaptiveInterruptionDetector.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,OAAO,EAAE,KAAK,cAAc,EAAmB,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAOjE,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,iBAAiB,EAEvB,MAAM,mBAAmB,CAAC;AAE3B,KAAK,qBAAqB,GAAG;IAC3B,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC,qBAAqB,EAAE,MAAM,IAAI,CAAC;IAClC,KAAK,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC;CACpD,CAAC;AAEF,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,uBAAuB,EAAE,MAAM,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,mCAAmC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;2DAEF,kBAAkB,qBAAqB,CAAC;AAArH,qBAAa,4BAA6B,SAAQ,iCAAoE;IACpH,OAAO,EAAE,mBAAmB,CAAC;IAC7B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAkB;gBAErB,OAAO,GAAE,mCAAwC;IAiF7D;;;;OAIG;IACH,YAAY,IAAI,sBAAsB;IAMtC;;;;OAIG;IACH,MAAM,IAAI,cAAc,CAAC,iBAAiB,CAAC;IAgB3C,aAAa,CAAC,OAAO,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,uBAAuB,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;CAQvF"}
@@ -0,0 +1,125 @@
1
+ import EventEmitter from "events";
2
+ import { TransformStream } from "stream/web";
3
+ import { InterruptionStreamBase } from "./InterruptionStream.js";
4
+ import {
5
+ DEFAULT_BASE_URL,
6
+ FRAMES_PER_SECOND,
7
+ SAMPLE_RATE,
8
+ interruptionOptionDefaults
9
+ } from "./defaults.js";
10
+ import {
11
+ InterruptionEventType
12
+ } from "./interruption.js";
13
+ class AdaptiveInterruptionDetector extends EventEmitter {
14
+ options;
15
+ label;
16
+ streams;
17
+ // TODO: Union of InterruptionHttpStream | InterruptionWebSocketStream
18
+ constructor(options = {}) {
19
+ super();
20
+ const {
21
+ maxAudioDuration,
22
+ baseUrl,
23
+ apiKey,
24
+ apiSecret,
25
+ useProxy: useProxyArg,
26
+ audioPrefixDuration,
27
+ threshold,
28
+ detectionInterval,
29
+ inferenceTimeout,
30
+ minInterruptionDuration
31
+ } = { ...interruptionOptionDefaults, ...options };
32
+ if (maxAudioDuration > 3) {
33
+ throw new Error("maxAudioDuration must be less than or equal to 3.0 seconds");
34
+ }
35
+ const lkBaseUrl = baseUrl ?? process.env.LIVEKIT_REMOTE_EOT_URL ?? DEFAULT_BASE_URL;
36
+ let lkApiKey = apiKey ?? "";
37
+ let lkApiSecret = apiSecret ?? "";
38
+ let useProxy;
39
+ if (lkBaseUrl === DEFAULT_BASE_URL) {
40
+ lkApiKey = apiKey ?? process.env.LIVEKIT_INFERENCE_API_KEY ?? process.env.LIVEKIT_API_KEY ?? "";
41
+ if (!lkApiKey) {
42
+ throw new Error(
43
+ "apiKey is required, either as argument or set LIVEKIT_API_KEY environmental variable"
44
+ );
45
+ }
46
+ lkApiSecret = apiSecret ?? process.env.LIVEKIT_INFERENCE_API_SECRET ?? process.env.LIVEKIT_API_SECRET ?? "";
47
+ if (!lkApiSecret) {
48
+ throw new Error(
49
+ "apiSecret is required, either as argument or set LIVEKIT_API_SECRET environmental variable"
50
+ );
51
+ }
52
+ useProxy = true;
53
+ } else {
54
+ useProxy = useProxyArg ?? false;
55
+ }
56
+ this.options = {
57
+ sampleRate: SAMPLE_RATE,
58
+ threshold,
59
+ minFrames: Math.ceil(minInterruptionDuration * FRAMES_PER_SECOND),
60
+ maxAudioDuration,
61
+ audioPrefixDuration,
62
+ detectionInterval,
63
+ inferenceTimeout,
64
+ baseUrl: lkBaseUrl,
65
+ apiKey: lkApiKey,
66
+ apiSecret: lkApiSecret,
67
+ useProxy,
68
+ minInterruptionDuration
69
+ };
70
+ this.label = `${this.constructor.name}`;
71
+ this.streams = /* @__PURE__ */ new WeakSet();
72
+ console.info("adaptive interruption detector initialized", {
73
+ baseUrl: this.options.baseUrl,
74
+ detectionInterval: this.options.detectionInterval,
75
+ audioPrefixDuration: this.options.audioPrefixDuration,
76
+ maxAudioDuration: this.options.maxAudioDuration,
77
+ minFrames: this.options.minFrames,
78
+ threshold: this.options.threshold,
79
+ inferenceTimeout: this.options.inferenceTimeout,
80
+ useProxy: this.options.useProxy
81
+ });
82
+ }
83
+ /**
84
+ * Creates a new InterruptionStreamBase for internal use.
85
+ * The stream can receive audio frames and sentinels via pushFrame().
86
+ * Use this when you need direct access to the stream for pushing frames.
87
+ */
88
+ createStream() {
89
+ const stream = new InterruptionStreamBase(this, {});
90
+ this.streams.add(stream);
91
+ return stream;
92
+ }
93
+ /**
94
+ * Creates a new interruption stream and returns a ReadableStream of InterruptionEvents.
95
+ * This is a convenience method for consuming interruption events without needing
96
+ * to manage the underlying stream directly.
97
+ */
98
+ stream() {
99
+ const httpStream = this.createStream();
100
+ const transformer = new TransformStream({
101
+ transform: (chunk, controller) => {
102
+ if (chunk.type === InterruptionEventType.INTERRUPTION) {
103
+ this.emit("interruptionDetected");
104
+ } else if (chunk.type === InterruptionEventType.OVERLAP_SPEECH_ENDED) {
105
+ this.emit("overlapSpeechDetected");
106
+ }
107
+ controller.enqueue(chunk);
108
+ }
109
+ });
110
+ const stream = httpStream.stream.pipeThrough(transformer);
111
+ return stream;
112
+ }
113
+ updateOptions(options) {
114
+ if (options.threshold !== void 0) {
115
+ this.options.threshold = options.threshold;
116
+ }
117
+ if (options.minInterruptionDuration !== void 0) {
118
+ this.options.minFrames = Math.ceil(options.minInterruptionDuration * FRAMES_PER_SECOND);
119
+ }
120
+ }
121
+ }
122
+ export {
123
+ AdaptiveInterruptionDetector
124
+ };
125
+ //# sourceMappingURL=AdaptiveInterruptionDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/inference/interruption/AdaptiveInterruptionDetector.ts"],"sourcesContent":["import type { TypedEventEmitter } from '@livekit/typed-emitter';\nimport EventEmitter from 'events';\nimport { type ReadableStream, TransformStream } from 'stream/web';\nimport { InterruptionStreamBase } from './InterruptionStream.js';\nimport {\n DEFAULT_BASE_URL,\n FRAMES_PER_SECOND,\n SAMPLE_RATE,\n interruptionOptionDefaults,\n} from './defaults.js';\nimport {\n type InterruptionDetectionError,\n type InterruptionEvent,\n InterruptionEventType,\n} from './interruption.js';\n\ntype InterruptionCallbacks = {\n interruptionDetected: () => void;\n overlapSpeechDetected: () => void;\n error: (error: InterruptionDetectionError) => void;\n};\n\nexport interface InterruptionOptions {\n sampleRate: number;\n threshold: number;\n minFrames: number;\n maxAudioDuration: number;\n audioPrefixDuration: number;\n detectionInterval: number;\n inferenceTimeout: number;\n minInterruptionDuration: number;\n baseUrl: string;\n apiKey: string;\n apiSecret: string;\n useProxy: boolean;\n}\n\nexport type AdaptiveInterruptionDetectorOptions = Partial<InterruptionOptions>;\n\nexport class AdaptiveInterruptionDetector extends (EventEmitter as new () => TypedEventEmitter<InterruptionCallbacks>) {\n options: InterruptionOptions;\n private label: string;\n private streams: WeakSet<object>; // TODO: Union of InterruptionHttpStream | InterruptionWebSocketStream\n\n constructor(options: AdaptiveInterruptionDetectorOptions = {}) {\n super();\n\n const {\n maxAudioDuration,\n baseUrl,\n apiKey,\n apiSecret,\n useProxy: useProxyArg,\n audioPrefixDuration,\n threshold,\n detectionInterval,\n inferenceTimeout,\n minInterruptionDuration,\n } = { ...interruptionOptionDefaults, ...options };\n\n if (maxAudioDuration > 3.0) {\n throw new Error('maxAudioDuration must be less than or equal to 3.0 seconds');\n }\n\n const lkBaseUrl = baseUrl ?? process.env.LIVEKIT_REMOTE_EOT_URL ?? DEFAULT_BASE_URL;\n let lkApiKey = apiKey ?? '';\n let lkApiSecret = apiSecret ?? '';\n let useProxy: boolean;\n\n // use LiveKit credentials if using the default base URL (inference)\n if (lkBaseUrl === DEFAULT_BASE_URL) {\n lkApiKey =\n apiKey ?? process.env.LIVEKIT_INFERENCE_API_KEY ?? process.env.LIVEKIT_API_KEY ?? '';\n if (!lkApiKey) {\n throw new Error(\n 'apiKey is required, either as argument or set LIVEKIT_API_KEY environmental variable',\n );\n }\n\n lkApiSecret =\n apiSecret ??\n process.env.LIVEKIT_INFERENCE_API_SECRET ??\n process.env.LIVEKIT_API_SECRET ??\n '';\n if (!lkApiSecret) {\n throw new Error(\n 'apiSecret is required, either as argument or set LIVEKIT_API_SECRET environmental variable',\n );\n }\n\n useProxy = true;\n } else {\n useProxy = useProxyArg ?? false;\n }\n\n this.options = {\n sampleRate: SAMPLE_RATE,\n threshold,\n minFrames: Math.ceil(minInterruptionDuration * FRAMES_PER_SECOND),\n maxAudioDuration,\n audioPrefixDuration,\n detectionInterval,\n inferenceTimeout,\n baseUrl: lkBaseUrl,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n useProxy,\n minInterruptionDuration,\n };\n\n this.label = `${this.constructor.name}`;\n this.streams = new WeakSet();\n\n console.info('adaptive interruption detector initialized', {\n baseUrl: this.options.baseUrl,\n detectionInterval: this.options.detectionInterval,\n audioPrefixDuration: this.options.audioPrefixDuration,\n maxAudioDuration: this.options.maxAudioDuration,\n minFrames: this.options.minFrames,\n threshold: this.options.threshold,\n inferenceTimeout: this.options.inferenceTimeout,\n useProxy: this.options.useProxy,\n });\n }\n\n /**\n * Creates a new InterruptionStreamBase for internal use.\n * The stream can receive audio frames and sentinels via pushFrame().\n * Use this when you need direct access to the stream for pushing frames.\n */\n createStream(): InterruptionStreamBase {\n const stream = new InterruptionStreamBase(this, {});\n this.streams.add(stream);\n return stream;\n }\n\n /**\n * Creates a new interruption stream and returns a ReadableStream of InterruptionEvents.\n * This is a convenience method for consuming interruption events without needing\n * to manage the underlying stream directly.\n */\n stream(): ReadableStream<InterruptionEvent> {\n const httpStream = this.createStream();\n const transformer = new TransformStream<InterruptionEvent, InterruptionEvent>({\n transform: (chunk, controller) => {\n if (chunk.type === InterruptionEventType.INTERRUPTION) {\n this.emit('interruptionDetected'); // TODO payload\n } else if (chunk.type === InterruptionEventType.OVERLAP_SPEECH_ENDED) {\n this.emit('overlapSpeechDetected'); // TODO payload\n }\n controller.enqueue(chunk);\n },\n });\n const stream = httpStream.stream.pipeThrough(transformer);\n return stream;\n }\n\n updateOptions(options: { threshold?: number; minInterruptionDuration?: number }): void {\n if (options.threshold !== undefined) {\n this.options.threshold = options.threshold;\n }\n if (options.minInterruptionDuration !== undefined) {\n this.options.minFrames = Math.ceil(options.minInterruptionDuration * FRAMES_PER_SECOND);\n }\n }\n}\n"],"mappings":"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","names":[]}