Merge pull request #1689 from pipecat-ai/mb/handle-http-smart-turn-errors
Handle case where Fal Smart Turn returns a 500 error
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -60,9 +60,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
- Function calls with parameters `(function_name, tool_call_id, args, llm,
|
- Function calls with parameters
|
||||||
context, result_callback)` are deprectated, use a single `FunctionCallParams`
|
`(function_name, tool_call_id, args, llm, context, result_callback)` are
|
||||||
parameter instead.
|
deprectated, use a single `FunctionCallParams` parameter instead.
|
||||||
|
|
||||||
- `TransportParams.camera_*` parameters are now deprecated, use
|
- `TransportParams.camera_*` parameters are now deprecated, use
|
||||||
`TransportParams.video_*` instead.
|
`TransportParams.video_*` instead.
|
||||||
@@ -75,6 +75,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed an issue with HTTP Smart Turn handling, where the service returns a 500
|
||||||
|
error. Previously, this would cause an unhandled exception. Now, a 500 error
|
||||||
|
is treated as an incomplete response.
|
||||||
|
|
||||||
- Fixed a TTS services issue that could cause assistant output not to be
|
- Fixed a TTS services issue that could cause assistant output not to be
|
||||||
aggregated to the context when also using `TTSSpeakFrame`s.
|
aggregated to the context when also using `TTSSpeakFrame`s.
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class HttpSmartTurnAnalyzer(BaseSmartTurn):
|
|||||||
async def _send_raw_request(self, data_bytes: bytes) -> Dict[str, Any]:
|
async def _send_raw_request(self, data_bytes: bytes) -> Dict[str, Any]:
|
||||||
headers = {"Content-Type": "application/octet-stream"}
|
headers = {"Content-Type": "application/octet-stream"}
|
||||||
headers.update(self._headers)
|
headers.update(self._headers)
|
||||||
logger.trace(f"Sending {len(data_bytes)} bytes as raw body to {self._url}...")
|
|
||||||
try:
|
try:
|
||||||
timeout = aiohttp.ClientTimeout(total=self._params.stop_secs)
|
timeout = aiohttp.ClientTimeout(total=self._params.stop_secs)
|
||||||
|
|
||||||
@@ -50,23 +50,30 @@ class HttpSmartTurnAnalyzer(BaseSmartTurn):
|
|||||||
logger.trace("\n--- Response ---")
|
logger.trace("\n--- Response ---")
|
||||||
logger.trace(f"Status Code: {response.status}")
|
logger.trace(f"Status Code: {response.status}")
|
||||||
|
|
||||||
if response.status == 200:
|
# Check if successful
|
||||||
try:
|
if response.status != 200:
|
||||||
json_data = await response.json()
|
|
||||||
logger.trace("Response JSON:")
|
|
||||||
logger.trace(json_data)
|
|
||||||
return json_data
|
|
||||||
except aiohttp.ContentTypeError:
|
|
||||||
# Non-JSON response
|
|
||||||
text = await response.text()
|
|
||||||
logger.trace("Response Content (non-JSON):")
|
|
||||||
logger.trace(text)
|
|
||||||
raise Exception(f"Non-JSON response: {text}")
|
|
||||||
else:
|
|
||||||
error_text = await response.text()
|
error_text = await response.text()
|
||||||
logger.trace("Response Content (Error):")
|
logger.trace("Response Content (Error):")
|
||||||
logger.trace(error_text)
|
logger.trace(error_text)
|
||||||
response.raise_for_status()
|
|
||||||
|
if response.status == 500:
|
||||||
|
logger.warning(f"Smart turn service returned 500 error: {error_text}")
|
||||||
|
raise Exception(f"Server returned HTTP 500: {error_text}")
|
||||||
|
else:
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
# Process successful response
|
||||||
|
try:
|
||||||
|
json_data = await response.json()
|
||||||
|
logger.trace("Response JSON:")
|
||||||
|
logger.trace(json_data)
|
||||||
|
return json_data
|
||||||
|
except aiohttp.ContentTypeError:
|
||||||
|
# Non-JSON response
|
||||||
|
text = await response.text()
|
||||||
|
logger.trace("Response Content (non-JSON):")
|
||||||
|
logger.trace(text)
|
||||||
|
raise Exception(f"Non-JSON response: {text}")
|
||||||
|
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
logger.error(f"Request timed out after {self._params.stop_secs} seconds")
|
logger.error(f"Request timed out after {self._params.stop_secs} seconds")
|
||||||
@@ -76,5 +83,14 @@ class HttpSmartTurnAnalyzer(BaseSmartTurn):
|
|||||||
raise Exception("Failed to send raw request to Daily Smart Turn.")
|
raise Exception("Failed to send raw request to Daily Smart Turn.")
|
||||||
|
|
||||||
async def _predict_endpoint(self, audio_array: np.ndarray) -> Dict[str, Any]:
|
async def _predict_endpoint(self, audio_array: np.ndarray) -> Dict[str, Any]:
|
||||||
serialized_array = self._serialize_array(audio_array)
|
try:
|
||||||
return await self._send_raw_request(serialized_array)
|
serialized_array = self._serialize_array(audio_array)
|
||||||
|
return await self._send_raw_request(serialized_array)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Smart turn prediction failed: {str(e)}")
|
||||||
|
# Return an incomplete prediction when a failure occurs
|
||||||
|
return {
|
||||||
|
"prediction": 0,
|
||||||
|
"probability": 0.0,
|
||||||
|
"metrics": {"inference_time": 0.0, "total_time": 0.0},
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user