"use strict";
var import_vitest = require("vitest");
var import_language = require("../language.cjs");
var import_log = require("../log.cjs");
var import_types = require("../types.cjs");
var import_vad = require("../vad.cjs");
var import_stt = require("./stt.cjs");
var import_vad2 = require("./vad.cjs");
(0, import_vitest.beforeAll)(() => {
  (0, import_log.initializeLogger)({ level: "silent", pretty: false });
});
function makeStt(overrides = {}) {
  const defaults = {
    model: "deepgram",
    apiKey: "test-key",
    apiSecret: "test-secret",
    baseURL: "https://example.livekit.cloud"
  };
  return new import_stt.STT({ ...defaults, ...overrides });
}
(0, import_vitest.describe)("parseSTTModelString", () => {
  (0, import_vitest.it)("simple model without language", () => {
    const [model, language] = (0, import_stt.parseSTTModelString)("deepgram");
    (0, import_vitest.expect)(model).toBe("deepgram");
    (0, import_vitest.expect)(language).toBeUndefined();
  });
  (0, import_vitest.it)("model with language suffix", () => {
    const [model, language] = (0, import_stt.parseSTTModelString)("deepgram:en");
    (0, import_vitest.expect)(model).toBe("deepgram");
    (0, import_vitest.expect)(language).toBe("en");
  });
  (0, import_vitest.it)("normalizes language suffixes", () => {
    const [model, language] = (0, import_stt.parseSTTModelString)("deepgram:english");
    (0, import_vitest.expect)(model).toBe("deepgram");
    (0, import_vitest.expect)(language).toBe("en");
  });
  (0, import_vitest.it)("provider/model format without language", () => {
    const [model, language] = (0, import_stt.parseSTTModelString)("deepgram/nova-3");
    (0, import_vitest.expect)(model).toBe("deepgram/nova-3");
    (0, import_vitest.expect)(language).toBeUndefined();
  });
  (0, import_vitest.it)("provider/model format with language", () => {
    const [model, language] = (0, import_stt.parseSTTModelString)("deepgram/nova-3:en");
    (0, import_vitest.expect)(model).toBe("deepgram/nova-3");
    (0, import_vitest.expect)(language).toBe("en");
  });
  import_vitest.it.each([
    ["cartesia/ink-whisper:de", "cartesia/ink-whisper", "de"],
    ["assemblyai:es", "assemblyai", "es"],
    ["deepgram/nova-2-medical:ja", "deepgram/nova-2-medical", "ja"],
    ["deepgram/nova-3:multi", "deepgram/nova-3", "multi"],
    ["cartesia:zh", "cartesia", "zh"]
  ])("various providers and languages: %s", (modelStr, expectedModel, expectedLang) => {
    const [model, language] = (0, import_stt.parseSTTModelString)(modelStr);
    (0, import_vitest.expect)(model).toBe(expectedModel);
    (0, import_vitest.expect)(language).toBe(expectedLang);
  });
  (0, import_vitest.it)("auto model without language", () => {
    const [model, language] = (0, import_stt.parseSTTModelString)("auto");
    (0, import_vitest.expect)(model).toBe("auto");
    (0, import_vitest.expect)(language).toBeUndefined();
  });
  (0, import_vitest.it)("auto model with language", () => {
    const [model, language] = (0, import_stt.parseSTTModelString)("auto:pt");
    (0, import_vitest.expect)(model).toBe("auto");
    (0, import_vitest.expect)(language).toBe("pt");
  });
});
(0, import_vitest.describe)("normalizeSTTFallback", () => {
  (0, import_vitest.it)("single string model", () => {
    const result = (0, import_stt.normalizeSTTFallback)("deepgram/nova-3");
    (0, import_vitest.expect)(result).toEqual([{ model: "deepgram/nova-3" }]);
  });
  (0, import_vitest.it)("single FallbackModel dict", () => {
    const fallback = { model: "deepgram/nova-3" };
    const result = (0, import_stt.normalizeSTTFallback)(fallback);
    (0, import_vitest.expect)(result).toEqual([{ model: "deepgram/nova-3" }]);
  });
  (0, import_vitest.it)("list of string models", () => {
    const result = (0, import_stt.normalizeSTTFallback)(["deepgram/nova-3", "cartesia/ink-whisper"]);
    (0, import_vitest.expect)(result).toEqual([{ model: "deepgram/nova-3" }, { model: "cartesia/ink-whisper" }]);
  });
  (0, import_vitest.it)("list of FallbackModel dicts", () => {
    const fallbacks = [{ model: "deepgram/nova-3" }, { model: "assemblyai" }];
    const result = (0, import_stt.normalizeSTTFallback)(fallbacks);
    (0, import_vitest.expect)(result).toEqual([{ model: "deepgram/nova-3" }, { model: "assemblyai" }]);
  });
  (0, import_vitest.it)("mixed list of strings and dicts", () => {
    const result = (0, import_stt.normalizeSTTFallback)([
      "deepgram/nova-3",
      { model: "cartesia/ink-whisper" },
      "assemblyai"
    ]);
    (0, import_vitest.expect)(result).toEqual([
      { model: "deepgram/nova-3" },
      { model: "cartesia/ink-whisper" },
      { model: "assemblyai" }
    ]);
  });
  (0, import_vitest.it)("string with language suffix discards language", () => {
    const result = (0, import_stt.normalizeSTTFallback)("deepgram/nova-3:en");
    (0, import_vitest.expect)(result).toEqual([{ model: "deepgram/nova-3" }]);
  });
  (0, import_vitest.it)("FallbackModel with extraKwargs is preserved", () => {
    const fallback = {
      model: "deepgram/nova-3",
      extraKwargs: { keywords: [["livekit", 1.5]], punctuate: true }
    };
    const result = (0, import_stt.normalizeSTTFallback)(fallback);
    (0, import_vitest.expect)(result).toEqual([
      {
        model: "deepgram/nova-3",
        extraKwargs: { keywords: [["livekit", 1.5]], punctuate: true }
      }
    ]);
  });
  (0, import_vitest.it)("list with extraKwargs preserved", () => {
    const result = (0, import_stt.normalizeSTTFallback)([
      { model: "deepgram/nova-3", extraKwargs: { punctuate: true } },
      "cartesia/ink-whisper",
      { model: "assemblyai", extraKwargs: { format_turns: true } }
    ]);
    (0, import_vitest.expect)(result).toEqual([
      { model: "deepgram/nova-3", extraKwargs: { punctuate: true } },
      { model: "cartesia/ink-whisper" },
      { model: "assemblyai", extraKwargs: { format_turns: true } }
    ]);
  });
  (0, import_vitest.it)("empty list returns empty list", () => {
    const result = (0, import_stt.normalizeSTTFallback)([]);
    (0, import_vitest.expect)(result).toEqual([]);
  });
  (0, import_vitest.it)("multiple colons in model string splits on last", () => {
    const result = (0, import_stt.normalizeSTTFallback)("some:model:part:fr");
    (0, import_vitest.expect)(result).toEqual([{ model: "some:model:part" }]);
  });
});
(0, import_vitest.describe)("STT constructor fallback and connOptions", () => {
  (0, import_vitest.it)("normalizes language in constructor and model string", () => {
    const stt = makeStt({ model: "deepgram/nova-3:english" });
    (0, import_vitest.expect)(stt["opts"].language).toBe("en");
  });
  (0, import_vitest.it)("prefers explicit normalized language over model suffix", () => {
    const stt = makeStt({ model: "deepgram/nova-3:english", language: "en_US" });
    (0, import_vitest.expect)(stt["opts"].language).toBe((0, import_language.normalizeLanguage)("en_US"));
  });
  (0, import_vitest.it)("fallback not given defaults to undefined", () => {
    const stt = makeStt();
    (0, import_vitest.expect)(stt["opts"].fallback).toBeUndefined();
  });
  (0, import_vitest.it)("fallback single string is normalized", () => {
    const stt = makeStt({ fallback: "cartesia/ink-whisper" });
    (0, import_vitest.expect)(stt["opts"].fallback).toEqual([{ model: "cartesia/ink-whisper" }]);
  });
  (0, import_vitest.it)("fallback list of strings is normalized", () => {
    const stt = makeStt({ fallback: ["deepgram/nova-3", "assemblyai"] });
    (0, import_vitest.expect)(stt["opts"].fallback).toEqual([{ model: "deepgram/nova-3" }, { model: "assemblyai" }]);
  });
  (0, import_vitest.it)("fallback single FallbackModel is normalized to list", () => {
    const stt = makeStt({ fallback: { model: "deepgram/nova-3" } });
    (0, import_vitest.expect)(stt["opts"].fallback).toEqual([{ model: "deepgram/nova-3" }]);
  });
  (0, import_vitest.it)("fallback with extraKwargs is preserved", () => {
    const stt = makeStt({
      fallback: {
        model: "deepgram/nova-3",
        extraKwargs: { punctuate: true, keywords: [["livekit", 1.5]] }
      }
    });
    (0, import_vitest.expect)(stt["opts"].fallback).toEqual([
      {
        model: "deepgram/nova-3",
        extraKwargs: { punctuate: true, keywords: [["livekit", 1.5]] }
      }
    ]);
  });
  (0, import_vitest.it)("fallback mixed list is normalized", () => {
    const stt = makeStt({
      fallback: [
        "deepgram/nova-3",
        { model: "cartesia", extraKwargs: { min_volume: 0.5 } },
        "assemblyai"
      ]
    });
    (0, import_vitest.expect)(stt["opts"].fallback).toEqual([
      { model: "deepgram/nova-3" },
      { model: "cartesia", extraKwargs: { min_volume: 0.5 } },
      { model: "assemblyai" }
    ]);
  });
  (0, import_vitest.it)("fallback string with language discards language", () => {
    const stt = makeStt({ fallback: "deepgram/nova-3:en" });
    (0, import_vitest.expect)(stt["opts"].fallback).toEqual([{ model: "deepgram/nova-3" }]);
  });
  (0, import_vitest.it)("connOptions not given uses default", () => {
    const stt = makeStt();
    (0, import_vitest.expect)(stt["opts"].connOptions).toEqual(import_types.DEFAULT_API_CONNECT_OPTIONS);
  });
  (0, import_vitest.it)("connOptions custom timeout", () => {
    const custom = { timeoutMs: 3e4, maxRetry: 3, retryIntervalMs: 2e3 };
    const stt = makeStt({ connOptions: custom });
    (0, import_vitest.expect)(stt["opts"].connOptions).toEqual(custom);
    (0, import_vitest.expect)(stt["opts"].connOptions.timeoutMs).toBe(3e4);
  });
  (0, import_vitest.it)("connOptions custom maxRetry", () => {
    const custom = { timeoutMs: 1e4, maxRetry: 5, retryIntervalMs: 2e3 };
    const stt = makeStt({ connOptions: custom });
    (0, import_vitest.expect)(stt["opts"].connOptions).toEqual(custom);
    (0, import_vitest.expect)(stt["opts"].connOptions.maxRetry).toBe(5);
  });
  (0, import_vitest.it)("connOptions full custom", () => {
    const custom = { timeoutMs: 6e4, maxRetry: 10, retryIntervalMs: 2e3 };
    const stt = makeStt({ connOptions: custom });
    (0, import_vitest.expect)(stt["opts"].connOptions).toEqual(custom);
    (0, import_vitest.expect)(stt["opts"].connOptions.timeoutMs).toBe(6e4);
    (0, import_vitest.expect)(stt["opts"].connOptions.maxRetry).toBe(10);
    (0, import_vitest.expect)(stt["opts"].connOptions.retryIntervalMs).toBe(2e3);
  });
});
(0, import_vitest.describe)("STT diarization capabilities", () => {
  (0, import_vitest.it)("no diarization by default", () => {
    const stt = makeStt();
    (0, import_vitest.expect)(stt.capabilities.diarization).toBe(false);
  });
  (0, import_vitest.it)("diarization enabled with deepgram diarize option", () => {
    const stt = makeStt({ modelOptions: { diarize: true } });
    (0, import_vitest.expect)(stt.capabilities.diarization).toBe(true);
  });
  (0, import_vitest.it)("diarization disabled with diarize false", () => {
    const stt = makeStt({ modelOptions: { diarize: false } });
    (0, import_vitest.expect)(stt.capabilities.diarization).toBe(false);
  });
  (0, import_vitest.it)("diarization enabled with assemblyai speaker_labels", () => {
    const stt = makeStt({
      model: "assemblyai/universal-streaming",
      modelOptions: { speaker_labels: true }
    });
    (0, import_vitest.expect)(stt.capabilities.diarization).toBe(true);
  });
  (0, import_vitest.it)("updateOptions toggles diarization capability", () => {
    const stt = makeStt();
    (0, import_vitest.expect)(stt.capabilities.diarization).toBe(false);
    stt.updateOptions({ modelOptions: { diarize: true } });
    (0, import_vitest.expect)(stt.capabilities.diarization).toBe(true);
    stt.updateOptions({ modelOptions: { diarize: false } });
    (0, import_vitest.expect)(stt.capabilities.diarization).toBe(false);
  });
  (0, import_vitest.it)("diarization enabled with xai diarize option", () => {
    const stt = makeStt({
      model: "xai/stt-1",
      modelOptions: { diarize: true }
    });
    (0, import_vitest.expect)(stt.capabilities.diarization).toBe(true);
  });
  (0, import_vitest.it)("updateOptions preserves unrelated flags when merging", () => {
    const stt = makeStt({ modelOptions: { diarize: true } });
    (0, import_vitest.expect)(stt.capabilities.diarization).toBe(true);
    stt.updateOptions({ modelOptions: { endpointing: 500 } });
    (0, import_vitest.expect)(stt["opts"].modelOptions).toHaveProperty("diarize", true);
    (0, import_vitest.expect)(stt["opts"].modelOptions).toHaveProperty("endpointing", 500);
    (0, import_vitest.expect)(stt.capabilities.diarization).toBe(true);
  });
  (0, import_vitest.it)("updateOptions merges modelOptions on associated streams", () => {
    const stt = makeStt({ modelOptions: { diarize: true } });
    const stream = stt.stream();
    stt.updateOptions({ modelOptions: { endpointing: 500 } });
    (0, import_vitest.expect)(stream["opts"].modelOptions).toHaveProperty("diarize", true);
    (0, import_vitest.expect)(stream["opts"].modelOptions).toHaveProperty("endpointing", 500);
    stream.close();
  });
});
(0, import_vitest.describe)("STT VAD handling for Speechmatics models", () => {
  class MockVAD extends import_vad.VAD {
    label = "mock";
    constructor() {
      super({ updateInterval: 0 });
    }
    stream() {
      throw new Error("not implemented");
    }
  }
  (0, import_vitest.it)("non-speechmatics model has no VAD", async () => {
    const stt = makeStt({ model: "deepgram/nova-3" });
    (0, import_vitest.expect)(stt["vad"]).toBeUndefined();
    await (0, import_vitest.expect)(stt.vadPromise).resolves.toBeUndefined();
  });
  (0, import_vitest.it)("speechmatics model with no user vad falls back to the inference VAD", async () => {
    const stt = makeStt({ model: "speechmatics/enhanced" });
    (0, import_vitest.expect)(stt["vad"]).toBeInstanceOf(import_vad2.VAD);
    await (0, import_vitest.expect)(stt.vadPromise).resolves.toBe(stt["vad"]);
  });
  (0, import_vitest.it)("speechmatics model with user vad uses that vad", async () => {
    const vad = new MockVAD();
    const stt = makeStt({ model: "speechmatics/enhanced", vad });
    (0, import_vitest.expect)(stt["vad"]).toBe(vad);
    await (0, import_vitest.expect)(stt.vadPromise).resolves.toBe(vad);
  });
  (0, import_vitest.it)("user vad with non-speechmatics model is ignored", async () => {
    const vad = new MockVAD();
    const stt = makeStt({ model: "deepgram/nova-3", vad });
    (0, import_vitest.expect)(stt["vad"]).toBeUndefined();
    await (0, import_vitest.expect)(stt.vadPromise).resolves.toBeUndefined();
  });
  (0, import_vitest.it)("updateOptions speechmatics \u2192 non-speechmatics clears VAD", async () => {
    const vad = new MockVAD();
    const stt = makeStt({ model: "speechmatics/enhanced", vad });
    await (0, import_vitest.expect)(stt.vadPromise).resolves.toBe(vad);
    stt.updateOptions({ model: "deepgram/nova-3" });
    (0, import_vitest.expect)(stt["vad"]).toBeUndefined();
    await (0, import_vitest.expect)(stt.vadPromise).resolves.toBeUndefined();
  });
  (0, import_vitest.it)("updateOptions non-speechmatics \u2192 speechmatics falls back to the inference VAD", () => {
    const stt = makeStt({ model: "deepgram/nova-3" });
    (0, import_vitest.expect)(stt["vad"]).toBeUndefined();
    stt.updateOptions({ model: "speechmatics/enhanced" });
    (0, import_vitest.expect)(stt["vad"]).toBeInstanceOf(import_vad2.VAD);
  });
});
//# sourceMappingURL=stt.test.cjs.map