@ai-sdk/openai 4.0.11 → 4.0.14

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.
@@ -2320,16 +2320,16 @@ import {
2320
2320
  convertBase64ToUint8Array as convertBase64ToUint8Array2,
2321
2321
  convertToBase64 as convertToBase642,
2322
2322
  createJsonResponseHandler as createJsonResponseHandler5,
2323
- getWebSocketConstructor,
2323
+ connectToWebSocket,
2324
2324
  mediaTypeToExtension,
2325
2325
  parseProviderOptions as parseProviderOptions5,
2326
2326
  postFormDataToApi as postFormDataToApi2,
2327
- readWebSocketMessageText,
2328
2327
  safeParseJSON,
2329
2328
  serializeModelOptions as serializeModelOptions5,
2330
2329
  toWebSocketUrl,
2331
2330
  WORKFLOW_DESERIALIZE as WORKFLOW_DESERIALIZE5,
2332
- WORKFLOW_SERIALIZE as WORKFLOW_SERIALIZE5
2331
+ WORKFLOW_SERIALIZE as WORKFLOW_SERIALIZE5,
2332
+ waitForWebSocketBufferDrain
2333
2333
  } from "@ai-sdk/provider-utils";
2334
2334
 
2335
2335
  // src/transcription/openai-transcription-api.ts
