Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/eva/assistant/pipecat_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,11 +568,25 @@ async def _on_turn_end(_service, transcript: str) -> None:

def _create_transport(self, websocket) -> FastAPIWebsocketTransport:
"""Create the WebSocket transport with Twilio frame serialization."""
audio_in_filter_cfg = self.pipeline_config.audio_in_filter.lower()
if audio_in_filter_cfg == "none":
audio_in_filter = None
elif audio_in_filter_cfg == "krisp_viva":
from pipecat.audio.filters.krisp_viva_filter import KrispVivaFilter

audio_in_filter = KrispVivaFilter(**self.pipeline_config.audio_in_filter_params)
logger.info("Using Krisp VIVA audio-in filter")
else:
raise ValueError(
f"Unsupported audio_in_filter: {audio_in_filter_cfg}. Supported types: 'krisp_viva', 'none'"
)

return FastAPIWebsocketTransport(
websocket=websocket,
params=FastAPIWebsocketParams(
audio_in_enabled=True,
audio_out_enabled=True,
audio_in_filter=audio_in_filter,
add_wav_header=False,
serializer=TwilioFrameSerializer(
self.conversation_id,
Expand Down
7 changes: 6 additions & 1 deletion src/eva/assistant/pipeline/turn_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,13 @@ def create_vad_analyzer(vad_type: str, vad_params: dict[str, Any]) -> VADAnalyze
# Create VADParams, respecting existing defaults if no params specified
params = VADParams(**vad_params) if vad_params else None
return SileroVADAnalyzer(params=params)
elif vad_type_lower == "krisp_viva":
from pipecat.audio.vad.krisp_viva_vad import KrispVivaVadAnalyzer

params = VADParams(**vad_params) if vad_params else None
return KrispVivaVadAnalyzer(params=params)
else:
raise ValueError(f"Unsupported VAD type: {vad_type}. Supported types: 'silero', 'none'")
raise ValueError(f"Unsupported VAD type: {vad_type}. Supported types: 'silero', 'none', 'krisp_viva'")


def create_turn_start_strategy(
Expand Down
15 changes: 14 additions & 1 deletion src/eva/models/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ class ModelConfig(BaseModel):
vad: str = Field(
"silero",
description=(
"VAD analyzer type: 'silero' or 'none'. Defaults to 'silero' (SileroVADAnalyzer). Use 'none' with external turn strategies (e.g. deepgram-flux) to skip local VAD. Set via EVA_MODEL__VAD."
"VAD analyzer type: 'silero', 'krisp_viva' or 'none'. Defaults to 'silero' (SileroVADAnalyzer). Use 'none' with external turn strategies (e.g. deepgram-flux) to skip local VAD. Set via EVA_MODEL__VAD."
),
)
vad_params: dict[str, Any] = Field(
Expand All @@ -198,6 +198,19 @@ class ModelConfig(BaseModel):
),
)

# Transport-level audio input filter
audio_in_filter: str = Field(
"none",
description=(
"Audio input filter applied to the transport: 'krisp_viva' or 'none'. Defaults to "
"'none'. Set via EVA_MODEL__AUDIO_IN_FILTER."
),
)
audio_in_filter_params: dict[str, Any] = Field(
{},
description="Audio input filter parameters (JSON). Set via EVA_MODEL__AUDIO_IN_FILTER_PARAMS.",
)

# CASCADE-only latency controls.
pre_tool_speech: str = Field(
"off",
Expand Down
1 change: 0 additions & 1 deletion tests/unit/assistant/test_pipecat_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ def _make_server(tmp_path: Path):
srv._server_task = None
srv._runner = None
srv._metrics_observer = None
srv._latency_measurements = []
srv.num_seconds = 0
srv.pipeline_config = MagicMock()
srv.conversation_id = "test-conv"
Expand Down
6 changes: 5 additions & 1 deletion vendor/krisp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ Result (wheel version and `.kef` set will vary by download):
vendor/krisp/
├── README.md (tracked)
├── krisp_audio-1.10.0-cp311-cp311-linux_x86_64.whl (git-ignored)
└── krisp-viva-tp-v3.kef (git-ignored)
├── krisp-viva-tp-v3.kef (git-ignored)
├── krisp-viva-vad-v2.kef (git-ignored)
└── krisp-viva-vi-tel-v2.1.kef (git-ignored)
```

> [!WARNING]
Expand All @@ -35,6 +37,8 @@ In the Docker container:
- The `eva` command (which is actually `scripts/docker_eva_wrapper.sh`) installs the `.whl`, if present.
- The `KRISP_VIVA_TURN_MODEL_PATH` env var points at the `.kef` file directly on that mount, e.g. `vendor/krisp/krisp-viva-tp-v3.kef`.
- The `KRISP_VIVA_API_KEY` env var provides the API key.
- If using the Krisp VAD, set `EVA_MODEL__VAD` to `krisp_viva` and point `KRISP_VIVA_VAD_MODEL_PATH` to the `krisp-viva-vad-v2.kef` file
- If using the Krisp audio input filter, set `EVA_MODEL__AUDIO_IN_FILTER` to `krisp_viva` and point `KRISP_VIVA_AUDIO_IN_FILTER_MODEL_PATH` to the `krisp-viva-vi-tel-v2.1.kef` file

## Runtime requirement

Expand Down
Loading