From cdea9c9bf86b6a2de070849ac8045f7e7a09541e Mon Sep 17 00:00:00 2001 From: mateo Date: Sun, 6 Sep 2026 08:05:40 +0000 Subject: [PATCH 1/4] refactor: clear fresh tech debt from the last 24 hours (2026-09-05, 2026-09-06) Drop the TID251 cast import and both cast-ok casts from the refusal message_delta rebuild by narrowing the TypedDict union on its type literal, drop the redundant Mapping cast after the isinstance check in _mapping_field, and type the Lyria predict read-only helpers as Mapping[str, object] instead of a bare dict with mutable-ok. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../adapters/streaming_iterator.py | 30 ++++++++++--------- .../messages/utils.py | 2 +- .../vertex_passthrough_logging_handler.py | 5 ++-- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py b/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py index 9158ff4569f..47974dca20c 100644 --- a/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py +++ b/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py @@ -11,7 +11,6 @@ from typing import ( Final, Literal, Protocol, - cast, # noqa: TID251 # rebuilt message_delta dict spans the ContentBlockDelta/MessageBlockDelta union get_args, ) @@ -25,6 +24,7 @@ from litellm.types.llms.anthropic import ( ContentBlockDelta, ContextManagementResponse, MessageBlockDelta, + MessageDelta, StreamingContentBlockDeltaType, UsageDelta, UsageIteration, @@ -1006,26 +1006,28 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper): self, processed_chunk: ContentBlockDelta | MessageBlockDelta, ) -> ContentBlockDelta | MessageBlockDelta: - if processed_chunk.get("type") != "message_delta" or not self._refusal_text: + if processed_chunk["type"] != "message_delta" or not self._refusal_text: return processed_chunk - delta: Final = cast(Mapping[str, object], processed_chunk["delta"]) # cast-ok: keys checked before use + delta: Final = processed_chunk["delta"] if delta.get("stop_reason") == "max_tokens": return processed_chunk from litellm.llms.anthropic.experimental_pass_through.messages.utils import ( refusal_stop_details, ) - return cast( # cast-ok: rebuilt dict matches the message_delta TypedDict shape for this branch - ContentBlockDelta | MessageBlockDelta, - { # mutable-ok: fresh translation payload; never mutated after construction - **processed_chunk, - "delta": { # mutable-ok: fresh message_delta payload; never mutated after construction - **delta, - "stop_reason": "refusal", - "stop_details": refusal_stop_details(self._refusal_text), - }, - }, - ) + refusal_delta: Final[MessageDelta] = { # mutable-ok: fresh message_delta payload + **delta, + "stop_reason": "refusal", + "stop_details": refusal_stop_details(self._refusal_text), + } + if "context_management" in processed_chunk: + return MessageBlockDelta( + type="message_delta", + delta=refusal_delta, + usage=processed_chunk["usage"], + context_management=processed_chunk["context_management"], + ) + return MessageBlockDelta(type="message_delta", delta=refusal_delta, usage=processed_chunk["usage"]) @staticmethod def _delta_has_content(processed_chunk: Mapping[str, object]) -> bool: diff --git a/litellm/llms/anthropic/experimental_pass_through/messages/utils.py b/litellm/llms/anthropic/experimental_pass_through/messages/utils.py index 7545dff1408..89105c00428 100644 --- a/litellm/llms/anthropic/experimental_pass_through/messages/utils.py +++ b/litellm/llms/anthropic/experimental_pass_through/messages/utils.py @@ -37,7 +37,7 @@ def _mapping_field(container: object, key: str) -> object | None: """One key of a raw provider payload, or None when the payload is not a mapping.""" if not isinstance(container, Mapping): return None - return cast(Mapping[str, object], container).get(key) # cast-ok: raw payload, callers re-check every value + return container.get(key) def _mapping_str_field(container: object, key: str) -> str | None: diff --git a/litellm/proxy/pass_through_endpoints/llm_provider_handlers/vertex_passthrough_logging_handler.py b/litellm/proxy/pass_through_endpoints/llm_provider_handlers/vertex_passthrough_logging_handler.py index 119a53c2411..00db751abe2 100644 --- a/litellm/proxy/pass_through_endpoints/llm_provider_handlers/vertex_passthrough_logging_handler.py +++ b/litellm/proxy/pass_through_endpoints/llm_provider_handlers/vertex_passthrough_logging_handler.py @@ -1,5 +1,6 @@ import asyncio import re +from collections.abc import Mapping from datetime import datetime from typing import TYPE_CHECKING, Any, Final, cast from urllib.parse import urlparse @@ -380,7 +381,7 @@ class VertexPassthroughLoggingHandler: @staticmethod def _is_audio_predict_response( model: str, - json_response: dict, # mutable-ok: predicate inspects the decoded provider response dictionary without mutation + json_response: Mapping[str, object], ) -> bool: return ( VertexPassthroughLoggingHandler._get_audio_prediction_count(json_response=json_response) > 0 @@ -389,7 +390,7 @@ class VertexPassthroughLoggingHandler: @staticmethod def _get_audio_prediction_count( - json_response: dict, # mutable-ok: counter inspects the decoded provider response dictionary without mutation + json_response: Mapping[str, object], ) -> int: predictions: Final = json_response.get("predictions") if not isinstance(predictions, list): From 40e96e3e2c56cf2e4721a491f6548be783d0bcc8 Mon Sep 17 00:00:00 2001 From: mateo Date: Wed, 9 Sep 2026 08:08:44 +0000 Subject: [PATCH 2/4] refactor: clear fresh tech debt from the last 24 hours (2026-09-09) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- litellm/litellm_core_utils/litellm_logging.py | 2 +- litellm/proxy/_experimental/mcp_server/tool_search.py | 5 +++-- litellm/types/llms/bedrock.py | 1 - 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py index b0d6db20b31..70b9f8ec72c 100644 --- a/litellm/litellm_core_utils/litellm_logging.py +++ b/litellm/litellm_core_utils/litellm_logging.py @@ -4877,7 +4877,7 @@ def _maybe_construct_otel_v2(callback_name: str, _in_memory_loggers: list[Custom for callback in _in_memory_loggers: if ( isinstance(callback, OpenTelemetryV2) - and getattr(callback, "callback_name", None) == callback_name + and callback.callback_name == callback_name and (serves_a_destination or not _exports_nowhere(callback.config)) ): return callback diff --git a/litellm/proxy/_experimental/mcp_server/tool_search.py b/litellm/proxy/_experimental/mcp_server/tool_search.py index 2c73f9b863b..cedbccfb70f 100644 --- a/litellm/proxy/_experimental/mcp_server/tool_search.py +++ b/litellm/proxy/_experimental/mcp_server/tool_search.py @@ -119,14 +119,15 @@ def with_mcp_proxy_identity(tool: Tool, server_id: str) -> Tool: def _mcp_proxy_identity(tool: Tool) -> MCPProxyToolIdentity: - identity: Final = (tool.meta or {}).get(_MCP_PROXY_IDENTITY_META_KEY) # mutable-ok: absent metadata default + identity: Final = None if tool.meta is None else tool.meta.get(_MCP_PROXY_IDENTITY_META_KEY) if not isinstance(identity, Mapping): raise TypeError("MCP proxy tool identity is missing") server_id: Final = identity.get("server_id") tool_name: Final = identity.get("tool_name") if not isinstance(server_id, str) or not isinstance(tool_name, str): raise TypeError("MCP proxy tool identity is invalid") - return {"server_id": server_id, "tool_name": tool_name} # mutable-ok: TypedDict identity payload + resolved: Final[MCPProxyToolIdentity] = {"server_id": server_id, "tool_name": tool_name} + return resolved def mcp_proxy_tool_id(tool: Tool) -> str: diff --git a/litellm/types/llms/bedrock.py b/litellm/types/llms/bedrock.py index 9f93886a9c6..2950ad5f9f5 100644 --- a/litellm/types/llms/bedrock.py +++ b/litellm/types/llms/bedrock.py @@ -557,7 +557,6 @@ class AmazonTitanMultimodalEmbeddingResponse(TypedDict): message: str # Specifies any errors that occur during generation. -# TwelveLabs Marengo Embed types TWELVELABS_EMBEDDING_INPUT_TYPES = Literal["text", "image", "video", "audio"] TWELVELABS_EMBEDDING_OPTIONS = Literal["visual-text", "visual-image", "audio"] From 0a89eefca075be6b4cd1e4715066857ee5ea0c4a Mon Sep 17 00:00:00 2001 From: mateo Date: Thu, 10 Sep 2026 08:16:44 +0000 Subject: [PATCH 3/4] refactor: clear fresh tech debt from the last 24 hours (2026-09-10) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- litellm/litellm_core_utils/prompt_templates/common_utils.py | 4 ++-- litellm/litellm_core_utils/streaming_handler.py | 2 +- .../responses_adapters/transformation.py | 4 ++-- .../proxy/management_endpoints/cost_tracking_settings.py | 1 - litellm/responses/streaming_iterator.py | 2 +- .../pre_call_checks/encrypted_content_affinity_check.py | 6 ++---- 6 files changed, 8 insertions(+), 11 deletions(-) diff --git a/litellm/litellm_core_utils/prompt_templates/common_utils.py b/litellm/litellm_core_utils/prompt_templates/common_utils.py index 2485896184e..0d69a784750 100644 --- a/litellm/litellm_core_utils/prompt_templates/common_utils.py +++ b/litellm/litellm_core_utils/prompt_templates/common_utils.py @@ -2014,11 +2014,11 @@ def strip_encrypted_reasoning_from_messages(messages: object) -> None: """ if not isinstance(messages, list): return - for content in _anthropic_content_lists(cast(list[object], messages)): # cast-ok: untyped client json + for content in anthropic_content_lists(cast(list[object], messages)): # cast-ok: untyped client json _strip_encrypted_reasoning_from_blocks(content) -def _anthropic_content_lists(messages: Sequence[object]) -> Iterator[object]: +def anthropic_content_lists(messages: Sequence[object]) -> Iterator[object]: return ( cast(list[object], content) # cast-ok: narrowed by isinstance for message in messages diff --git a/litellm/litellm_core_utils/streaming_handler.py b/litellm/litellm_core_utils/streaming_handler.py index db23929e0c3..2a03075ce7d 100644 --- a/litellm/litellm_core_utils/streaming_handler.py +++ b/litellm/litellm_core_utils/streaming_handler.py @@ -1480,7 +1480,7 @@ class CustomStreamWrapper: "is_finished": chunk_finish_reason is not None, "finish_reason": chunk_finish_reason, "original_chunk": cached_chunk, - "tool_calls": (getattr(cached_choice.delta, "tool_calls", None) if cached_choice is not None else None), + "tool_calls": cached_choice.delta.tool_calls if cached_choice is not None else None, } completion_obj["content"] = response_obj["text"] diff --git a/litellm/llms/anthropic/experimental_pass_through/responses_adapters/transformation.py b/litellm/llms/anthropic/experimental_pass_through/responses_adapters/transformation.py index 1fdb0318bab..b5e5c642940 100644 --- a/litellm/llms/anthropic/experimental_pass_through/responses_adapters/transformation.py +++ b/litellm/llms/anthropic/experimental_pass_through/responses_adapters/transformation.py @@ -171,7 +171,7 @@ class LiteLLMAnthropicToResponsesAPIAdapter: cls, summary: Iterable[object], encrypted_content: object, - ) -> dict[str, Any] | None: # mutable-ok: API message payload + ) -> dict[str, object] | None: # mutable-ok: API message payload """The one Anthropic block for a Responses reasoning item. The item's encrypted reasoning rides the block's opaque field (`signature`, or @@ -200,7 +200,7 @@ class LiteLLMAnthropicToResponsesAPIAdapter: @classmethod def _assistant_group_to_input_items( cls, group: tuple[Mapping[str, object], ...] - ) -> tuple[dict[str, Any], ...]: # mutable-ok: API message payload + ) -> tuple[dict[str, object], ...]: # mutable-ok: API message payload first: Final = group[0] btype: Final = first.get("type") if btype in ("thinking", "redacted_thinking"): diff --git a/litellm/proxy/management_endpoints/cost_tracking_settings.py b/litellm/proxy/management_endpoints/cost_tracking_settings.py index dc0da63555f..a679e79f8d4 100644 --- a/litellm/proxy/management_endpoints/cost_tracking_settings.py +++ b/litellm/proxy/management_endpoints/cost_tracking_settings.py @@ -634,7 +634,6 @@ async def estimate_cost( # Pinning one moment keeps an off-peak window that opens mid-quote from pricing the totals on # one side of it and the reported rates on the other. with pinned_billing_time(current_billing_time()): - # Use completion_cost which handles all the logic including margins/discounts try: cost_per_request: Final = completion_cost( completion_response=mock_response, diff --git a/litellm/responses/streaming_iterator.py b/litellm/responses/streaming_iterator.py index 40ff88fc557..a8dd8c2d8cd 100644 --- a/litellm/responses/streaming_iterator.py +++ b/litellm/responses/streaming_iterator.py @@ -1323,7 +1323,7 @@ def _stamp_responses_usage_cost( if usage_obj is None: return response_obj.usage = usage_obj # rebind-ok: the stamped cost has to ride on the response the client receives - if isinstance(getattr(usage_obj, "cost", None), (int, float)): + if isinstance(usage_obj.cost, (int, float)): return try: cost: Final[float | None] = logging_obj._response_cost_calculator(result=response_obj) diff --git a/litellm/router_utils/pre_call_checks/encrypted_content_affinity_check.py b/litellm/router_utils/pre_call_checks/encrypted_content_affinity_check.py index cdd70e6baf2..939a852b34f 100644 --- a/litellm/router_utils/pre_call_checks/encrypted_content_affinity_check.py +++ b/litellm/router_utils/pre_call_checks/encrypted_content_affinity_check.py @@ -49,6 +49,7 @@ from litellm.exceptions import ( ) from litellm.integrations.custom_logger import CustomLogger, Span from litellm.litellm_core_utils.prompt_templates.common_utils import ( + anthropic_content_lists, encrypted_content_of_block, strip_encrypted_reasoning_from_messages, ) @@ -154,10 +155,7 @@ class EncryptedContentAffinityCheck(CustomLogger): return iter(()) return ( cast(Mapping[str, object], block) # cast-ok: narrowed by isinstance - for message in cast(list[object], messages) # cast-ok: narrowed by isinstance - if isinstance(message, Mapping) - for content in (cast(Mapping[str, object], message).get("content"),) # cast-ok: narrowed by isinstance - if isinstance(content, list) + for content in anthropic_content_lists(cast(list[object], messages)) # cast-ok: narrowed by isinstance for block in cast(list[object], content) # cast-ok: narrowed by isinstance if isinstance(block, Mapping) ) From 2d0ee09e58463f61d7957e39b9e5b052c32e6381 Mon Sep 17 00:00:00 2001 From: mateo Date: Thu, 10 Sep 2026 08:23:14 +0000 Subject: [PATCH 4/4] refactor: keep the pre-existing cost-estimate comment and usage cost read out of the cleanup Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- litellm/proxy/management_endpoints/cost_tracking_settings.py | 1 + litellm/responses/streaming_iterator.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/litellm/proxy/management_endpoints/cost_tracking_settings.py b/litellm/proxy/management_endpoints/cost_tracking_settings.py index a679e79f8d4..dc0da63555f 100644 --- a/litellm/proxy/management_endpoints/cost_tracking_settings.py +++ b/litellm/proxy/management_endpoints/cost_tracking_settings.py @@ -634,6 +634,7 @@ async def estimate_cost( # Pinning one moment keeps an off-peak window that opens mid-quote from pricing the totals on # one side of it and the reported rates on the other. with pinned_billing_time(current_billing_time()): + # Use completion_cost which handles all the logic including margins/discounts try: cost_per_request: Final = completion_cost( completion_response=mock_response, diff --git a/litellm/responses/streaming_iterator.py b/litellm/responses/streaming_iterator.py index a8dd8c2d8cd..40ff88fc557 100644 --- a/litellm/responses/streaming_iterator.py +++ b/litellm/responses/streaming_iterator.py @@ -1323,7 +1323,7 @@ def _stamp_responses_usage_cost( if usage_obj is None: return response_obj.usage = usage_obj # rebind-ok: the stamped cost has to ride on the response the client receives - if isinstance(usage_obj.cost, (int, float)): + if isinstance(getattr(usage_obj, "cost", None), (int, float)): return try: cost: Final[float | None] = logging_obj._response_cost_calculator(result=response_obj)