@@ -2678,21 +2678,18 @@ function createOpenAIRealtimeTranscriptionStream({
2678
2678
  };
2679
2679
  return new ReadableStream({
2680
2680
  start: (controller) => {
2681
- const WebSocketConstructor = getWebSocketConstructor(webSocket);
2682
- const ws = new WebSocketConstructor(
2683
- url,
2684
- getOpenAIRealtimeProtocols(headers),
2685
- { headers }
2686
- );
2681
+ const realtimeConnection = getOpenAIRealtimeConnection(headers);
2687
2682
  let audioReader;
2683
+ let connection;
2688
2684
  cleanup = (closeCode) => {
2689
- abortSignal == null ? void 0 : abortSignal.removeEventListener("abort", abort);
2690
- void (audioReader == null ? void 0 : audioReader.cancel().catch(() => {
2691
- }));
2692
- try {
2693
- ws.close(closeCode);
2694
- } catch (e) {
2685
+ if (audioReader != null) {
2686
+ void audioReader.cancel().catch(() => {
2687
+ });
2688
+ } else {
2689
+ void audio.cancel().catch(() => {
2690
+ });
2695
2691
  }
2692
+ connection == null ? void 0 : connection.close(closeCode);
2696
2693
  };
2697
2694
  const finishWithError = (error) => {
2698
2695
  if (finished) return;
@@ -2715,42 +2712,42 @@ function createOpenAIRealtimeTranscriptionStream({
2715
2712
  controller.close();
2716
2713
  cleanup(1e3);
2717
2714
  };
2718
- const abort = () => {
2719
- var _a;
2720
- finishWithError((_a = abortSignal == null ? void 0 : abortSignal.reason) != null ? _a : new Error("Aborted"));
2721
- };
2722
- if (abortSignal == null ? void 0 : abortSignal.aborted) {
2723
- abort();
2724
- return;
2725
- }
2726
- abortSignal == null ? void 0 : abortSignal.addEventListener("abort", abort, { once: true });
2727
- const sendAudio = async () => {
2715
+ const sendAudio = async (socket) => {
2728
2716
  audioReader = audio.getReader();
2729
2717
  try {
2730
2718
  while (true) {
2731
2719
  const { done, value } = await audioReader.read();
2732
2720
  if (done || finished) break;
2733
- ws.send(
2721
+ socket.send(
2734
2722
  JSON.stringify({
2735
2723
  type: "input_audio_buffer.append",
2736
2724
  audio: convertToBase642(value)
2737
2725
  })
2738
2726
  );
2727
+ await waitForWebSocketBufferDrain(socket);
2739
2728
  }
2740
2729
  } finally {
2741
2730
  audioReader.releaseLock();
2731
+ audioReader = void 0;
2742
2732
  }
2743
2733
  if (!finished) {
2744
- ws.send(JSON.stringify({ type: "input_audio_buffer.commit" }));
2734
+ socket.send(JSON.stringify({ type: "input_audio_buffer.commit" }));
2745
2735
  }
2746
2736
  };
2747
- ws.onopen = () => {
2748
- controller.enqueue({ type: "stream-start", warnings });
2749
- ws.send(JSON.stringify(sessionUpdate));
2750
- void sendAudio().catch(finishWithError);
2751
- };
2752
- ws.onmessage = (event) => {
2753
- void readWebSocketMessageText(event.data).then(async (text) => {
2737
+ connection = connectToWebSocket({
2738
+ url,
2739
+ protocols: realtimeConnection.protocols,
2740
+ headers: realtimeConnection.headers,
2741
+ webSocket,
2742
+ abortSignal,
2743
+ onAbort: finishWithError,
2744
+ onProcessingError: finishWithError,
2745
+ onOpen: (socket) => {
2746
+ controller.enqueue({ type: "stream-start", warnings });
2747
+ socket.send(JSON.stringify(sessionUpdate));
2748
+ void sendAudio(socket).catch(finishWithError);
2749
+ },
2750
+ onMessageText: async (text) => {
2754
2751
  var _a, _b, _c, _d;
2755
2752
  const parsed = await safeParseJSON({ text });
2756
2753
  if (!parsed.success) return;
@@ -2778,17 +2775,17 @@ function createOpenAIRealtimeTranscriptionStream({
2778
2775
  break;
2779
2776
  }
2780
2777
  }
2781
- }).catch(finishWithError);
2782
- };
2783
- ws.onerror = () => {
2784
- finishWithError(new Error("OpenAI realtime transcription error"));
2785
- };
2786
- ws.onclose = () => {
2787
- if (finished) return;
2788
- finished = true;
2789
- cleanup();
2790
- controller.close();
2791
- };
2778
+ },
2779
+ onSocketError: () => {
2780
+ finishWithError(new Error("OpenAI realtime transcription error"));
2781
+ },
2782
+ onClose: () => {
2783
+ if (finished) return;
2784
+ finished = true;
2785
+ cleanup();
2786
+ controller.close();
2787
+ }
2788
+ });
2792
2789
  },
2793
2790
  cancel: () => {
2794
2791
  if (finished) return;
@@ -2825,11 +2822,26 @@ function buildOpenAIRealtimeTranscriptionSession({
2825
2822
  }
2826
2823
  };
2827
2824
  }
2828
- function getOpenAIRealtimeProtocols(headers) {
2825
+ function getOpenAIRealtimeConnection(headers) {
2829
2826
  var _a;
2830
- const authorization = (_a = headers.Authorization) != null ? _a : headers.authorization;
2831
- const token = (authorization == null ? void 0 : authorization.startsWith("Bearer ")) ? authorization.slice("Bearer ".length) : void 0;
2832
- return token == null ? ["realtime"] : ["realtime", `openai-insecure-api-key.${token}`];
2827
+ let authorization;
2828
+ for (const [key, value] of Object.entries(headers)) {
2829
+ if (key.toLowerCase() === "authorization" && value != null) {
2830
+ authorization = value;
2831
+ }
2832
+ }
2833
+ const token = (_a = authorization == null ? void 0 : authorization.match(/^bearer\s+(.+)$/i)) == null ? void 0 : _a[1];
2834
+ if (token == null) {
2835
+ return { protocols: ["realtime"], headers };
2836
+ }
2837
+ return {
2838
+ protocols: ["realtime", `openai-insecure-api-key.${token}`],
2839
+ headers: Object.fromEntries(
2840
+ Object.entries(headers).filter(
2841
+ ([key]) => key.toLowerCase() !== "authorization"
2842
+ )
2843
+ )
2844
+ };
2833
2845
  }
2834
2846
 
2835
2847
  // src/speech/openai-speech-model.ts