@elevenlabs/client 1.8.0 → 1.9.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 (39) hide show
  1. package/dist/InputController.d.ts +7 -0
  2. package/dist/InputController.d.ts.map +1 -1
  3. package/dist/InputController.js +2 -1
  4. package/dist/InputController.js.map +1 -1
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib.iife.js +142 -28
  10. package/dist/lib.iife.js.map +1 -1
  11. package/dist/platform/tsconfig.test.tsbuildinfo +1 -1
  12. package/dist/platform/web/VoiceSessionSetup.d.ts.map +1 -1
  13. package/dist/platform/web/VoiceSessionSetup.js +15 -2
  14. package/dist/platform/web/VoiceSessionSetup.js.map +1 -1
  15. package/dist/platform/web/audioUnlock.d.ts +11 -0
  16. package/dist/platform/web/audioUnlock.d.ts.map +1 -0
  17. package/dist/platform/web/audioUnlock.js +74 -0
  18. package/dist/platform/web/audioUnlock.js.map +1 -0
  19. package/dist/platform/web/index.d.ts.map +1 -1
  20. package/dist/platform/web/index.js +6 -0
  21. package/dist/platform/web/index.js.map +1 -1
  22. package/dist/platform/web/input.d.ts +2 -2
  23. package/dist/platform/web/input.d.ts.map +1 -1
  24. package/dist/platform/web/input.js +12 -5
  25. package/dist/platform/web/input.js.map +1 -1
  26. package/dist/platform/web/output.d.ts +3 -1
  27. package/dist/platform/web/output.d.ts.map +1 -1
  28. package/dist/platform/web/output.js +29 -3
  29. package/dist/platform/web/output.js.map +1 -1
  30. package/dist/platform/web/rawAudioProcessor.generated.d.ts.map +1 -1
  31. package/dist/platform/web/rawAudioProcessor.generated.js +5 -1
  32. package/dist/platform/web/rawAudioProcessor.generated.js.map +1 -1
  33. package/dist/utils/WebSocketConnection.d.ts +1 -0
  34. package/dist/utils/WebSocketConnection.d.ts.map +1 -1
  35. package/dist/utils/WebSocketConnection.js +15 -0
  36. package/dist/utils/WebSocketConnection.js.map +1 -1
  37. package/dist/version.d.ts +1 -1
  38. package/dist/version.js +1 -1
  39. package/package.json +1 -1
@@ -1,10 +1,17 @@
1
1
  import type { FormatConfig } from "./utils/BaseConnection.js";
2
+ /** Default microphone audio chunk duration sent to the agent (WebSocket path). */
3
+ export declare const DEFAULT_INPUT_CHUNK_DURATION_MS = 25;
2
4
  export type InputDeviceConfig = {
3
5
  inputDeviceId?: string;
4
6
  preferHeadphonesForIosDevices?: boolean;
5
7
  };
6
8
  export type InputConfig = InputDeviceConfig & {
7
9
  onError?(message: string, context?: unknown): void;
10
+ /**
11
+ * Duration of each microphone audio chunk sent to the agent, in milliseconds.
12
+ * Only applies to the WebSocket input path (AudioWorklet). Default: 25.
13
+ */
14
+ inputChunkDurationMs?: number;
8
15
  };
9
16
  export type InputMessageEvent = MessageEvent<[Uint8Array, number]>;
10
17
  export type InputListener = (event: InputMessageEvent) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"InputController.d.ts","sourceRoot":"","sources":["../src/InputController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG;IAC5C,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,YAAY,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;AACnE,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;AAE/D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3C,cAAc,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;CAC/C,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,SAAS,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,IAAI,OAAO,CAAC;IAEnB;;;;OAIG;IACH,WAAW,IAAI,YAAY,GAAG,SAAS,CAAC;IAExC,mDAAmD;IACnD,SAAS,IAAI,MAAM,CAAC;IACpB;;;;OAIG;IACH,oBAAoB,CAAC,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;CAC7D"}
