"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var interruption_detector_exports = {};
__export(interruption_detector_exports, {
  AdaptiveInterruptionDetector: () => AdaptiveInterruptionDetector
});
module.exports = __toCommonJS(interruption_detector_exports);
var import_throws = require("@livekit/throws-transformer/throws");
var import_events = __toESM(require("events"), 1);
var import_log = require("../../log.cjs");
var import_utils = require("../../utils.cjs");
var import_utils2 = require("../utils.cjs");
var import_defaults = require("./defaults.cjs");
var import_errors = require("./errors.cjs");
var import_interruption_stream = require("./interruption_stream.cjs");
class AdaptiveInterruptionDetector extends import_events.default {
  options;
  _label;
  logger = (0, import_log.log)();
  // Use Set instead of WeakSet to allow iteration for propagating option updates
  streams = /* @__PURE__ */ new Set();
  constructor(options = {}) {
    super();
    const {
      maxAudioDurationInS,
      baseUrl,
      audioPrefixDurationInS,
      threshold,
      detectionIntervalInS,
      inferenceTimeout,
      minInterruptionDurationInS
    } = { ...import_defaults.interruptionOptionDefaults, ...options };
    const { apiKey, apiSecret } = options;
    if (maxAudioDurationInS > 3) {
      throw new RangeError("maxAudioDurationInS must be less than or equal to 3.0 seconds");
    }
    const lkBaseUrl = baseUrl ?? (0, import_utils2.getDefaultInferenceUrl)();
    const lkApiKey = apiKey || process.env.LIVEKIT_INFERENCE_API_KEY || process.env.LIVEKIT_API_KEY || "";
    if (!lkApiKey) {
      throw new TypeError(
        "apiKey is required, either as argument or set LIVEKIT_API_KEY environmental variable"
      );
    }
    const lkApiSecret = apiSecret || process.env.LIVEKIT_INFERENCE_API_SECRET || process.env.LIVEKIT_API_SECRET || "";
    if (!lkApiSecret) {
      throw new TypeError(
        "apiSecret is required, either as argument or set LIVEKIT_API_SECRET environmental variable"
      );
    }
    this.options = {
      sampleRate: import_defaults.SAMPLE_RATE,
      threshold,
      minFrames: Math.ceil(minInterruptionDurationInS * import_defaults.FRAMES_PER_SECOND),
      maxAudioDurationInS,
      audioPrefixDurationInS,
      detectionIntervalInS,
      inferenceTimeout,
      baseUrl: lkBaseUrl,
      apiKey: lkApiKey,
      apiSecret: lkApiSecret,
      minInterruptionDurationInS
    };
    this._label = `${this.constructor.name}`;
    this.logger.debug(
      {
        baseUrl: this.options.baseUrl,
        detectionIntervalInS: this.options.detectionIntervalInS,
        audioPrefixDurationInS: this.options.audioPrefixDurationInS,
        maxAudioDurationInS: this.options.maxAudioDurationInS,
        minFrames: this.options.minFrames,
        threshold: this.options.threshold ?? null,
        inferenceTimeout: this.options.inferenceTimeout
      },
      "=== Adaptive interruption detector initialized"
    );
  }
  /**
   * The model identifier for this detector.
   */
  get model() {
    return "adaptive interruption";
  }
  /**
   * The provider identifier for this detector.
   */
  get provider() {
    return "livekit";
  }
  /**
   * The label for this detector instance.
   */
  get label() {
    return this._label;
  }
  /**
   * The sample rate used for audio processing.
   */
  get sampleRate() {
    return this.options.sampleRate;
  }
  /**
   * Emit an error event from the detector.
   */
  emitError(error) {
    this.emit("error", error);
  }
  /**
   * Creates a new InterruptionStreamBase for internal use.
   * The stream can receive audio frames and sentinels via pushFrame().
   * Use this when you need direct access to the stream for pushing frames.
   */
  createStream() {
    try {
      const streamBase = new import_interruption_stream.InterruptionStreamBase(this, {});
      this.streams.add(streamBase);
      return streamBase;
    } catch (e) {
      const cause = (0, import_utils.asError)(e);
      this.emitError(new import_errors.InterruptionDetectionError(cause.message, Date.now(), this._label, false));
      throw e;
    }
  }
  /**
   * Remove a stream from tracking (called when stream is closed).
   */
  removeStream(stream) {
    this.streams.delete(stream);
  }
  /**
   * Update options for the detector and propagate to all active streams.
   * For WebSocket streams, this triggers a reconnection with new settings.
   */
  async updateOptions(options) {
    if (options.threshold !== void 0) {
      this.options.threshold = options.threshold;
    }
    if (options.minInterruptionDurationInS !== void 0) {
      this.options.minInterruptionDurationInS = options.minInterruptionDurationInS;
      this.options.minFrames = Math.ceil(options.minInterruptionDurationInS * import_defaults.FRAMES_PER_SECOND);
    }
    const updatePromises = [];
    for (const stream of this.streams) {
      updatePromises.push(stream.updateOptions(options));
    }
    await import_throws.ThrowsPromise.all(updatePromises);
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  AdaptiveInterruptionDetector
});
//# sourceMappingURL=interruption_detector.cjs.map