From bc983b09881c00620ee6f68bbf6c400171cb4a2b Mon Sep 17 00:00:00 2001 From: Sameer Kankute Date: Fri, 5 Jun 2026 18:09:08 +0530 Subject: [PATCH] fix: address greptile and veria review feedback - langfuse: guard httpx_client injection behind version check (>= 2.7.3) - soniox: propagate audio_transcription_duration in _hidden_params for spend tracking - soniox: give SONIOX_API_BASE env var priority over caller-supplied api_base - mcp: replace CancelledError catch with asyncio.wait_for + TimeoutError --- .../langfuse/langfuse_prompt_management.py | 5 ++-- .../soniox/audio_transcription/handler.py | 23 ++++++++++++++++--- litellm/llms/soniox/common_utils.py | 4 +++- .../mcp_server/mcp_server_manager.py | 14 +++++------ 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/litellm/integrations/langfuse/langfuse_prompt_management.py b/litellm/integrations/langfuse/langfuse_prompt_management.py index 75e32d4abae..c5041c98baa 100644 --- a/litellm/integrations/langfuse/langfuse_prompt_management.py +++ b/litellm/integrations/langfuse/langfuse_prompt_management.py @@ -104,8 +104,9 @@ def langfuse_client_init( from ...llms.custom_httpx.http_handler import _get_httpx_client - http_client = _get_httpx_client() - parameters["httpx_client"] = http_client.client + if Version(langfuse.version.__version__) >= Version("2.7.3"): + http_client = _get_httpx_client() + parameters["httpx_client"] = http_client.client client = Langfuse(**parameters) diff --git a/litellm/llms/soniox/audio_transcription/handler.py b/litellm/llms/soniox/audio_transcription/handler.py index bbc7ad09196..a4cb03961dd 100644 --- a/litellm/llms/soniox/audio_transcription/handler.py +++ b/litellm/llms/soniox/audio_transcription/handler.py @@ -437,9 +437,17 @@ class SonioxAudioTranscriptionHandler: self._safe_log_post_call(logging_obj, audio_file, api_key, body, payload) - # Carry through hidden_params hints expected by the rest of litellm. + audio_duration_ms = transcription_meta.get("audio_duration_ms") response._hidden_params.update( - {"model": model, "custom_llm_provider": "soniox"} + { + "model": model, + "custom_llm_provider": "soniox", + "audio_transcription_duration": ( + float(audio_duration_ms) / 1000.0 + if audio_duration_ms is not None + else None + ), + } ) return response finally: @@ -665,8 +673,17 @@ class SonioxAudioTranscriptionHandler: self._safe_log_post_call(logging_obj, audio_file, api_key, body, payload) + audio_duration_ms = transcription_meta.get("audio_duration_ms") response._hidden_params.update( - {"model": model, "custom_llm_provider": "soniox"} + { + "model": model, + "custom_llm_provider": "soniox", + "audio_transcription_duration": ( + float(audio_duration_ms) / 1000.0 + if audio_duration_ms is not None + else None + ), + } ) return response finally: diff --git a/litellm/llms/soniox/common_utils.py b/litellm/llms/soniox/common_utils.py index a8424fe277b..de5479e7a63 100644 --- a/litellm/llms/soniox/common_utils.py +++ b/litellm/llms/soniox/common_utils.py @@ -61,7 +61,9 @@ def get_soniox_api_base(api_base: Optional[str] = None) -> str: """Resolve the Soniox API base URL (defaults to public API).""" from litellm.secret_managers.main import get_secret_str - base = api_base or get_secret_str("SONIOX_API_BASE") or SONIOX_API_BASE + # Env var takes precedence over caller-supplied value to prevent + # request-controlled redirection of authenticated requests. + base = get_secret_str("SONIOX_API_BASE") or api_base or SONIOX_API_BASE return base.rstrip("/") diff --git a/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py b/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py index 887fe610403..5fd028b3436 100644 --- a/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py +++ b/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py @@ -3164,19 +3164,19 @@ class MCPServerManager: asyncio.create_task(_call_tool_via_client(client, call_tool_params)) ) + _timeout = ( + mcp_server.timeout if mcp_server.timeout is not None else MCP_CLIENT_TIMEOUT + ) try: - mcp_responses = await asyncio.gather(*tasks) - except asyncio.CancelledError: - timeout = ( - mcp_server.timeout - if mcp_server.timeout is not None - else MCP_CLIENT_TIMEOUT + mcp_responses = await asyncio.wait_for( + asyncio.gather(*tasks), timeout=_timeout ) + except asyncio.TimeoutError: raise HTTPException( status_code=504, detail={ "error": "timeout", - "message": f"MCP tool call timed out after {timeout}s", + "message": f"MCP tool call timed out after {_timeout}s", }, ) except (