1
+ {"version":3,"file":"InputController.d.ts","sourceRoot":"","sources":["../src/InputController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,kFAAkF;AAClF,eAAO,MAAM,+BAA+B,KAAK,CAAC;AAElD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG;IAC5C,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACnD;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,YAAY,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;AACnE,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;AAE/D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3C,cAAc,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;CAC/C,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,SAAS,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,IAAI,OAAO,CAAC;IAEnB;;;;OAIG;IACH,WAAW,IAAI,YAAY,GAAG,SAAS,CAAC;IAExC,mDAAmD;IACnD,SAAS,IAAI,MAAM,CAAC;IACpB;;;;OAIG;IACH,oBAAoB,CAAC,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;CAC7D"}
@@ -1,2 +1,3 @@
1
- export {};
1
+ /** Default microphone audio chunk duration sent to the agent (WebSocket path). */
2
+ export const DEFAULT_INPUT_CHUNK_DURATION_MS = 25;
2
3
  //# sourceMappingURL=InputController.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InputController.js","sourceRoot":"","sources":["../src/InputController.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"InputController.js","sourceRoot":"","sources":["../src/InputController.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,MAAM,CAAC,MAAM,+BAA+B,GAAG,EAAE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import { TextConversation } from "./TextConversation.js";
3
3
  import { VoiceConversation } from "./VoiceConversation.js";
4
4
  export type { Mode, Role, Options, PartialOptions, ClientToolsConfig, Callbacks, Status, AudioWorkletConfig, MultimodalMessageInput, UploadFileResult, ConversationCreatedCallback, ConversationLifecycleOptions, ContextualUpdateOptions, } from "./BaseConversation.js";
5
5
  export type { InputController, InputDeviceConfig, InputConfig, } from "./InputController.js";
6
+ export { DEFAULT_INPUT_CHUNK_DURATION_MS } from "./InputController.js";
6
7
  export type { OutputController, OutputDeviceConfig, OutputConfig, } from "./OutputController.js";
7
8
  export type { IncomingSocketEvent, VadScoreEvent, AudioAlignmentEvent, } from "./utils/events.js";
8
9
  export type { SessionConfig, BaseSessionConfig, DisconnectionContext, DisconnectionDetails, Language, ConnectionType, FormatConfig, } from "./utils/BaseConnection.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAExE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,YAAY,EACV,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,MAAM,EACN,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,2BAA2B,EAC3B,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,GACb,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,mBAAmB,EACnB,aAAa,EACb,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,QAAQ,EACR,cAAc,EACd,YAAY,GACb,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EACL,MAAM,EACN,WAAW,EACX,cAAc,EACd,cAAc,EACd,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,wCAAwC,EACxC,kBAAkB,EAClB,sBAAsB,EACtB,+BAA+B,EAC/B,iCAAiC,EACjC,6BAA6B,EAC7B,iCAAiC,EACjC,6BAA6B,EAC7B,uBAAuB,EACvB,+BAA+B,EAC/B,mCAAmC,EACnC,0CAA0C,EAC1C,mCAAmC,EACnC,2CAA2C,GAC5C,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAEhE,UAAU,qBAAqB;IAC7B,YAAY,CAAC,CAAC,SAAS,cAAc,EACnC,OAAO,EAAE,CAAC,GACT,CAAC,SAAS;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,GAC3B,OAAO,CAAC,gBAAgB,CAAC,GACzB,CAAC,SAAS;QAAE,QAAQ,EAAE,KAAK,CAAA;KAAE,GAC3B,OAAO,CAAC,iBAAiB,CAAC,GAC1B,OAAO,CAAC,gBAAgB,GAAG,iBAAiB,CAAC,CAAC;CACrD;AAED,eAAO,MAAM,YAAY,EAAE,qBAOD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAExE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,YAAY,EACV,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,MAAM,EACN,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,2BAA2B,EAC3B,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,+BAA+B,EAAE,MAAM,sBAAsB,CAAC;AACvE,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,GACb,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,mBAAmB,EACnB,aAAa,EACb,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,QAAQ,EACR,cAAc,EACd,YAAY,GACb,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EACL,MAAM,EACN,WAAW,EACX,cAAc,EACd,cAAc,EACd,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,wCAAwC,EACxC,kBAAkB,EAClB,sBAAsB,EACtB,+BAA+B,EAC/B,iCAAiC,EACjC,6BAA6B,EAC7B,iCAAiC,EACjC,6BAA6B,EAC7B,uBAAuB,EACvB,+BAA+B,EAC/B,mCAAmC,EACnC,0CAA0C,EAC1C,mCAAmC,EACnC,2CAA2C,GAC5C,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAEhE,UAAU,qBAAqB;IAC7B,YAAY,CAAC,CAAC,SAAS,cAAc,EACnC,OAAO,EAAE,CAAC,GACT,CAAC,SAAS;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,GAC3B,OAAO,CAAC,gBAAgB,CAAC,GACzB,CAAC,SAAS;QAAE,QAAQ,EAAE,KAAK,CAAA;KAAE,GAC3B,OAAO,CAAC,iBAAiB,CAAC,GAC1B,OAAO,CAAC,gBAAgB,GAAG,iBAAiB,CAAC,CAAC;CACrD;AAED,eAAO,MAAM,YAAY,EAAE,qBAOD,CAAC"}
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import { isTextOnly } from "./BaseConversation.js";
2
2
  import { assertRuntimeCompatibility } from "./runtime.js";
