diff --git a/litellm/google_genai/adapters/transformation.py b/litellm/google_genai/adapters/transformation.py index b73a1443330..8ea19deef4c 100644 --- a/litellm/google_genai/adapters/transformation.py +++ b/litellm/google_genai/adapters/transformation.py @@ -108,7 +108,6 @@ class GoogleGenAIStreamWrapper(AdapterCompletionStreamWrapper): def __init__(self, completion_stream: object): self.sent_first_chunk = False - # State tracking for accumulating partial tool calls self.accumulated_tool_calls = dict[int, _ToolCallAccumulator]() self._returned_response = False super().__init__(completion_stream) diff --git a/litellm/litellm_core_utils/model_response_utils.py b/litellm/litellm_core_utils/model_response_utils.py index 7bf667164ae..dc4f375daa7 100644 --- a/litellm/litellm_core_utils/model_response_utils.py +++ b/litellm/litellm_core_utils/model_response_utils.py @@ -144,7 +144,6 @@ def _is_choice_non_empty(choice: StreamingChoices) -> bool: # Check model_extra for dynamically added fields on the choice choice_extra_fields: Final[Mapping[str, object]] = choice.model_extra or {} for extra_field_name, extra_field_value in choice_extra_fields.items(): - # Skip certain structural fields that are just default/None placeholders if extra_field_name == "index" and extra_field_value == 0: continue if extra_field_name in {"finish_reason", "logprobs"} and extra_field_value is None: @@ -192,7 +191,6 @@ def _is_delta_non_empty(delta: Delta) -> bool: # Check model_extra for dynamically added fields (this is where Pydantic stores them) delta_extra_fields: Final[Mapping[str, object]] = delta.model_extra or {} for extra_field_value in delta_extra_fields.values(): - # Even structural fields are meaningful if they have actual content if _has_meaningful_content(extra_field_value): return True diff --git a/litellm/llms/oci/chat/cohere.py b/litellm/llms/oci/chat/cohere.py index 384e7ec4cf8..6e9bb83b0a0 100644 --- a/litellm/llms/oci/chat/cohere.py +++ b/litellm/llms/oci/chat/cohere.py @@ -9,7 +9,7 @@ response parsing, and streaming chunk parsing for models served with import datetime import json from collections.abc import Iterable, Mapping, Sequence -from typing import Any, Final +from typing import Final import httpx from pydantic import JsonValue, TypeAdapter, ValidationError @@ -76,7 +76,7 @@ def _content_text(content: str | Iterable[Mapping[str, object]] | None) -> str: return str(content) -def _extract_text_content(content: Any) -> str: +def _extract_text_content(content: str | Iterable[Mapping[str, object]] | None) -> str: """Return the plain-text representation of a message content value.""" return _content_text(content) diff --git a/litellm/llms/runwayml/videos/transformation.py b/litellm/llms/runwayml/videos/transformation.py index c7289eb47f5..c7696a1cb29 100644 --- a/litellm/llms/runwayml/videos/transformation.py +++ b/litellm/llms/runwayml/videos/transformation.py @@ -160,14 +160,12 @@ class RunwayMLVideoConfig(BaseVideoConfig): **self._prompt_image_param(video_create_optional_params), **self._ratio_param(video_create_optional_params), **self._duration_param(video_create_optional_params), - # Pass through other parameters that aren't OpenAI-specific **{key: value for key, value in video_create_optional_params.items() if key not in supported_openai_params}, } @staticmethod def _prompt_image_param(video_create_optional_params: VideoCreateOptionalRequestParams) -> Mapping[str, object]: # Handle input_reference parameter - map to promptImage - # RunwayML supports URLs and data URIs directly if "input_reference" in video_create_optional_params: return {"promptImage": video_create_optional_params["input_reference"]} return {} diff --git a/litellm/llms/vertex_ai/image_edit/vertex_gemini_transformation.py b/litellm/llms/vertex_ai/image_edit/vertex_gemini_transformation.py index 5889a8eba06..725a7f39917 100644 --- a/litellm/llms/vertex_ai/image_edit/vertex_gemini_transformation.py +++ b/litellm/llms/vertex_ai/image_edit/vertex_gemini_transformation.py @@ -182,7 +182,6 @@ class VertexAIGeminiImageEditConfig(BaseImageEditConfig, VertexLLM): else None ) - # Generation config with proper structure for image editing generation_config: Final[dict[str, object]] = { key: value for key, value in (("response_modalities", ["IMAGE"]), ("image_config", image_config)) if value } diff --git a/litellm/llms/vertex_ai/vector_stores/rag_api/transformation.py b/litellm/llms/vertex_ai/vector_stores/rag_api/transformation.py index eedd488ecdb..5c250fc1a7e 100644 --- a/litellm/llms/vertex_ai/vector_stores/rag_api/transformation.py +++ b/litellm/llms/vertex_ai/vector_stores/rag_api/transformation.py @@ -203,7 +203,6 @@ class VertexVectorStoreConfig(BaseVectorStoreConfig, VertexBase): if value is not None } - # Build the request body for Vertex AI RAG API query_body: Final[Mapping[str, object]] = { key: value for key, value in (("text", query), ("rag_retrieval_config", rag_retrieval_config or None)) @@ -294,7 +293,6 @@ class VertexVectorStoreConfig(BaseVectorStoreConfig, VertexBase): # Add metadata if provided metadata: Final = vector_store_create_optional_params.get("metadata") - # Build the request body for Vertex AI RAG Corpus creation request_body: Final[dict[str, object]] = { key: value for key, value in ( diff --git a/litellm/proxy/guardrails/guardrail_hooks/headroom/headroom.py b/litellm/proxy/guardrails/guardrail_hooks/headroom/headroom.py index daa15fb5e5f..d8c8c2f4974 100644 --- a/litellm/proxy/guardrails/guardrail_hooks/headroom/headroom.py +++ b/litellm/proxy/guardrails/guardrail_hooks/headroom/headroom.py @@ -433,7 +433,7 @@ class HeadroomGuardrail(CustomGuardrail): payload["model"] = model try: - raw_response: HttpxResponse = await self.async_handler.post( # pyright: ignore[reportUnknownMemberType] + raw_response: HttpxResponse = await self.async_handler.post( # pyright: ignore[reportUnknownMemberType] # AsyncHTTPHandler.post is untyped url=f"{self.headroom_api_base}/v1/compress", json=payload, headers=self._request_headers(), @@ -570,7 +570,7 @@ class HeadroomGuardrail(CustomGuardrail): params["query"] = query try: - raw_response: HttpxResponse = await self.async_handler.get( # pyright: ignore[reportUnknownMemberType] + raw_response: HttpxResponse = await self.async_handler.get( # pyright: ignore[reportUnknownMemberType] # AsyncHTTPHandler.get is untyped url=f"{self.headroom_api_base}/v1/retrieve/{hash_value}", params=params, headers=self._request_headers(), diff --git a/litellm/proxy/guardrails/guardrail_hooks/repelloai/repelloai.py b/litellm/proxy/guardrails/guardrail_hooks/repelloai/repelloai.py index d842a9b9b6a..8925cc5b3a6 100644 --- a/litellm/proxy/guardrails/guardrail_hooks/repelloai/repelloai.py +++ b/litellm/proxy/guardrails/guardrail_hooks/repelloai/repelloai.py @@ -197,7 +197,7 @@ class RepelloAIGuardrail(CustomGuardrail): repelloai_response: RepelloAIAnalyzeResponse | None = None try: verbose_proxy_logger.debug("RepelloAI Argus request: %s", request) - response: Final[HttpxResponse] = await self.async_handler.post( # pyright: ignore[reportUnknownMemberType] + response: Final[HttpxResponse] = await self.async_handler.post( # pyright: ignore[reportUnknownMemberType] # AsyncHTTPHandler.post is untyped url=endpoint, headers={"X-API-Key": self.repelloai_api_key}, json=request, diff --git a/litellm/proxy/response_polling/background_streaming.py b/litellm/proxy/response_polling/background_streaming.py index f755c6d478b..b03122966c0 100644 --- a/litellm/proxy/response_polling/background_streaming.py +++ b/litellm/proxy/response_polling/background_streaming.py @@ -144,10 +144,8 @@ async def background_streaming_task( # Process streaming response following OpenAI events format # https://platform.openai.com/docs/api-reference/responses-streaming - output_items: Final = dict[str, _OutputItem]() # Track output items by ID - accumulated_text: Final = dict[ - tuple[str, int], str - ]() # Track accumulated text deltas by (item_id, content_index) + output_items: Final = dict[str, _OutputItem]() + accumulated_text: Final = dict[tuple[str, int], str]() # ResponsesAPIResponse fields to extract from response.completed usage_data = None @@ -262,7 +260,6 @@ async def background_streaming_task( if "content" in delta_item: content_list = delta_item["content"] if content_index < len(content_list): - # Update existing content part with accumulated text content_entry = content_list[content_index] if isinstance(content_entry, dict): content_entry["text"] = accumulated_text[key] diff --git a/litellm/rag/ingestion/vertex_ai_ingestion.py b/litellm/rag/ingestion/vertex_ai_ingestion.py index 07f9f346d08..eff8ad1b8cb 100644 --- a/litellm/rag/ingestion/vertex_ai_ingestion.py +++ b/litellm/rag/ingestion/vertex_ai_ingestion.py @@ -186,7 +186,6 @@ class VertexAIRAGIngestion(BaseRAGIngestion, VertexBase): base_url: Final = get_vertex_base_url(self.location) url: Final = f"{base_url}/v1beta1/projects/{self.project_id}/locations/{self.location}/ragCorpora" - # Build request body with camelCase keys (Vertex AI API format) vector_db_config: Final = self.vector_store_config.get("vector_db_config") embedding_model: Final = self.vector_store_config.get("embedding_model") embedding_model_config: Final = ( @@ -447,7 +446,6 @@ class VertexAIRAGIngestion(BaseRAGIngestion, VertexBase): # Add max embedding requests per minute if specified max_embedding_qpm: Final = self.vector_store_config.get("max_embedding_requests_per_min") - # Build request body with camelCase keys (Vertex AI API format) chunking_config: Final = ( {"chunkSize": chunk_size or 1024, "chunkOverlap": chunk_overlap or 200} if chunk_size or chunk_overlap diff --git a/type-discipline-budget.json b/type-discipline-budget.json index ab34775c460..c27844a0004 100644 --- a/type-discipline-budget.json +++ b/type-discipline-budget.json @@ -9,7 +9,7 @@ "limit": 269 }, "LIT004": { - "limit": 43 + "limit": 40 }, "LIT005": { "limit": 0