diff --git a/litellm/litellm_core_utils/chat_completion_agentic_loop.py b/litellm/litellm_core_utils/chat_completion_agentic_loop.py index 7abcd172ddc..e9c5dc2fbf8 100644 --- a/litellm/litellm_core_utils/chat_completion_agentic_loop.py +++ b/litellm/litellm_core_utils/chat_completion_agentic_loop.py @@ -4,7 +4,7 @@ import json from collections.abc import Iterable, Mapping from itertools import chain from types import MappingProxyType -from typing import Final +from typing import Final, cast from pydantic import TypeAdapter, ValidationError @@ -85,7 +85,7 @@ def _coerce_int(value: object, default: int) -> int: return int(value) if isinstance(value, (int, str)) else default -def _agentic_loop_settings(kwargs: dict[str, object]) -> tuple[int, int, list[str]]: +def _agentic_loop_settings(kwargs: Mapping[str, object]) -> tuple[int, int, list[str]]: depth: Final = _coerce_int(kwargs.get("_agentic_loop_depth"), 0) configured: Final = validated_max_agentic_loops( kwargs.get("max_agentic_loops"), field="litellm_params.max_agentic_loops" @@ -334,7 +334,10 @@ async def maybe_run_chat_completion_agentic_loop( import litellm callbacks: Final = litellm.callbacks + (getattr(logging_obj, "dynamic_success_callbacks", None) or []) - request_kwargs: Final = with_caller_tool_choice(kwargs, optional_params) + requested_optional_params: Final = cast( # cast-ok: optional_params is a str-keyed dict + "Mapping[str, object]", optional_params + ) + request_kwargs: Final = with_caller_tool_choice(kwargs, requested_optional_params) depth, max_loops, fingerprints = _agentic_loop_settings(request_kwargs) tools: Final = optional_params.get("tools", []) diff --git a/litellm/llms/custom_httpx/llm_http_handler.py b/litellm/llms/custom_httpx/llm_http_handler.py index bd3b1cafd01..1da1d7b03fa 100644 --- a/litellm/llms/custom_httpx/llm_http_handler.py +++ b/litellm/llms/custom_httpx/llm_http_handler.py @@ -5965,8 +5965,6 @@ class BaseLLMHTTPHandler: else False ) if websearch_converted_stream and isinstance(response, dict): - from typing import cast - from litellm._logging import verbose_logger from litellm.llms.anthropic.pass_through.messages.fake_stream_iterator import ( FakeAnthropicMessagesStreamIterator, @@ -6209,6 +6207,7 @@ class BaseLLMHTTPHandler: callbacks: Final = litellm.callbacks + (logging_obj.dynamic_success_callbacks or []) tools: Final = optional_params.get("tools", []) depth, max_loops, fingerprints = self._get_agentic_loop_settings(kwargs=kwargs) + request_kwargs: Final = cast("Mapping[str, object]", kwargs) # cast-ok: kwargs is a str-keyed dict for callback in callbacks: if not isinstance(callback, CustomLogger): @@ -6243,7 +6242,7 @@ class BaseLLMHTTPHandler: # Safety guards must run OUTSIDE the callback try/except — they are # bounded-loop / cycle-break rails that must propagate to the caller. - refuse_a_call_the_choice_excludes(response, kwargs, callbacks, model) + refuse_a_call_the_choice_excludes(response, request_kwargs, callbacks, model) fingerprint = self._check_agentic_loop_safety( tool_calls=tool_calls, fingerprints=fingerprints,