3
3
  import { TextConversation } from "./TextConversation.js";
4
4
  import { VoiceConversation } from "./VoiceConversation.js";
5
+ export { DEFAULT_INPUT_CHUNK_DURATION_MS } from "./InputController.js";
5
6
  export { createConnection } from "./utils/ConnectionFactory.js";
6
7
  export { WebSocketConnection } from "./utils/WebSocketConnection.js";
7
8
  export { WebRTCConnection } from "./utils/WebRTCConnection.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAuB,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAyC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,iBAAiB;AACjB,OAAO,EACL,MAAM,EACN,WAAW,EACX,cAAc,EACd,cAAc,EACd,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAmC3B,MAAM,CAAC,MAAM,YAAY,GAA0B;IACjD,KAAK,CAAC,YAAY,CAAC,OAAuB;QACxC,0BAA0B,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAC,OAAO,CAAC;YACxB,CAAC,CAAC,gBAAgB,CAAC,YAAY,CAAC,OAAO,CAAC;YACxC,CAAC,CAAC,iBAAiB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;CACuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAuB,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAsB3D,OAAO,EAAE,+BAA+B,EAAE,MAAM,sBAAsB,CAAC;AAoBvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,iBAAiB;AACjB,OAAO,EACL,MAAM,EACN,WAAW,EACX,cAAc,EACd,cAAc,EACd,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAmC3B,MAAM,CAAC,MAAM,YAAY,GAA0B;IACjD,KAAK,CAAC,YAAY,CAAC,OAAuB;QACxC,0BAA0B,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAC,OAAO,CAAC;YACxB,CAAC,CAAC,gBAAgB,CAAC,YAAY,CAAC,OAAO,CAAC;YACxC,CAAC,CAAC,iBAAiB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;CACuB,CAAC"}
package/dist/lib.iife.js CHANGED
@@ -92,7 +92,7 @@ var ElevenLabsClient = (function(exports) {
92
92
  //#region src/sourceInfo.ts
93
93
  let sourceInfo = Object.freeze({
94
94
  name: "js_sdk",
95
- version: "1.8.0"
95
+ version: "1.9.0"
96
96
  });
97
97
  //#endregion
98
98
  //#region src/utils/events.ts
@@ -21955,14 +21955,39 @@ registerProcessor("audioConcatProcessor", AudioConcatProcessor);
21955
21955
  };
21956
21956
  }
21957
21957
  //#endregion
21958
+ //#region src/platform/web/compatibility.ts
21959
+ function isIosDevice() {
21960
+ return [
21961
+ "iPad Simulator",
21962
+ "iPhone Simulator",
21963
+ "iPod Simulator",
21964
+ "iPad",
21965
+ "iPhone",
21966
+ "iPod"
21967
+ ].includes(navigator.platform) || navigator.userAgent.includes("Mac") && "ontouchend" in document;
21968
+ }
21969
+ function isAndroidDevice() {
21970
+ return /android/i.test(navigator.userAgent);
21971
+ }
21972
+ //#endregion
21958
21973
  //#region src/platform/web/output.ts
21974
+ function maybePrimeIosPlayback({ sampleRate, format, worklet, audioElement }) {
21975
+ if (!isIosDevice()) return;
21976
+ const primeFrameCount = Math.floor(sampleRate * 100 / 1e3);
21977
+ const silentBuffer = format === "ulaw" ? new Uint8Array(primeFrameCount).fill(255) : new Int16Array(primeFrameCount);
21978
+ worklet.port.postMessage({
21979
+ type: "buffer",
21980
+ buffer: silentBuffer.buffer
21981
+ });
21982
+ audioElement.play().catch(() => {});
21983
+ }
21959
21984
  var MediaDeviceOutput = class MediaDeviceOutput {
21960
- static async create({ sampleRate, format, outputDeviceId, workletPaths, libsampleratePath }) {
21961
- let context = null;
21985
+ static async create({ sampleRate, format, outputDeviceId, workletPaths, libsampleratePath, audioContext }) {
21986
+ let context = audioContext ?? null;
21962
21987
  let audioElement = null;
21963
21988
  try {
21964
21989
  const supportsSampleRateConstraint = navigator.mediaDevices.getSupportedConstraints().sampleRate;
21965
- context = new AudioContext(supportsSampleRateConstraint ? { sampleRate } : {});
21990
+ if (!context) context = new AudioContext(supportsSampleRateConstraint ? { sampleRate } : {});
21966
21991
  const analyser = context.createAnalyser();
21967
21992
  const gain = context.createGain();
21968
21993
  audioElement = new Audio();
@@ -21988,6 +22013,12 @@ registerProcessor("audioConcatProcessor", AudioConcatProcessor);
21988
22013
  });
21989
22014
  worklet.connect(gain);
21990
22015
  await context.resume();
22016
+ maybePrimeIosPlayback({
22017
+ sampleRate,
22018
+ format,
22019
+ worklet,
22020
+ audioElement
22021
+ });
21991
22022
  if (outputDeviceId && audioElement.setSinkId) await audioElement.setSinkId(outputDeviceId);
21992
22023
  return new MediaDeviceOutput(context, analyser, gain, worklet, audioElement);
21993
22024
  } catch (error) {
@@ -22126,7 +22157,11 @@ class RawAudioProcessor extends AudioWorkletProcessor {
22126
22157
  case "setFormat":
22127
22158
  this.isMuted = false;
22128
22159
  this.buffer = []; // Initialize an empty buffer
22129
- this.bufferSize = data.sampleRate / 10;
22160
+ const chunkDurationMs = data.chunkDurationMs ?? 25;
22161
+ this.bufferSize = Math.max(
22162
+ 1,
22163
+ Math.round((data.sampleRate * chunkDurationMs) / 1000)
22164
+ );
22130
22165
  this.format = data.format;
22131
22166
 
22132
22167
  if (globalThis.LibSampleRate && sampleRate !== data.sampleRate) {
@@ -22200,20 +22235,9 @@ class RawAudioProcessor extends AudioWorkletProcessor {
22200
22235
  registerProcessor("rawAudioProcessor", RawAudioProcessor);
22201
22236
  `);
22202
22237
  //#endregion
22203
- //#region src/platform/web/compatibility.ts
22204
- function isIosDevice() {
22205
- return [
22206
- "iPad Simulator",
22207
- "iPhone Simulator",
22208
- "iPod Simulator",
22209
- "iPad",
22210
- "iPhone",
22211
- "iPod"
22212
- ].includes(navigator.platform) || navigator.userAgent.includes("Mac") && "ontouchend" in document;
22213
- }
22214
- function isAndroidDevice() {
22215
- return /android/i.test(navigator.userAgent);
22216
- }
22238
+ //#region src/InputController.ts
22239
+ /** Default microphone audio chunk duration sent to the agent (WebSocket path). */
22240
+ const DEFAULT_INPUT_CHUNK_DURATION_MS = 25;
22217
22241
  //#endregion
22218
22242
  //#region src/platform/web/input.ts
22219
22243
  const defaultConstraints = {
@@ -22223,7 +22247,7 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
22223
22247
  channelCount: { ideal: 1 }
22224
22248
  };
22225
22249
  var MediaDeviceInput = class MediaDeviceInput {
22226
- static async create({ sampleRate, format, preferHeadphonesForIosDevices, inputDeviceId, workletPaths, libsampleratePath, onError }) {
22250
+ static async create({ sampleRate, format, preferHeadphonesForIosDevices, inputDeviceId, workletPaths, libsampleratePath, onError, inputChunkDurationMs = 25 }) {
22227
22251
  let context = null;
22228
22252
  let inputStream = null;
22229
22253
  try {
@@ -22255,7 +22279,8 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
22255
22279
  worklet.port.postMessage({
22256
22280
  type: "setFormat",
22257
22281
  format,
22258
- sampleRate
22282
+ sampleRate,
22283
+ chunkDurationMs: inputChunkDurationMs
22259
22284
  });
22260
22285
  source.connect(analyser);
22261
22286
  analyser.connect(worklet);
@@ -22372,6 +22397,7 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
22372
22397
  inputFormat;
22373
22398
  outputFormat;
22374
22399
  outputListeners = /* @__PURE__ */ new Set();
22400
+ pendingAudioEvents = [];
22375
22401
  constructor(socket, conversationId, inputFormat, outputFormat) {
22376
22402
  super();
22377
22403
  this.socket = socket;
@@ -22472,13 +22498,19 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
22472
22498
  }
22473
22499
  }
22474
22500
  close() {
22501
+ this.pendingAudioEvents = [];
22475
22502
  this.socket.close(1e3, "User ended conversation");
22476
22503
  }
22477
22504
  sendMessage(message) {
22478
22505
  this.socket.send(JSON.stringify(message));
22479
22506
  }
22480
22507
  addListener(listener) {
22508
+ const hadListeners = this.outputListeners.size > 0;
22481
22509
  this.outputListeners.add(listener);
22510
+ if (hadListeners || this.pendingAudioEvents.length === 0) return;
22511
+ const pending = this.pendingAudioEvents;
22512
+ this.pendingAudioEvents = [];
22513
+ for (const event of pending) listener(event);
22482
22514
  }
22483
22515
  removeListener(listener) {
22484
22516
  this.outputListeners.delete(listener);
@@ -22487,6 +22519,10 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
22487
22519
  super.handleMessage(parsedEvent);
22488
22520
  if (parsedEvent.type === "audio" && parsedEvent.audio_event.audio_base_64) {
22489
22521
  const audioEvent = { audio_base_64: parsedEvent.audio_event.audio_base_64 };
22522
+ if (this.outputListeners.size === 0) {
22523
+ this.pendingAudioEvents.push(audioEvent);
22524
+ return;
22525
+ }
22490
22526
  this.outputListeners.forEach((listener) => listener(audioEvent));
22491
22527
  }
22492
22528
  }
@@ -22553,6 +22589,70 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
22553
22589
  if (delayMs > 0) await new Promise((resolve) => setTimeout(resolve, delayMs));
22554
22590
  }
22555
22591
  //#endregion
22592
+ //#region src/platform/web/audioUnlock.ts
22593
+ const STASH_TTL_MS = 3e4;
22594
+ const UNLOCK_EVENTS = [
22595
+ "touchstart",
22596
+ "touchend",
22597
+ "click"
22598
+ ];
22599
+ let stashedAudioContext = null;
22600
+ let discardTimer = null;
22601
+ let unlockListenerInstalled = false;
22602
+ function unlockAudioContext(ctx) {
22603
+ const buffer = ctx.createBuffer(1, 1, 22050);
22604
+ const source = ctx.createBufferSource();
22605
+ source.buffer = buffer;
22606
+ source.connect(ctx.destination);
22607
+ source.start(0);
22608
+ ctx.resume().catch(() => {});
22609
+ }
22610
+ function scheduleStashDiscard() {
22611
+ if (discardTimer) clearTimeout(discardTimer);
22612
+ discardTimer = setTimeout(() => {
22613
+ discardTimer = null;
22614
+ discardStashedAudioContext();
22615
+ }, STASH_TTL_MS);
22616
+ }
22617
+ function clearStashDiscardTimer() {
22618
+ if (!discardTimer) return;
22619
+ clearTimeout(discardTimer);
22620
+ discardTimer = null;
22621
+ }
22622
+ /** Unlock iOS audio during a user gesture. No-op on non-iOS. */
22623
+ function unlockIosAudioForSession() {
22624
+ if (!isIosDevice() || stashedAudioContext) return;
22625
+ const ctx = new AudioContext();
22626
+ unlockAudioContext(ctx);
22627
+ stashedAudioContext = ctx;
22628
+ scheduleStashDiscard();
22629
+ }
22630
+ /**
22631
+ * Listen for the first user interaction on the page and unlock iOS audio in
22632
+ * the capture phase, before application click handlers run. Covers callers
22633
+ * (such as the convai widget) that `await` before `Conversation.startSession`.
22634
+ */
22635
+ function installIosAudioUnlockListener() {
22636
+ if (!isIosDevice() || unlockListenerInstalled || typeof document === "undefined") return;
22637
+ unlockListenerInstalled = true;
22638
+ const onUserGesture = () => {
22639
+ unlockIosAudioForSession();
22640
+ };
22641
+ for (const event of UNLOCK_EVENTS) document.addEventListener(event, onUserGesture, true);
22642
+ }
22643
+ function takeUnlockedAudioContext() {
22644
+ const ctx = stashedAudioContext;
22645
+ stashedAudioContext = null;
22646
+ clearStashDiscardTimer();
22647
+ return ctx;
22648
+ }
22649
+ function discardStashedAudioContext() {
22650
+ if (!stashedAudioContext) return;
22651
+ stashedAudioContext.close().catch(() => {});
22652
+ stashedAudioContext = null;
22653
+ clearStashDiscardTimer();
22654
+ }
22655
+ //#endregion
22556
22656
  //#region src/platform/web/VoiceSessionSetup.ts
22557
22657
  function detectPlatform() {
22558
22658
  if (isAndroidDevice()) return "android";
@@ -22569,17 +22669,19 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
22569
22669
  * Sets up WebSocket-specific input and output controllers using
22570
22670
  * web MediaDevice APIs (AudioContext, AudioWorklet, etc.).
22571
22671
  */
22572
- async function setupWebSocketIO(options, connection) {
22672
+ async function setupWebSocketIO(options, connection, audioContext) {
22573
22673
  const [input, output] = await Promise.all([MediaDeviceInput.create({
22574
22674
  ...connection.inputFormat,
22575
22675
  preferHeadphonesForIosDevices: options.preferHeadphonesForIosDevices,
22576
22676
  inputDeviceId: options.inputDeviceId,
22677
+ inputChunkDurationMs: options.inputChunkDurationMs,
22577
22678
  workletPaths: options.workletPaths,
22578
22679
  libsampleratePath: options.libsampleratePath
22579
22680
  }), MediaDeviceOutput.create({
22580
22681
  ...connection.outputFormat,
22581
22682
  outputDeviceId: options.outputDeviceId,
22582
- workletPaths: options.workletPaths
22683
+ workletPaths: options.workletPaths,
22684
+ audioContext: audioContext ?? void 0
22583
22685
  })]);
22584
22686
  const detachInput = attachInputToConnection(input, connection);
22585
22687
  const detachOutput = attachConnectionToOutput(connection, output);
@@ -22602,6 +22704,7 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
22602
22704
  const useWakeLock = options.useWakeLock ?? true;
22603
22705
  let wakeLock = null;
22604
22706
  let preliminaryInputStream = null;
22707
+ let unlockedAudioContext = null;
22605
22708
  try {
22606
22709
  if (useWakeLock) wakeLock = await requestWakeLock();
22607
22710
  preliminaryInputStream = await navigator.mediaDevices.getUserMedia({ audio: true });
@@ -22610,12 +22713,20 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
22610
22713
  const connection = await createConnection(options);
22611
22714
  let result;
22612
22715
  try {
22613
- if (connection instanceof WebSocketConnection) result = {
22614
- connection,
22615
- ...await setupWebSocketIO(options, connection)
22616
- };
22617
- else result = setupWebRTCSession(connection);
22716
+ if (connection instanceof WebSocketConnection) {
22717
+ unlockedAudioContext = takeUnlockedAudioContext();
22718
+ result = {
22719
+ connection,
22720
+ ...await setupWebSocketIO(options, connection, unlockedAudioContext)
22721
+ };
22722
+ unlockedAudioContext = null;
22723
+ } else {
22724
+ discardStashedAudioContext();
22725
+ result = setupWebRTCSession(connection);
22726
+ }
22618
22727
  } catch (ioError) {
22728
+ await unlockedAudioContext?.close().catch(() => {});
22729
+ unlockedAudioContext = null;
22619
22730
  connection.close();
22620
22731
  throw ioError;
22621
22732
  }
@@ -22650,6 +22761,7 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
22650
22761
  await wakeLock?.release();
22651
22762
  wakeLock = null;
22652
22763
  } catch (_e) {}
22764
+ discardStashedAudioContext();
22653
22765
  throw error;
22654
22766
  }
22655
22767
  }
@@ -23993,12 +24105,14 @@ registerProcessor("scribeAudioProcessor", ScribeAudioProcessor);
23993
24105
  } };
23994
24106
  //#endregion
23995
24107
  //#region src/platform/web/index.ts
24108
+ installIosAudioUnlockListener();
23996
24109
  setWebRTCAudioAdapterFactory(() => new WebAudioAdapter());
23997
24110
  setScribeMicrophoneSetup(webScribeMicrophoneSetup);
23998
24111
  //#endregion
23999
24112
  exports.AudioFormat = AudioFormat;
24000
24113
  exports.CommitStrategy = CommitStrategy;
24001
24114
  exports.Conversation = Conversation;
24115
+ exports.DEFAULT_INPUT_CHUNK_DURATION_MS = DEFAULT_INPUT_CHUNK_DURATION_MS;
24002
24116
  exports.RealtimeConnection = RealtimeConnection;
24003
24117
  exports.RealtimeEvents = RealtimeEvents;
24004
24118
  exports.Scribe = ScribeRealtime;