Merge pull request #3195 from ivaaan/add-hume-header

Add tracking headers to Hume service
This commit is contained in:
Mark Backman
2025-12-05 14:50:18 -05:00
committed by GitHub
2 changed files with 39 additions and 6 deletions

View File

@@ -0,0 +1,3 @@
- Added tracking headers (`X-Hume-Client-Name` and `X-Hume-Client-Version`) to all requests made by `HumeTTSService` to the Hume API for better usage tracking and analytics.
- Added `stop()` and `cancel()` cleanup methods to `HumeTTSService` to properly close the HTTP client and prevent resource leaks.

View File

@@ -8,10 +8,14 @@ import base64
import os import os
from typing import Any, AsyncGenerator, Optional from typing import Any, AsyncGenerator, Optional
import httpx
from loguru import logger from loguru import logger
from pydantic import BaseModel from pydantic import BaseModel
from pipecat import __version__
from pipecat.frames.frames import ( from pipecat.frames.frames import (
CancelFrame,
EndFrame,
ErrorFrame, ErrorFrame,
Frame, Frame,
InterruptionFrame, InterruptionFrame,
@@ -26,11 +30,7 @@ from pipecat.utils.tracing.service_decorators import traced_tts
try: try:
from hume import AsyncHumeClient from hume import AsyncHumeClient
from hume.tts import ( from hume.tts import FormatPcm, PostedUtterance, PostedUtteranceVoiceWithId
FormatPcm,
PostedUtterance,
PostedUtteranceVoiceWithId,
)
from hume.tts.types import TimestampMessage from hume.tts.types import TimestampMessage
except ModuleNotFoundError as e: # pragma: no cover - import-time guidance except ModuleNotFoundError as e: # pragma: no cover - import-time guidance
logger.error(f"Exception: {e}") logger.error(f"Exception: {e}")
@@ -40,6 +40,12 @@ except ModuleNotFoundError as e: # pragma: no cover - import-time guidance
HUME_SAMPLE_RATE = 48_000 # Hume TTS streams at 48 kHz HUME_SAMPLE_RATE = 48_000 # Hume TTS streams at 48 kHz
# Tracking headers for Hume API requests
DEFAULT_HEADERS = {
"X-Hume-Client-Name": "pipecat",
"X-Hume-Client-Version": __version__,
}
class HumeTTSService(WordTTSService): class HumeTTSService(WordTTSService):
"""Hume Octave Text-to-Speech service. """Hume Octave Text-to-Speech service.
@@ -104,7 +110,11 @@ class HumeTTSService(WordTTSService):
**kwargs, **kwargs,
) )
self._client = AsyncHumeClient(api_key=api_key) # Create a custom httpx.AsyncClient with tracking headers
# Headers are included in all requests made by the Hume SDK
self._http_client = httpx.AsyncClient(headers=DEFAULT_HEADERS)
self._client = AsyncHumeClient(api_key=api_key, httpx_client=self._http_client)
self._params = params or HumeTTSService.InputParams() self._params = params or HumeTTSService.InputParams()
# Store voice in the base class (mirrors other services) # Store voice in the base class (mirrors other services)
@@ -138,6 +148,26 @@ class HumeTTSService(WordTTSService):
self._cumulative_time = 0.0 self._cumulative_time = 0.0
self._started = False self._started = False
async def stop(self, frame: EndFrame) -> None:
"""Stop the service and cleanup resources.
Args:
frame: The end frame.
"""
await super().stop(frame)
if hasattr(self, "_http_client") and self._http_client:
await self._http_client.aclose()
async def cancel(self, frame: CancelFrame) -> None:
"""Cancel the service and cleanup resources.
Args:
frame: The cancel frame.
"""
await super().cancel(frame)
if hasattr(self, "_http_client") and self._http_client:
await self._http_client.aclose()
async def push_frame(self, frame: Frame, direction: FrameDirection = FrameDirection.DOWNSTREAM): async def push_frame(self, frame: Frame, direction: FrameDirection = FrameDirection.DOWNSTREAM):
"""Push a frame and handle state changes. """Push a frame and handle state changes.