mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-27 06:13:07 +00:00
Merge f736ac8891 into 17db64ef78
This commit is contained in:
commit
dfcb2b603b
12 changed files with 25 additions and 36 deletions
|
|
@ -189,7 +189,6 @@ def _load_beta_headers_config() -> dict:
|
|||
if _BETA_HEADERS_CONFIG is not None:
|
||||
return _BETA_HEADERS_CONFIG
|
||||
|
||||
# Get the URL from environment or use default
|
||||
from litellm import anthropic_beta_headers_url
|
||||
|
||||
_BETA_HEADERS_CONFIG = get_beta_headers_config(url=anthropic_beta_headers_url)
|
||||
|
|
|
|||
|
|
@ -318,9 +318,7 @@ def _classify_fetch_content(content: bytes, url: str, etag: str | None) -> _Fetc
|
|||
return ModelCostMapReloadUnavailable(reason=f"invalid JSON from {url}: {e}")
|
||||
if not isinstance(parsed, dict):
|
||||
return ModelCostMapReloadUnavailable(reason=f"expected a JSON object from {url}, got {type(parsed).__name__}")
|
||||
model_cost_map: Final = cast( # cast-ok: JSON object keys are strings by definition
|
||||
dict[str, object], parsed
|
||||
)
|
||||
model_cost_map: Final = _BUNDLED_CATALOG_ADAPTER.validate_python(parsed)
|
||||
return ModelCostMapReloaded(model_cost_map=model_cost_map, revision=git_blob_id(content), etag=etag)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2757,7 +2757,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
response: ModelResponse | TextCompletionResponse | ResponsesAPIResponse | InteractionsAPIResponse,
|
||||
) -> ModelResponse | TextCompletionResponse | ResponsesAPIResponse | InteractionsAPIResponse:
|
||||
response_id: Final = self.model_call_details.get("continued_response_id")
|
||||
if not isinstance(response_id, str) or getattr(response, "id", None) == response_id:
|
||||
if not isinstance(response_id, str) or response.id == response_id:
|
||||
return response
|
||||
return response.model_copy(update={"id": response_id})
|
||||
|
||||
|
|
@ -5739,7 +5739,7 @@ def _init_custom_logger_compatible_class(
|
|||
logging_integration: str,
|
||||
internal_usage_cache: DualCache | None,
|
||||
llm_router: object,
|
||||
custom_logger_init_args: dict[str, object] | None = {},
|
||||
custom_logger_init_args: dict[str, object] | None = None,
|
||||
raise_import_errors: bool = False,
|
||||
) -> CustomLogger | None:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -2464,8 +2464,6 @@ class CustomStreamWrapper:
|
|||
return any(get(field) for field in cls._CONTINUATION_DISQUALIFYING_DELTA_FIELDS)
|
||||
|
||||
def _accumulate_streamed_delta(self, delta: object) -> None:
|
||||
# Shared by the sync, async, and non-aiohttp iteration sites so answer
|
||||
# text and the disqualifying-content latch stay in step across all three.
|
||||
get: Final = getattr(delta, "get", None)
|
||||
content: Final = get("content") if callable(get) else None
|
||||
self.response_uptil_now += content if isinstance(content, str) else ""
|
||||
|
|
|
|||
|
|
@ -243,8 +243,7 @@ async def caller_within_model_budget(
|
|||
return "allowed"
|
||||
|
||||
model_max_budget: Final = getattr(user_api_key_auth, "model_max_budget", None)
|
||||
token: Final = getattr(user_api_key_auth, "token", None)
|
||||
if isinstance(model_max_budget, dict) and model_max_budget and token is not None:
|
||||
if isinstance(model_max_budget, dict) and model_max_budget and user_api_key_auth.token is not None:
|
||||
try:
|
||||
await model_max_budget_limiter.is_key_within_model_budget(
|
||||
user_api_key_dict=user_api_key_auth,
|
||||
|
|
@ -299,10 +298,8 @@ async def caller_within_model_budget(
|
|||
)
|
||||
return "denied_for_now"
|
||||
|
||||
end_user_model_max_budget: Final[dict[str, object] | None] = getattr(
|
||||
user_api_key_auth, "end_user_model_max_budget", None
|
||||
)
|
||||
end_user_id: Final[str | None] = getattr(user_api_key_auth, "end_user_id", None)
|
||||
end_user_model_max_budget: Final[dict[str, object] | None] = user_api_key_auth.end_user_model_max_budget
|
||||
end_user_id: Final[str | None] = user_api_key_auth.end_user_id
|
||||
if isinstance(end_user_model_max_budget, dict) and end_user_model_max_budget and end_user_id is not None:
|
||||
try:
|
||||
await model_max_budget_limiter.is_end_user_within_model_budget(
|
||||
|
|
|
|||
|
|
@ -452,9 +452,7 @@ def _converse_request(
|
|||
if not all(_text_only(message) for message in messages):
|
||||
return None
|
||||
try:
|
||||
chat_tools: Final = tuple(
|
||||
chat_tool for tool in tools or () for chat_tool in _as_converse_input(tool)
|
||||
) # comprehension-ok: flattens each tool's translation
|
||||
chat_tools: Final = tuple(chain.from_iterable(_as_converse_input(tool) for tool in tools or ()))
|
||||
return _ConverseRequest.model_validate(
|
||||
litellm.AmazonConverseConfig().transform_request(
|
||||
model=model,
|
||||
|
|
|
|||
|
|
@ -5894,7 +5894,6 @@ def completion(
|
|||
return resolve_timeout(stream_kind=StreamKind.NOT_STREAMED)
|
||||
return resolve_timeout(stream_kind=StreamKind.FAKED if fakes_stream(attempt_params) else StreamKind.LIVE)
|
||||
|
||||
### TIMEOUT LOGIC ###
|
||||
timeout = timeout_for_optional_params(optional_params)
|
||||
logging.record_applied_timeout(timeout)
|
||||
processed_non_default_params: Final = pre_process_non_default_params(
|
||||
|
|
|
|||
|
|
@ -6187,9 +6187,9 @@ class MCPServerManager:
|
|||
"server_name": server_name,
|
||||
"mcp_rate_limit_server_name": server.alias or server.server_name or server.name,
|
||||
"user_api_key_auth": checked_auth,
|
||||
"user_api_key_user_id": (getattr(checked_auth, "user_id", None) if checked_auth else None),
|
||||
"user_api_key_team_id": (getattr(checked_auth, "team_id", None) if checked_auth else None),
|
||||
"user_api_key_end_user_id": (getattr(checked_auth, "end_user_id", None) if checked_auth else None),
|
||||
"user_api_key_user_id": checked_auth.user_id if checked_auth else None,
|
||||
"user_api_key_team_id": checked_auth.team_id if checked_auth else None,
|
||||
"user_api_key_end_user_id": checked_auth.end_user_id if checked_auth else None,
|
||||
"user_api_key_hash": (getattr(checked_auth, "api_key_hash", None) if checked_auth else None),
|
||||
"incoming_bearer_token": caller_bearer.get_secret_value() if caller_bearer is not None else None,
|
||||
"headers": logging_safe_mcp_headers(raw_headers),
|
||||
|
|
|
|||
|
|
@ -595,7 +595,7 @@ class SpendLogCleanup:
|
|||
rows: Final = _STORAGE_ROWS.validate_python(
|
||||
await tx.query_raw(trusted_sql(_STORAGE_SQL), list(_SPEND_LOG_TABLES))
|
||||
)
|
||||
except Exception as e: # noqa: BLE001 - a failed measurement skips the size pass, it must not fail the run
|
||||
except Exception as e: # noqa: BLE001 # a failed measurement skips the size pass, it must not fail the run
|
||||
verbose_proxy_logger.warning("Could not measure spend-log storage: %s: %s", type(e).__name__, e)
|
||||
return None
|
||||
if not rows:
|
||||
|
|
@ -663,7 +663,7 @@ class SpendLogCleanup:
|
|||
await tx.query_raw(trusted_sql(_LOAD_SIZE_STATE_SQL), SPEND_LOG_SIZE_CLEANUP_STATE_PARAM)
|
||||
)
|
||||
return SizeCleanupState.model_validate_json(rows[0].state_json) if rows else None
|
||||
except Exception as e: # noqa: BLE001 - an unreadable count restarts from the catalog, it must not fail the run
|
||||
except Exception as e: # noqa: BLE001 # an unreadable count restarts from the catalog, it must not fail the run
|
||||
verbose_proxy_logger.warning("Could not read the spend-log size cleanup state: %s: %s", type(e).__name__, e)
|
||||
return None
|
||||
|
||||
|
|
@ -675,7 +675,7 @@ class SpendLogCleanup:
|
|||
await tx.execute_raw(
|
||||
trusted_sql(_SAVE_SIZE_STATE_SQL), SPEND_LOG_SIZE_CLEANUP_STATE_PARAM, state.model_dump_json()
|
||||
)
|
||||
except Exception as e: # noqa: BLE001 - a lost save costs one re-seed from the catalog, it must not fail the run
|
||||
except Exception as e: # noqa: BLE001 # a lost save costs one re-seed from the catalog, it must not fail the run
|
||||
verbose_proxy_logger.warning("Could not save the spend-log size cleanup state: %s: %s", type(e).__name__, e)
|
||||
|
||||
async def _size_step_cutoff(self, prisma_client: PrismaClient, deadline: float, rows: int) -> datetime | None:
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ def initialize_guardrail(litellm_params: "LitellmParams", guardrail: "Guardrail"
|
|||
additional_provider_specific_params=getattr(litellm_params, "additional_provider_specific_params", {}),
|
||||
unreachable_fallback=getattr(litellm_params, "unreachable_fallback", "fail_closed"),
|
||||
fail_on_error=getattr(litellm_params, "fail_on_error", True),
|
||||
forward_messages_as_sent=getattr(litellm_params, "forward_messages_as_sent", False),
|
||||
forward_messages_as_sent=litellm_params.forward_messages_as_sent,
|
||||
extra_headers=getattr(litellm_params, "extra_headers", None),
|
||||
guardrail_name=guardrail.get("guardrail_name", ""),
|
||||
event_hook=litellm_params.mode,
|
||||
|
|
|
|||
|
|
@ -16161,9 +16161,6 @@ async def _apply_search_filter_to_models(
|
|||
team_public_model_name: Final = (m.get("model_info") or {}).get("team_public_model_name") or ""
|
||||
if search_lower in team_public_model_name.lower():
|
||||
return True
|
||||
# Also match the underlying LiteLLM model name (e.g.
|
||||
# "openrouter/deepseek/deepseek-chat"), so users can find
|
||||
# deployments by typing the provider or the upstream model id.
|
||||
litellm_params: Final[Mapping[str, object]] = m.get("litellm_params") or MappingProxyType({})
|
||||
litellm_model: Final = litellm_params.get("model")
|
||||
return isinstance(litellm_model, str) and search_lower in litellm_model.lower()
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ from dataclasses import dataclass, field
|
|||
from datetime import date, datetime, timedelta, timezone
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from functools import partial
|
||||
from functools import partial, reduce
|
||||
from itertools import takewhile
|
||||
from operator import attrgetter
|
||||
from types import MappingProxyType
|
||||
|
|
@ -1396,14 +1396,17 @@ _LOG_DB_METRICS_CALL_TYPES: Final = frozenset(("get_data", "insert_data", "updat
|
|||
_EXCEPTION_CHAIN_MAX_DEPTH: Final = 16
|
||||
|
||||
|
||||
def _extended_exception_chain(chain: tuple[BaseException, ...], iteration: int) -> tuple[BaseException, ...]:
|
||||
if len(chain) != iteration + 1:
|
||||
return chain
|
||||
following: Final = chain[-1].__cause__ or chain[-1].__context__
|
||||
if following is None or following in chain:
|
||||
return chain
|
||||
return (*chain, following)
|
||||
|
||||
|
||||
def _exception_chain(exception: BaseException) -> tuple[BaseException, ...]:
|
||||
chain: Final[list[BaseException]] = [exception] # mutable-ok: built once, returned frozen
|
||||
for _ in range(_EXCEPTION_CHAIN_MAX_DEPTH):
|
||||
following = chain[-1].__cause__ or chain[-1].__context__
|
||||
if following is None or following in chain:
|
||||
break
|
||||
chain.append(following)
|
||||
return tuple(chain)
|
||||
return reduce(_extended_exception_chain, range(_EXCEPTION_CHAIN_MAX_DEPTH), (exception,))
|
||||
|
||||
|
||||
def _timed_out_reading_from_provider(exception: Exception) -> bool:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue