From f08d281641e21eced9cf146d7f524093c5c2e567 Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Mon, 30 Mar 2026 10:56:54 -0700 Subject: [PATCH 1/3] [Fix] Resolve mypy type errors across 3 files Add missing `user_api_key_project_alias` key to SpendLogsMetadata and PagerDutyInternalEvent constructors, and cast `reasoning_items` to list for safe iteration in responses transformation. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../enterprise_callbacks/pagerduty/pagerduty.py | 1 + .../litellm_responses_transformation/transformation.py | 4 ++-- litellm/proxy/spend_tracking/spend_tracking_utils.py | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/enterprise/litellm_enterprise/enterprise_callbacks/pagerduty/pagerduty.py b/enterprise/litellm_enterprise/enterprise_callbacks/pagerduty/pagerduty.py index b6c9104b232..3369db8d3c7 100644 --- a/enterprise/litellm_enterprise/enterprise_callbacks/pagerduty/pagerduty.py +++ b/enterprise/litellm_enterprise/enterprise_callbacks/pagerduty/pagerduty.py @@ -197,6 +197,7 @@ class PagerDutyAlerting(SlackAlerting): user_api_key_org_id=user_api_key_dict.org_id, user_api_key_team_id=user_api_key_dict.team_id, user_api_key_project_id=user_api_key_dict.project_id, + user_api_key_project_alias=user_api_key_dict.project_alias, user_api_key_user_id=user_api_key_dict.user_id, user_api_key_team_alias=user_api_key_dict.team_alias, user_api_key_end_user_id=user_api_key_dict.end_user_id, diff --git a/litellm/completion_extras/litellm_responses_transformation/transformation.py b/litellm/completion_extras/litellm_responses_transformation/transformation.py index 6e6070f7f2c..fded88c3ec5 100644 --- a/litellm/completion_extras/litellm_responses_transformation/transformation.py +++ b/litellm/completion_extras/litellm_responses_transformation/transformation.py @@ -246,7 +246,7 @@ class LiteLLMResponsesTransformationHandler(CompletionTransformationBridge): } ) elif role == "assistant" and tool_calls and isinstance(tool_calls, list): - for r_item in msg.get("reasoning_items") or []: + for r_item in cast(list, msg.get("reasoning_items") or []): input_items.append(_reasoning_item_to_response_input(r_item)) for tool_call in tool_calls: function = tool_call.get("function") @@ -264,7 +264,7 @@ class LiteLLMResponsesTransformationHandler(CompletionTransformationBridge): raise ValueError(f"tool call not supported: {tool_call}") elif content is not None: if role == "assistant": - for r_item in msg.get("reasoning_items") or []: + for r_item in cast(list, msg.get("reasoning_items") or []): input_items.append(_reasoning_item_to_response_input(r_item)) input_items.append( { diff --git a/litellm/proxy/spend_tracking/spend_tracking_utils.py b/litellm/proxy/spend_tracking/spend_tracking_utils.py index 3eacc19a6df..8ea93453ed3 100644 --- a/litellm/proxy/spend_tracking/spend_tracking_utils.py +++ b/litellm/proxy/spend_tracking/spend_tracking_utils.py @@ -90,6 +90,7 @@ def _get_spend_logs_metadata( user_api_key_alias=None, user_api_key_team_id=None, user_api_key_project_id=None, + user_api_key_project_alias=None, user_api_key_org_id=None, user_api_key_user_id=None, user_api_key_team_alias=None, From 0f785f988b752afe5044718b8817835a310b8b69 Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Mon, 30 Mar 2026 11:07:04 -0700 Subject: [PATCH 2/3] [Fix] Add missing user_api_key_project_alias to failed-response PagerDuty event The hanging-response constructor was fixed but the sibling failed-response constructor at line 104 was still missing this field. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../enterprise_callbacks/pagerduty/pagerduty.py | 1 + 1 file changed, 1 insertion(+) diff --git a/enterprise/litellm_enterprise/enterprise_callbacks/pagerduty/pagerduty.py b/enterprise/litellm_enterprise/enterprise_callbacks/pagerduty/pagerduty.py index 3369db8d3c7..de02a0c4dab 100644 --- a/enterprise/litellm_enterprise/enterprise_callbacks/pagerduty/pagerduty.py +++ b/enterprise/litellm_enterprise/enterprise_callbacks/pagerduty/pagerduty.py @@ -116,6 +116,7 @@ class PagerDutyAlerting(SlackAlerting): user_api_key_org_id=_meta.get("user_api_key_org_id"), user_api_key_team_id=_meta.get("user_api_key_team_id"), user_api_key_project_id=_meta.get("user_api_key_project_id"), + user_api_key_project_alias=_meta.get("user_api_key_project_alias"), user_api_key_user_id=_meta.get("user_api_key_user_id"), user_api_key_team_alias=_meta.get("user_api_key_team_alias"), user_api_key_end_user_id=_meta.get("user_api_key_end_user_id"), From 310d61ba70a7310b24064c19da0852519ac4bee4 Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Mon, 30 Mar 2026 11:33:26 -0700 Subject: [PATCH 3/3] [Fix] Replace cast with proper typing for reasoning_items Add reasoning_items field to ChatCompletionAssistantMessage TypedDict and extract a typed _get_reasoning_items helper instead of using cast. Also widen _reasoning_item_to_response_input to accept ChatCompletionReasoningItem. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../transformation.py | 16 +++++++++++++--- litellm/types/llms/openai.py | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/litellm/completion_extras/litellm_responses_transformation/transformation.py b/litellm/completion_extras/litellm_responses_transformation/transformation.py index fded88c3ec5..a387418ef55 100644 --- a/litellm/completion_extras/litellm_responses_transformation/transformation.py +++ b/litellm/completion_extras/litellm_responses_transformation/transformation.py @@ -56,6 +56,16 @@ if TYPE_CHECKING: ) +def _get_reasoning_items( + msg: "AllMessageValues", +) -> List[ChatCompletionReasoningItem]: + """Extract reasoning_items from a message dict with proper typing.""" + items = msg.get("reasoning_items") # type: ignore[union-attr] + if items: + return items # type: ignore[return-value] + return [] + + def _build_reasoning_item( item_id: str, encrypted_content: Optional[str], @@ -86,7 +96,7 @@ def _build_reasoning_item( } -def _reasoning_item_to_response_input(r_item: Dict[str, Any]) -> Dict[str, Any]: +def _reasoning_item_to_response_input(r_item: Union[ChatCompletionReasoningItem, Dict[str, Any]]) -> Dict[str, Any]: """Convert a stored ChatCompletionReasoningItem back to a Responses API input item.""" r_input: Dict[str, Any] = { "type": "reasoning", @@ -246,7 +256,7 @@ class LiteLLMResponsesTransformationHandler(CompletionTransformationBridge): } ) elif role == "assistant" and tool_calls and isinstance(tool_calls, list): - for r_item in cast(list, msg.get("reasoning_items") or []): + for r_item in _get_reasoning_items(msg): input_items.append(_reasoning_item_to_response_input(r_item)) for tool_call in tool_calls: function = tool_call.get("function") @@ -264,7 +274,7 @@ class LiteLLMResponsesTransformationHandler(CompletionTransformationBridge): raise ValueError(f"tool call not supported: {tool_call}") elif content is not None: if role == "assistant": - for r_item in cast(list, msg.get("reasoning_items") or []): + for r_item in _get_reasoning_items(msg): input_items.append(_reasoning_item_to_response_input(r_item)) input_items.append( { diff --git a/litellm/types/llms/openai.py b/litellm/types/llms/openai.py index 9e669655761..80b6190db8f 100644 --- a/litellm/types/llms/openai.py +++ b/litellm/types/llms/openai.py @@ -747,6 +747,7 @@ class ChatCompletionAssistantMessage(OpenAIChatCompletionAssistantMessage, total thinking_blocks: Optional[ List[Union[ChatCompletionThinkingBlock, ChatCompletionRedactedThinkingBlock]] ] + reasoning_items: Optional[List[ChatCompletionReasoningItem]] class ChatCompletionToolMessage(TypedDict):