> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ai-coustics.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from LiveKit's ai-coustics Plugins

> Replace LiveKit-owned ai-coustics plugins with the Python or Node.js plugin maintained by ai-coustics.

This guide migrates a LiveKit agent from LiveKit's `livekit-plugins-ai-coustics` Python package or
`@livekit/plugins-ai-coustics` Node.js package to the corresponding plugin maintained by
ai-coustics.

<Warning>
  The ai-coustics-maintained plugins are replacements for the LiveKit-owned packages.
  Do not install both implementations in the same application.
</Warning>

For a new integration, start with the [LiveKit quickstart](/models/get-started/livekit-quickstart).
For the LiveKit-owned packages, continue to use LiveKit's
[noise and echo cancellation documentation](https://docs.livekit.io/transport/media/noise-cancellation/).

## What changes

| Area                        | LiveKit-owned plugin                                             | ai-coustics-maintained plugin                                                          |
| --------------------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| Python package              | `livekit-plugins-ai-coustics`                                    | `ai-coustics-livekit-plugin`                                                           |
| Node.js package             | `@livekit/plugins-ai-coustics`                                   | `@ai-coustics/livekit-plugin`                                                          |
| Authentication              | LiveKit Cloud by default, or an explicit ai-coustics key         | An ai-coustics SDK key                                                                 |
| Models                      | A fixed set of embedded `EnhancerModel` values                   | Explicitly downloaded or supplied SDK model files                                      |
| Enhancement                 | `audio_enhancement()` / `audioEnhancement()`                     | `Processor`                                                                            |
| Enhancement settings        | `ModelParameters` or `modelParameters`                           | `ProcessorParameter` through the object returned by `get_context()` or `getContext()`  |
| VAD                         | Not standalone; the adapter requires the enhancement integration | A separate `VAD` backed by a dedicated model, with `vad.processor` installed in RoomIO |
| Audio-quality analysis      | Not available                                                    | `Analyzer` with `analyzer.collector` installed in RoomIO                               |
| Frame processor composition | Managed by the package                                           | Explicit `FrameProcessorChain`                                                         |
| Model provisioning          | Handled by the package                                           | Controlled by your application or deployment                                           |

The Python import path remains `livekit.plugins.ai_coustics`, even though the installed
distribution changes. The Node.js import changes to the `@ai-coustics` scope.

In the LiveKit-owned plugin, VAD is part of the enhancement integration and cannot be used on its
own. The ai-coustics-maintained plugin separates the two concerns: `Processor` performs
enhancement with an enhancement model, while `VAD` performs voice activity detection with a
dedicated VAD model. When both are used, `FrameProcessorChain` composes their frame processors.

The repository for the ai-coustics-maintained plugin can be found at [https://github.com/ai-coustics/livekit-plugins](https://github.com/ai-coustics/livekit-plugins),
while the LiveKit-owned plugins are found at [https://github.com/livekit/plugins-ai-coustics-python](https://github.com/livekit/plugins-ai-coustics-python) and [https://github.com/livekit/plugins-ai-coustics-node](https://github.com/livekit/plugins-ai-coustics-node).

## Choose replacement models

The LiveKit-owned plugin exposes model enums or short string names. The ai-coustics-maintained
plugins accept a loaded SDK `Model` instead.

| LiveKit-owned model       | Equivalent model ID    | Latest recommended model ID |
| ------------------------- | ---------------------- | --------------------------- |
| `QUAIL_L` / `quailL`      | `quail-l-16khz`        | `quail-l-16khz`             |
| `QUAIL_VF_L` / `quailVfL` | `quail-vf-2.1-l-16khz` | `quail-vf-2.2-l-16khz`      |
| `QUAIL_VF_S` / `quailVfS` | `quail-vf-2.1-s-16khz` | `quail-vf-2.2-s-16khz`      |

Use the equivalent model ID when you want to minimize behavior changes during migration. Moving
to a newer model version at the same time can change enhancement behavior, so evaluate that as a
separate change. See the [models reference](/reference/sdk/models) for model sizes and properties.

If you use ai-coustics VAD, also provision a dedicated VAD model such as
`vad-2.1-xxs-16khz`. An enhancement model cannot be passed to `VAD`, and a VAD model cannot be
passed to `Processor`.

## Migration steps

<Steps>
  <Step title="Replace the package">
    Remove the LiveKit-owned package before adding the ai-coustics-maintained package:

    <CodeGroup>
      ```sh Python theme={null}
      uv remove livekit-plugins-ai-coustics
      uv add ai-coustics-livekit-plugin
      ```

      ```sh Node.js theme={null}
      pnpm remove @livekit/plugins-ai-coustics
      pnpm add @ai-coustics/livekit-plugin
      ```
    </CodeGroup>

    <Warning>
      The two Python packages both provide `livekit.plugins.ai_coustics`. Installing them together
      can load the wrong implementation or combine incompatible APIs.
    </Warning>
  </Step>

  <Step title="Configure ai-coustics authentication">
    The replacement plugins do not use `Auth.livekit_cloud()` or LiveKit Cloud metering. Add an
    ai-coustics SDK key to your agent's backend environment:

    ```dotenv .env.local theme={null}
    AIC_SDK_LICENSE=your-sdk-key
    ```

    Generate a key on the [ai-coustics developer platform](https://developers.ai-coustics.com/).
    Keep it on the server and out of browser or mobile clients.

    If the old plugin used `AI_COUSTICS_API_KEY`, rename that environment variable to
    `AIC_SDK_LICENSE`. You can alternatively pass `license_key=` in Python or `licenseKey` in
    Node.js when constructing each component.
  </Step>

  <Step title="Provision and load models">
    Download each model during deployment, or let the SDK download it into an application-managed
    directory. Load each model once at module scope so every session in the worker can reuse it:

    <CodeGroup>
      ```python Python theme={null}
      from livekit.plugins import ai_coustics


      # Optional provisioning step:
      # ai_coustics.Model.download("quail-vf-2.1-l-16khz", "./models")
      # ai_coustics.Model.download("vad-2.1-xxs-16khz", "./models")

      enhancement_model = ai_coustics.Model.from_file(
          "/path/to/enhancement-model.aicmodel"
      )
      vad_model = ai_coustics.Model.from_file("/path/to/vad-model.aicmodel")
      ```

      ```ts Node.js theme={null}
      import { Model } from '@ai-coustics/livekit-plugin';

      // Optional provisioning step:
      // Model.download('quail-vf-2.1-l-16khz', './models');
      // Model.download('vad-2.1-xxs-16khz', './models');

      const enhancementModel = Model.fromFile('/path/to/enhancement-model.aicmodel');
      const vadModel = Model.fromFile('/path/to/vad-model.aicmodel');
      ```
    </CodeGroup>

    <Warning>
      Every call to `Model.from_file` or `Model.fromFile` loads another copy of that model into
      memory. Call it once per model file in each worker process. Reuse the returned `Model` to
      construct any number of corresponding `Processor` or `VAD` instances.
    </Warning>

    The custom packages do not participate in LiveKit's `download-files` command. If your
    deployment runs that command for other plugins, keep it, but provision ai-coustics models
    separately.
  </Step>

  <Step title="Replace the enhancement filter">
    Replace the model enum and `audio_enhancement()` or `audioEnhancement()` factory with a
    per-session `Processor`. `get_context()` in Python and `getContext()` in Node.js return a
    small control object for reading and updating that processor's runtime settings.

    <Tabs>
      <Tab title="Python">
        <CodeGroup>
          ```python Before theme={null}
          noise_filter = ai_coustics.audio_enhancement(
              model=ai_coustics.EnhancerModel.QUAIL_VF_L,
              model_parameters=ai_coustics.ModelParameters(
                  enhancement_level=0.8,
              ),
          )

          await session.start(
              # ...
              room_options=room_io.RoomOptions(
                  audio_input=room_io.AudioInputOptions(
                      noise_cancellation=noise_filter,
                  ),
              ),
          )
          ```

          ```python After theme={null}
          processor = ai_coustics.Processor(model=enhancement_model)
          processor_context = processor.get_context()
          processor_context.set_parameter(
              ai_coustics.ProcessorParameter.EnhancementLevel,
              0.8,
          )

          await session.start(
              # ...
              room_options=room_io.RoomOptions(
                  audio_input=room_io.AudioInputOptions(
                      noise_cancellation=processor,
                  ),
              ),
          )
          ```
        </CodeGroup>
      </Tab>

      <Tab title="Node.js">
        <CodeGroup>
          ```ts Before theme={null}
          import * as aiCoustics from '@livekit/plugins-ai-coustics';

          const noiseFilter = aiCoustics.audioEnhancement({
            model: 'quailVfL',
            modelParameters: { enhancementLevel: 0.8 },
          });

          await session.start({
            // ...
            inputOptions: { noiseCancellation: noiseFilter },
          });
          ```

          ```ts After theme={null}
          import {
            Processor,
            ProcessorParameter,
          } from '@ai-coustics/livekit-plugin';

          const processor = new Processor({ model: enhancementModel });
          const processorContext = processor.getContext();
          processorContext.setParameter(ProcessorParameter.EnhancementLevel, 0.8);

          await session.start({
            // ...
            inputOptions: { noiseCancellation: processor },
          });
          ```
        </CodeGroup>
      </Tab>
    </Tabs>

    Construct a separate `Processor` for each concurrent room. The loaded enhancement `Model`
    remains shared.
  </Step>

  <Step title="Migrate VAD">
    Because the LiveKit-owned VAD requires enhancement, migrating it means replacing both parts.
    Create a `Processor` from the enhancement model and a separate `VAD` from the dedicated VAD
    model, then install both in RoomIO's audio path. The examples repeat `Processor` construction
    for clarity; if you completed the previous step, reuse that session's `processor` instead.

    <Tabs>
      <Tab title="Python">
        <CodeGroup>
          ```python Before theme={null}
          session = AgentSession(
              vad=ai_coustics.VAD(),
              # ...
          )
          ```

          ```python After theme={null}
          # Enhancement and VAD use separate models and stateful components.
          processor = ai_coustics.Processor(model=enhancement_model)
          vad = ai_coustics.VAD(
              model=vad_model,
              vad_parameters=ai_coustics.VADParameters(
                  sensitivity=0.5,
                  speech_hold_duration=0.25,
                  minimum_speech_duration=0.05,
              ),
          )

          session = AgentSession(
              vad=vad,
              # ...
          )

          frame_processor = ai_coustics.FrameProcessorChain(vad.processor, processor)

          await session.start(
              # ...
              room_options=room_io.RoomOptions(
                  audio_input=room_io.AudioInputOptions(
                      noise_cancellation=frame_processor,
                  ),
              ),
          )
          ```
        </CodeGroup>
      </Tab>

      <Tab title="Node.js">
        <CodeGroup>
          ```ts Before theme={null}
          import * as aiCoustics from '@livekit/plugins-ai-coustics';

          const session = new voice.AgentSession({
            vad: aiCoustics.vad(),
            // ...
          });
          ```

          ```ts After theme={null}
          import {
            FrameProcessorChain,
            Processor,
            VAD,
          } from '@ai-coustics/livekit-plugin';

          // Enhancement and VAD use separate models and stateful components.
          const processor = new Processor({ model: enhancementModel });
          const vad = new VAD({
            model: vadModel,
            vadParameters: {
              sensitivity: 0.5,
              speechHoldDuration: 0.25,
              minimumSpeechDuration: 0.05,
            },
            // Unlike the vadParameters durations, these options use milliseconds.
            prefixPaddingDuration: 500,
            maxBufferedSpeech: 60_000,
          });

          const session = new voice.AgentSession({
            vad,
            // ...
          });

          const frameProcessor = new FrameProcessorChain(vad.processor, processor);

          await session.start({
            // ...
            inputOptions: { noiseCancellation: frameProcessor },
          });
          ```
        </CodeGroup>
      </Tab>
    </Tabs>

    <Warning>
      Do not copy the old `VadSettings.sensitivity` value. The old integration used an energy
      threshold from `1.0` to `15.0`; the dedicated VAD uses a probability threshold from `0.0`
      to `1.0`, and its direction is different. Start with the model default or `0.5`, then tune
      it against representative production audio. See
      [Migrate to the dedicated VAD](/reference/deprecated/energy-vad-to-dedicated-vad).
    </Warning>

    `FrameProcessorChain` runs its components in order. Keep `vad.processor` before `processor` so
    VAD inference uses the original microphone audio and enhancement runs afterward. VAD streams
    consume the metadata attached to the frame, so the SDK VAD model runs once per audio block.

    Create a separate stateful `VAD` and `Processor` for each agent session. Reuse the loaded
    enhancement and VAD models across sessions.
  </Step>

  <Step title="Test and deploy">
    Test the migration with representative microphone and telephony audio before deploying it to
    all workers. Verify that:

    * The worker can read `AIC_SDK_LICENSE` and access both model files.
    * Model loading happens once per model per worker, rather than once per room.
    * Every concurrent room receives its own `Processor` and `VAD` instances.
    * `vad.processor` appears before `processor` in the RoomIO frame processor chain.
    * Enhancement behavior matches the model and enhancement level you selected.
    * VAD start and end events produce the desired turn-taking behavior.
  </Step>
</Steps>

## API mapping

| LiveKit-owned API                                             | ai-coustics-maintained API                                                                            |
| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `EnhancerModel.QUAIL_*` or a short model string               | `Model.from_file(...)` / `Model.fromFile(...)`                                                        |
| `audio_enhancement(...)` / `audioEnhancement(...)`            | `Processor(...)` / `new Processor(...)`                                                               |
| `ModelParameters(enhancement_level=...)`                      | `processor.get_context().set_parameter(ProcessorParameter.EnhancementLevel, ...)`                     |
| `modelParameters.enhancementLevel`                            | `processor.getContext().setParameter(ProcessorParameter.EnhancementLevel, ...)`                       |
| `update_model_parameters(...)` / `updateModelParameters(...)` | Call the same setter again on the object returned by `get_context()` or `getContext()`                |
| `VAD()` / `vad()`                                             | `VAD(model=vad_model)` / `new VAD({ model: vadModel })`, plus `vad.processor` in RoomIO               |
| `VadSettings`                                                 | `VADParameters` / `vadParameters` on the dedicated VAD component                                      |
| Package-managed enhancement and VAD routing                   | `FrameProcessorChain(vad.processor, processor)` / `new FrameProcessorChain(vad.processor, processor)` |
| `Auth.livekit_cloud()`                                        | Not supported; configure an ai-coustics SDK key                                                       |
| `Auth.ai_coustics_api(...)` / `Auth.aiCousticsApi(...)`       | `AIC_SDK_LICENSE`, `license_key=`, or `licenseKey`                                                    |

## Why the chain order matters

The migrated audio path is:

```text theme={null}
microphone -> vad.processor -> Processor -> AgentSession -> STT
                    |
                    +---- frame metadata ----> VAD stream
```

`vad.processor` is a pass-through frame processor: it runs inference on the original audio and
attaches immutable results to the frame. `Processor` then enhances the audio for STT without
discarding that metadata. Reversing the order makes VAD run on enhanced, delayed audio instead.

## Rollback

To roll back, reverse the package replacement and restore the old factory calls, model enums, and
authentication configuration. Do not leave both packages installed during a staged rollback.
Workers using the LiveKit-owned plugin can continue to use LiveKit Cloud authentication; workers
using the ai-coustics-maintained plugin require `AIC_SDK_LICENSE` and provisioned model files.
