mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_daily_any_cleanup_08_03_2026
This commit is contained in:
commit
1ae5297ef7
382 changed files with 12771 additions and 2719 deletions
|
|
@ -88,6 +88,36 @@ commands:
|
|||
rm -f /tmp/uv-install.sh
|
||||
echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$BASH_ENV"
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
install_rust:
|
||||
description: "Install pinned rustup (1.28.2) and Rust toolchain (1.97.1) with checksum verification. Adds ~/.cargo/bin to PATH. Run this before any `uv sync` or `uv build` of the workspace: the root package builds litellm-rust through maturin, and on an image without cargo maturin fetches an unpinned rustup and a floating toolchain by itself."
|
||||
steps:
|
||||
- run:
|
||||
name: Install Rust (rustup 1.28.2, toolchain 1.97.1)
|
||||
command: |
|
||||
case "$(uname -m)" in
|
||||
x86_64)
|
||||
RUSTUP_TRIPLE=x86_64-unknown-linux-gnu
|
||||
RUSTUP_SHA256=20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c
|
||||
;;
|
||||
aarch64)
|
||||
RUSTUP_TRIPLE=aarch64-unknown-linux-gnu
|
||||
RUSTUP_SHA256=e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c
|
||||
;;
|
||||
*)
|
||||
echo "install_rust: unsupported architecture $(uname -m)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
curl -sSLf -o /tmp/rustup-init \
|
||||
"https://static.rust-lang.org/rustup/archive/1.28.2/${RUSTUP_TRIPLE}/rustup-init"
|
||||
echo "${RUSTUP_SHA256} /tmp/rustup-init" | sha256sum -c -
|
||||
chmod +x /tmp/rustup-init
|
||||
/tmp/rustup-init -y --no-modify-path --profile minimal --default-toolchain 1.97.1
|
||||
rm -f /tmp/rustup-init
|
||||
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> "$BASH_ENV"
|
||||
export PATH="$HOME/.cargo/bin:$PATH"
|
||||
rustc --version
|
||||
cargo --version
|
||||
start_postgres:
|
||||
description: "Start a postgres-db container on port 5432 and wait until it accepts connections."
|
||||
parameters:
|
||||
|
|
@ -163,6 +193,26 @@ commands:
|
|||
done
|
||||
echo "fake OpenAI endpoint did not become ready" >&2
|
||||
exit 1
|
||||
start_cost_center_service:
|
||||
description: "Start the stand-in cost center validation service (tests/store_model_in_db_tests/cost_center_service.py) on host port 9414 and wait until healthy. The proxy's team-metadata validator (team_metadata_validator_e2e.py, impl 'http') reaches it via TEAM_METADATA_VALIDATION_SERVICE_URL=http://host.docker.internal:9414/validate. Run after uv deps are synced."
|
||||
steps:
|
||||
- run:
|
||||
name: Start cost center validation service
|
||||
background: true
|
||||
command: |
|
||||
uv run --no-sync python tests/store_model_in_db_tests/cost_center_service.py --host 0.0.0.0 --port 9414
|
||||
- run:
|
||||
name: Wait for cost center validation service
|
||||
command: |
|
||||
for i in $(seq 1 30); do
|
||||
if curl -sf http://localhost:9414/health >/dev/null 2>&1; then
|
||||
echo "cost center validation service is up"
|
||||
exit 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
echo "cost center validation service did not become ready" >&2
|
||||
exit 1
|
||||
setup_litellm_enterprise_pip:
|
||||
steps:
|
||||
- run:
|
||||
|
|
@ -178,6 +228,7 @@ commands:
|
|||
- checkout
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-uv-cache-{{ checksum "uv.lock" }}
|
||||
|
|
@ -292,6 +343,7 @@ jobs:
|
|||
- checkout
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Build the wheel
|
||||
environment:
|
||||
|
|
@ -324,6 +376,7 @@ jobs:
|
|||
keys:
|
||||
- v1-uv-cache-{{ checksum "uv.lock" }}
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -397,6 +450,7 @@ jobs:
|
|||
keys:
|
||||
- v1-uv-cache-{{ checksum "uv.lock" }}
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -471,6 +525,7 @@ jobs:
|
|||
keys:
|
||||
- v1-uv-cache-{{ checksum "uv.lock" }}
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -522,6 +577,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -588,6 +644,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -628,6 +685,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -669,6 +727,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -702,6 +761,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-uv-cache-{{ checksum "uv.lock" }}
|
||||
|
|
@ -752,6 +812,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-uv-cache-{{ checksum "uv.lock" }}
|
||||
|
|
@ -803,6 +864,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -836,6 +898,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-uv-cache-{{ checksum "uv.lock" }}
|
||||
|
|
@ -882,6 +945,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -928,6 +992,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -970,6 +1035,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1016,6 +1082,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1063,6 +1130,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-uv-cache-{{ checksum "uv.lock" }}
|
||||
|
|
@ -1103,6 +1171,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1148,6 +1217,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1192,6 +1262,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1224,6 +1295,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1267,6 +1339,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1311,6 +1384,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1355,6 +1429,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1386,6 +1461,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1432,6 +1508,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1477,6 +1554,7 @@ jobs:
|
|||
keys:
|
||||
- v1-uv-cache-{{ checksum "uv.lock" }}
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1527,6 +1605,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1551,6 +1630,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1577,6 +1657,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1678,6 +1759,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1773,6 +1855,7 @@ jobs:
|
|||
at: ~/project
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1861,6 +1944,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -1944,6 +2028,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -2076,6 +2161,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -2162,6 +2248,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -2258,12 +2345,14 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
uv sync --frozen --all-groups --all-extras --python 3.12
|
||||
- start_postgres
|
||||
- start_fake_openai_endpoint
|
||||
- start_cost_center_service
|
||||
- attach_workspace:
|
||||
at: ~/project
|
||||
- run:
|
||||
|
|
@ -2283,11 +2372,13 @@ jobs:
|
|||
-e STORE_MODEL_IN_DB="True" \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e FAKE_OPENAI_API_BASE=http://host.docker.internal:8190 \
|
||||
-e TEAM_METADATA_VALIDATION_SERVICE_URL=http://host.docker.internal:9414/validate \
|
||||
-e LITELLM_LICENSE=$LITELLM_LICENSE \
|
||||
-e LITELLM_LOG=ERROR \
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
--name my-app \
|
||||
-v $(pwd)/litellm/proxy/example_config_yaml/store_model_db_config.yaml:/app/config.yaml \
|
||||
-v $(pwd)/litellm/proxy/example_config_yaml/team_metadata_validator_e2e.py:/app/team_metadata_validator_e2e.py \
|
||||
litellm-docker-database:ci \
|
||||
--config /app/config.yaml \
|
||||
--port 4000
|
||||
|
|
@ -2333,6 +2424,7 @@ jobs:
|
|||
- setup_google_dns
|
||||
# Remove Docker CLI installation since it's already available in machine executor
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -2414,6 +2506,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -2553,6 +2646,7 @@ jobs:
|
|||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
|
|
@ -2743,6 +2837,7 @@ jobs:
|
|||
category: client
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-uv-cache-{{ checksum "uv.lock" }}
|
||||
|
|
@ -2885,6 +2980,7 @@ jobs:
|
|||
category: client
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
- install_rust
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-uv-cache-{{ checksum "uv.lock" }}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"reportAny": {
|
||||
"limit": 29684
|
||||
"limit": 29682
|
||||
},
|
||||
"reportArgumentType": {
|
||||
"limit": 2645
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
"limit": 42
|
||||
},
|
||||
"reportExplicitAny": {
|
||||
"limit": 9442
|
||||
"limit": 9440
|
||||
},
|
||||
"reportFunctionMemberAccess": {
|
||||
"limit": 11
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ from typing import Any, cast
|
|||
# Import all the data structures that define what can be lazy-loaded
|
||||
# These are just lists of names and maps of where to find them
|
||||
from ._lazy_imports_registry import (
|
||||
# Import maps
|
||||
_BEDROCK_TYPES_IMPORT_MAP,
|
||||
_CACHING_IMPORT_MAP,
|
||||
_COST_CALCULATOR_IMPORT_MAP,
|
||||
|
|
@ -33,12 +34,11 @@ from ._lazy_imports_registry import (
|
|||
_TOKEN_COUNTER_IMPORT_MAP,
|
||||
_TYPES_IMPORT_MAP,
|
||||
_TYPES_UTILS_IMPORT_MAP,
|
||||
# Import maps
|
||||
_UTILS_IMPORT_MAP,
|
||||
_UTILS_MODULE_IMPORT_MAP,
|
||||
# Name tuples
|
||||
BEDROCK_TYPES_NAMES,
|
||||
CACHING_NAMES,
|
||||
# Name tuples
|
||||
COST_CALCULATOR_NAMES,
|
||||
DOTPROMPT_NAMES,
|
||||
HTTP_HANDLER_NAMES,
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ def batch_completion_models_all_responses(*args, **kwargs):
|
|||
if result is not None:
|
||||
responses.append(result)
|
||||
except Exception as e:
|
||||
print_verbose(f"batch_completion_models_all_responses: model request failed: {e!s}")
|
||||
print_verbose(f"batch_completion_models_all_responses: model request failed: {e}")
|
||||
continue
|
||||
|
||||
return responses
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ def create_batch(
|
|||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"litellm.batches.main.py::create_batch() - Error inferring custom_llm_provider - {e!s}"
|
||||
f"litellm.batches.main.py::create_batch() - Error inferring custom_llm_provider - {e}"
|
||||
)
|
||||
|
||||
_is_async = kwargs.pop("acreate_batch", False) is True
|
||||
|
|
@ -890,7 +890,7 @@ def cancel_batch(
|
|||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"litellm.batches.main.py::cancel_batch() - Error inferring custom_llm_provider - {e!s}"
|
||||
f"litellm.batches.main.py::cancel_batch() - Error inferring custom_llm_provider - {e}"
|
||||
)
|
||||
optional_params = GenericLiteLLMParams(**kwargs)
|
||||
litellm_params = get_litellm_params(
|
||||
|
|
|
|||
|
|
@ -353,13 +353,13 @@ class Cache:
|
|||
if param in combined_kwargs:
|
||||
param_value: str | None = self._get_param_value(param, kwargs)
|
||||
if param_value is not None:
|
||||
cache_key += f"{param!s}: {param_value!s}"
|
||||
cache_key += f"{param}: {param_value}"
|
||||
elif param not in litellm_param_kwargs: # check if user passed in optional param - e.g. top_k
|
||||
if litellm.enable_caching_on_provider_specific_optional_params is True: # feature flagged for now
|
||||
if kwargs[param] is None:
|
||||
continue # ignore None params
|
||||
param_value = kwargs[param]
|
||||
cache_key += f"{param!s}: {param_value!s}"
|
||||
cache_key += f"{param}: {param_value}"
|
||||
|
||||
if is_semantic_cache:
|
||||
cache_key += self._get_semantic_cache_tenant_scope(kwargs)
|
||||
|
|
@ -676,7 +676,7 @@ class Cache:
|
|||
cache_key, cached_data, kwargs = self._add_cache_logic(result=result, **kwargs)
|
||||
self.cache.set_cache(cache_key, cached_data, **kwargs)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"LiteLLM Cache: Excepton add_cache: {e!s}")
|
||||
verbose_logger.exception(f"LiteLLM Cache: Excepton add_cache: {e}")
|
||||
|
||||
async def async_add_cache(self, result, dynamic_cache_object: BaseCache | None = None, **kwargs):
|
||||
"""
|
||||
|
|
@ -695,7 +695,7 @@ class Cache:
|
|||
else:
|
||||
await self.cache.async_set_cache(cache_key, cached_data, **kwargs)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"LiteLLM Cache: Excepton add_cache: {e!s}")
|
||||
verbose_logger.exception(f"LiteLLM Cache: Excepton add_cache: {e}")
|
||||
|
||||
def _convert_to_cached_embedding(
|
||||
self,
|
||||
|
|
@ -874,7 +874,7 @@ class Cache:
|
|||
else:
|
||||
await self.cache.async_set_cache_pipeline(cache_list=cache_list, **kwargs)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"LiteLLM Cache: Excepton add_cache: {e!s}")
|
||||
verbose_logger.exception(f"LiteLLM Cache: Excepton add_cache: {e}")
|
||||
|
||||
def should_use_cache(self, **kwargs):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ class DualCache(BaseCache):
|
|||
|
||||
return result
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"LiteLLM Cache: Excepton async add_cache: {e!s}")
|
||||
verbose_logger.error(f"LiteLLM Cache: Excepton async add_cache: {e}")
|
||||
raise e
|
||||
|
||||
def get_cache(
|
||||
|
|
@ -347,7 +347,7 @@ class DualCache(BaseCache):
|
|||
if self.redis_cache is not None and local_only is False:
|
||||
await self.redis_cache.async_set_cache(key, value, **kwargs)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"LiteLLM Cache: Excepton async add_cache: {e!s}")
|
||||
verbose_logger.exception(f"LiteLLM Cache: Excepton async add_cache: {e}")
|
||||
|
||||
# async_batch_set_cache
|
||||
async def async_set_cache_pipeline(self, cache_list: list, local_only: bool = False, **kwargs):
|
||||
|
|
@ -366,7 +366,7 @@ class DualCache(BaseCache):
|
|||
cache_list=cache_list, ttl=kwargs.pop("ttl", None), **kwargs
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"LiteLLM Cache: Excepton async add_cache: {e!s}")
|
||||
verbose_logger.exception(f"LiteLLM Cache: Excepton async add_cache: {e}")
|
||||
|
||||
async def async_increment_cache(
|
||||
self,
|
||||
|
|
|
|||
276
litellm/caching/evicted_client_closer.py
Normal file
276
litellm/caching/evicted_client_closer.py
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
"""
|
||||
Deferred close of HTTP/SDK clients that the LLM client cache has evicted.
|
||||
|
||||
Eviction only drops the cache's reference to a client. Every OpenAI/Azure SDK
|
||||
client is a reference cycle (each resource namespace holds the client back), so
|
||||
an evicted client and its pooled TCP connections survive until a generational
|
||||
collection runs, which under load is thousands of requests later.
|
||||
|
||||
Closing at eviction time is not an option: a request that was handed the client
|
||||
just before it was evicted is still using it, and closing it underneath that
|
||||
request raises ``RuntimeError: Cannot send a request, as the client has been
|
||||
closed.``
|
||||
|
||||
So an evicted client is closed once two conditions hold. A grace window must
|
||||
have passed since its eviction, which covers a request that holds the client
|
||||
but is momentarily not on the wire, and the client must report no connection in
|
||||
flight. The second condition is what keeps the first honest: a request may run
|
||||
for ``litellm.request_timeout`` seconds, 6000 by default, and a streaming
|
||||
response is bounded only by how long the upstream keeps sending, so no deadline
|
||||
on its own can promise that a request has finished.
|
||||
|
||||
Only clients litellm itself created are closed; a client the caller supplied is
|
||||
left alone because litellm does not own its lifecycle.
|
||||
|
||||
A client that closes synchronously is closed from wherever the cache is next
|
||||
used. One whose close is a coroutine needs the event loop it was evicted on, so
|
||||
it waits for a call from that loop rather than having work scheduled onto a loop
|
||||
it does not belong to. Queued clients are therefore bucketed by what it takes to
|
||||
close them, and each bucket is ordered by deadline, so a reap walks the entries
|
||||
that are due rather than the whole queue.
|
||||
|
||||
The queue holds its clients weakly, so waiting out a grace window never keeps
|
||||
alive anything the collector would have reclaimed first.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import inspect
|
||||
import threading
|
||||
import time
|
||||
import weakref
|
||||
from collections import deque
|
||||
from collections.abc import Awaitable, Callable, Iterator
|
||||
from dataclasses import dataclass, replace
|
||||
|
||||
from litellm.constants import (
|
||||
EVICTED_LLM_CLIENT_CLOSE_GRACE_SECONDS,
|
||||
EVICTED_LLM_CLIENT_CLOSE_MAX_PENDING,
|
||||
)
|
||||
|
||||
_CLOSABLE_ANYWHERE = "closable-anywhere"
|
||||
_CLOSABLE_ON_ANY_LOOP = "closable-on-any-loop"
|
||||
|
||||
_BucketKey = str | int
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class _PendingClose:
|
||||
"""A queued close.
|
||||
|
||||
The client is held weakly, so queueing one never keeps alive anything the
|
||||
collector would otherwise have reclaimed first.
|
||||
|
||||
``needs_loop`` is set for a client whose close is a coroutine; those can only
|
||||
be closed from the event loop they were evicted on, recorded in ``loop_id``.
|
||||
A client that closes synchronously carries neither constraint.
|
||||
"""
|
||||
|
||||
client_ref: "weakref.ref[object]"
|
||||
loop_id: int | None
|
||||
needs_loop: bool
|
||||
close_after: float
|
||||
|
||||
|
||||
def _bucket_key(pending: _PendingClose) -> _BucketKey:
|
||||
"""Which reaps can close this entry: any at all, any running a loop, or one loop's."""
|
||||
if not pending.needs_loop:
|
||||
return _CLOSABLE_ANYWHERE
|
||||
if pending.loop_id is None:
|
||||
return _CLOSABLE_ON_ANY_LOOP
|
||||
return pending.loop_id
|
||||
|
||||
|
||||
def _running_loop_id() -> int | None:
|
||||
try:
|
||||
return id(asyncio.get_running_loop())
|
||||
except RuntimeError:
|
||||
return None
|
||||
|
||||
|
||||
def _close_function(client: object) -> Callable[[], object] | None:
|
||||
close_fn: Callable[[], object] | None = getattr(client, "aclose", None) or getattr(client, "close", None)
|
||||
return close_fn
|
||||
|
||||
|
||||
def _transport_of(client: object) -> object:
|
||||
"""The httpx transport behind an SDK wrapper, a litellm handler, or a bare client."""
|
||||
for holder in (getattr(client, "_client", None), getattr(client, "client", None), client):
|
||||
transport: object = getattr(holder, "_transport", None)
|
||||
if transport is not None:
|
||||
return transport
|
||||
return None
|
||||
|
||||
|
||||
def _connection_is_idle(connection: object) -> bool:
|
||||
"""A pooled connection is idle unless it is servicing a request."""
|
||||
is_idle: object = getattr(connection, "is_idle", None)
|
||||
return bool(is_idle()) if callable(is_idle) else True
|
||||
|
||||
|
||||
def _pool_has_busy_connection(transport: object) -> bool | None:
|
||||
"""Whether the httpcore pool behind the transport is servicing a request.
|
||||
|
||||
``None`` when there is no such pool, so the caller can ask the other backend.
|
||||
"""
|
||||
pooled: object = getattr(getattr(transport, "_pool", None), "connections", None)
|
||||
if not isinstance(pooled, (list, tuple)):
|
||||
return None
|
||||
return any(
|
||||
not _connection_is_idle(connection) # pyright: ignore[reportUnknownArgumentType] # untyped pool list
|
||||
for connection in pooled # pyright: ignore[reportUnknownVariableType] # untyped pool list
|
||||
)
|
||||
|
||||
|
||||
def _has_connection_in_flight(client: object) -> bool:
|
||||
"""Whether the client is servicing a request right now.
|
||||
|
||||
Both connection backends litellm uses already account for the connections
|
||||
they have handed out, so this reads the client's own lease accounting rather
|
||||
than inferring it from elapsed time: httpcore reports a non-idle connection
|
||||
for the whole of a response including a stream, and aiohttp holds the
|
||||
connection in ``_acquired`` over the same span.
|
||||
|
||||
A client that cannot answer is reported as idle, which leaves the grace
|
||||
window as the only guard, exactly as it was before this check existed.
|
||||
"""
|
||||
try:
|
||||
transport = _transport_of(client)
|
||||
pooled_busy = _pool_has_busy_connection(transport)
|
||||
if pooled_busy is not None:
|
||||
return pooled_busy
|
||||
session: object = getattr(transport, "client", None)
|
||||
return bool(getattr(getattr(session, "connector", None), "_acquired", None))
|
||||
except Exception: # noqa: BLE001 - a client that cannot report its state is treated as idle
|
||||
return False
|
||||
|
||||
|
||||
async def _close_quietly(closing: Awaitable[object]) -> None:
|
||||
try:
|
||||
await closing
|
||||
except Exception: # noqa: BLE001 - a discarded client's close must never surface to callers
|
||||
pass
|
||||
|
||||
|
||||
class EvictedClientCloser:
|
||||
"""Closes evicted, litellm-owned clients once they are idle and out of grace."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
grace_seconds: float = EVICTED_LLM_CLIENT_CLOSE_GRACE_SECONDS,
|
||||
max_pending: int = EVICTED_LLM_CLIENT_CLOSE_MAX_PENDING,
|
||||
clock: Callable[[], float] = time.monotonic,
|
||||
) -> None:
|
||||
self._grace_seconds = grace_seconds
|
||||
self._max_pending = max_pending
|
||||
self._clock = clock
|
||||
self._owned: weakref.WeakSet[object] = weakref.WeakSet()
|
||||
self._buckets: dict[_BucketKey, deque[_PendingClose]] = {} # mutable-ok: deadline-ordered queues
|
||||
self._pending_count = 0
|
||||
self._queue_lock = threading.Lock() # the cache is reachable from every worker thread's loop
|
||||
self._close_tasks: set[asyncio.Task[None]] = set() # mutable-ok: strong refs to running closes
|
||||
|
||||
def mark_owned(self, client: object) -> None:
|
||||
"""Record that litellm created this client, so it may be closed on eviction."""
|
||||
try:
|
||||
self._owned.add(client)
|
||||
except TypeError:
|
||||
pass # values that cannot be weak-referenced are never litellm clients
|
||||
|
||||
def _is_owned(self, client: object) -> bool:
|
||||
try:
|
||||
return client in self._owned
|
||||
except TypeError:
|
||||
return False # unhashable values are never litellm clients
|
||||
|
||||
def schedule(self, client: object) -> None:
|
||||
"""Queue an evicted client for closing once it is idle and out of grace.
|
||||
|
||||
Past ``max_pending`` the client is left to the collector instead, so a
|
||||
workload that churns the cache cannot grow this queue without bound.
|
||||
Every queued entry comes due within one grace window, so the capacity it
|
||||
occupies is returned within that window rather than held.
|
||||
"""
|
||||
if client is None or not self._is_owned(client):
|
||||
return
|
||||
close_fn = _close_function(client)
|
||||
if close_fn is None:
|
||||
return
|
||||
if self._pending_count >= self._max_pending:
|
||||
return
|
||||
self._enqueue(
|
||||
_PendingClose(
|
||||
client_ref=weakref.ref(client),
|
||||
loop_id=_running_loop_id(),
|
||||
needs_loop=inspect.iscoroutinefunction(close_fn),
|
||||
close_after=self._clock() + self._grace_seconds,
|
||||
)
|
||||
)
|
||||
|
||||
def reap(self) -> None:
|
||||
"""Close every queued client that is due, idle, and closable from here.
|
||||
|
||||
Called from the cache's read path, so the empty-queue exit comes first and
|
||||
the work done past it is proportional to what is due, not to the queue.
|
||||
"""
|
||||
if not self._pending_count:
|
||||
return
|
||||
now = self._clock()
|
||||
for pending in self._take_due(_running_loop_id(), now):
|
||||
client = pending.client_ref()
|
||||
if client is None:
|
||||
continue
|
||||
if _has_connection_in_flight(client):
|
||||
self._enqueue(replace(pending, close_after=now + self._grace_seconds))
|
||||
continue
|
||||
self._close(client)
|
||||
|
||||
@property
|
||||
def pending_count(self) -> int:
|
||||
return self._pending_count
|
||||
|
||||
def _enqueue(self, pending: _PendingClose) -> None:
|
||||
"""Append to the entry's bucket, dropping any dead entries it queues behind.
|
||||
|
||||
Deadlines only ever move forward, so appending keeps each bucket ordered
|
||||
by deadline, and entries whose client the collector already took sit at
|
||||
the front rather than having to be searched for.
|
||||
"""
|
||||
with self._queue_lock:
|
||||
bucket = self._buckets.setdefault(_bucket_key(pending), deque()) # mutable-ok: FIFO by design
|
||||
while bucket and bucket[0].client_ref() is None:
|
||||
bucket.popleft()
|
||||
self._pending_count -= 1
|
||||
bucket.append(pending)
|
||||
self._pending_count += 1
|
||||
|
||||
def _take_due(self, loop_id: int | None, now: float) -> tuple[_PendingClose, ...]:
|
||||
buckets = (_CLOSABLE_ANYWHERE,) if loop_id is None else (_CLOSABLE_ANYWHERE, _CLOSABLE_ON_ANY_LOOP, loop_id)
|
||||
with self._queue_lock:
|
||||
return tuple(pending for key in buckets for pending in self._drain_locked(key, now))
|
||||
|
||||
def _drain_locked(self, key: _BucketKey, now: float) -> Iterator[_PendingClose]:
|
||||
bucket = self._buckets.get(key)
|
||||
if bucket is None:
|
||||
return
|
||||
while bucket and bucket[0].close_after <= now:
|
||||
self._pending_count -= 1
|
||||
yield bucket.popleft()
|
||||
if not bucket:
|
||||
del self._buckets[key]
|
||||
|
||||
def _close(self, client: object) -> None:
|
||||
close_fn = _close_function(client)
|
||||
if close_fn is None:
|
||||
return
|
||||
try:
|
||||
closing = close_fn()
|
||||
except Exception: # noqa: BLE001 - a discarded client's close must never surface to callers
|
||||
return
|
||||
if not inspect.isawaitable(closing):
|
||||
return
|
||||
task = asyncio.get_running_loop().create_task(_close_quietly(closing))
|
||||
self._close_tasks.add(task)
|
||||
task.add_done_callback(self._close_tasks.discard)
|
||||
|
||||
|
||||
default_evicted_client_closer = EvictedClientCloser()
|
||||
|
|
@ -4,21 +4,44 @@ Add the event loop to the cache key, to prevent event loop closed errors.
|
|||
|
||||
import asyncio
|
||||
|
||||
from .evicted_client_closer import EvictedClientCloser, default_evicted_client_closer
|
||||
from .in_memory_cache import InMemoryCache
|
||||
|
||||
|
||||
class LLMClientCache(InMemoryCache):
|
||||
"""Cache for LLM HTTP clients (OpenAI, Azure, httpx, etc.).
|
||||
|
||||
IMPORTANT: This cache intentionally does NOT close clients on eviction.
|
||||
Evicted clients may still be in use by in-flight requests. Closing them
|
||||
eagerly causes ``RuntimeError: Cannot send a request, as the client has
|
||||
been closed.`` errors in production after the TTL (1 hour) expires.
|
||||
An evicted client is never closed on the spot: a request handed the client
|
||||
just before eviction is still using it, and closing it there raises
|
||||
``RuntimeError: Cannot send a request, as the client has been closed.``
|
||||
|
||||
Clients that are no longer referenced will be garbage-collected normally.
|
||||
For explicit shutdown cleanup, use ``close_litellm_async_clients()``.
|
||||
Nor can eviction be left to rely on garbage collection. The SDK clients are
|
||||
reference cycles, so an evicted client and its open TCP connections survive
|
||||
until a generational collection runs. Instead a client litellm created is
|
||||
handed to ``EvictedClientCloser``, which closes it once a grace window has
|
||||
passed. Clients the caller supplied are left untouched.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
max_size_in_memory: int | None = 200,
|
||||
default_ttl: int | None = 600,
|
||||
max_size_per_item: int | None = 1024,
|
||||
evicted_client_closer: EvictedClientCloser | None = None,
|
||||
):
|
||||
super().__init__(
|
||||
max_size_in_memory=max_size_in_memory,
|
||||
default_ttl=default_ttl,
|
||||
max_size_per_item=max_size_per_item,
|
||||
)
|
||||
self.evicted_client_closer = evicted_client_closer or default_evicted_client_closer
|
||||
|
||||
def _remove_key(self, key: str) -> None:
|
||||
evicted: object = self.cache_dict.get(key)
|
||||
super()._remove_key(key)
|
||||
self.evicted_client_closer.schedule(evicted)
|
||||
self.evicted_client_closer.reap()
|
||||
|
||||
def update_cache_key_with_event_loop(self, key):
|
||||
"""
|
||||
Add the event loop to the cache key, to prevent event loop closed errors.
|
||||
|
|
@ -31,16 +54,22 @@ class LLMClientCache(InMemoryCache):
|
|||
except RuntimeError: # handle no current running event loop
|
||||
return key
|
||||
|
||||
def set_cache(self, key, value, **kwargs):
|
||||
def set_cache(self, key: str, value: object, litellm_owned_client: bool = False, **kwargs):
|
||||
"""``litellm_owned_client`` marks a client litellm built, so it may be closed once evicted."""
|
||||
if litellm_owned_client:
|
||||
self.evicted_client_closer.mark_owned(value)
|
||||
key = self.update_cache_key_with_event_loop(key)
|
||||
return super().set_cache(key, value, **kwargs)
|
||||
|
||||
async def async_set_cache(self, key, value, **kwargs):
|
||||
async def async_set_cache(self, key: str, value: object, litellm_owned_client: bool = False, **kwargs):
|
||||
if litellm_owned_client:
|
||||
self.evicted_client_closer.mark_owned(value)
|
||||
key = self.update_cache_key_with_event_loop(key)
|
||||
return await super().async_set_cache(key, value, **kwargs)
|
||||
|
||||
def get_cache(self, key, **kwargs):
|
||||
key = self.update_cache_key_with_event_loop(key)
|
||||
self.evicted_client_closer.reap()
|
||||
|
||||
return super().get_cache(key, **kwargs)
|
||||
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ class QdrantSemanticCache(BaseCache):
|
|||
if response.status_code not in (200, 201):
|
||||
print_verbose(f"Qdrant semantic-cache could not create cache-key payload index: {response.text}")
|
||||
except Exception as exc:
|
||||
print_verbose(f"Qdrant semantic-cache could not create cache-key payload index: {exc!s}")
|
||||
print_verbose(f"Qdrant semantic-cache could not create cache-key payload index: {exc}")
|
||||
|
||||
def _payload_matches_cache_key(self, payload: dict, key: str) -> bool:
|
||||
# Pre-isolation points stored only prompt + response with no cache-key
|
||||
|
|
|
|||
|
|
@ -346,7 +346,7 @@ class RedisCache(BaseCache):
|
|||
verbose_logger.debug("Ignoring async redis ping. No running event loop.")
|
||||
else:
|
||||
verbose_logger.error(
|
||||
f"Error connecting to Async Redis client - {e!s}",
|
||||
f"Error connecting to Async Redis client - {e}",
|
||||
extra={"error": str(e)},
|
||||
)
|
||||
self._handle_async_ping_error(e)
|
||||
|
|
@ -483,7 +483,7 @@ class RedisCache(BaseCache):
|
|||
)
|
||||
except Exception as e:
|
||||
# NON blocking - notify users Redis is throwing an exception
|
||||
print_verbose(f"litellm.caching.caching: set() - Got exception from REDIS : {e!s}")
|
||||
print_verbose(f"litellm.caching.caching: set() - Got exception from REDIS : {e}")
|
||||
|
||||
def increment_cache(self, key, value: int, ttl: float | None = None, **kwargs) -> int:
|
||||
_redis_client = self.redis_client
|
||||
|
|
@ -1139,7 +1139,7 @@ class RedisCache(BaseCache):
|
|||
|
||||
return decoded_results
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"Error occurred in batch get cache - {e!s}")
|
||||
verbose_logger.error(f"Error occurred in batch get cache - {e}")
|
||||
return key_value_dict
|
||||
|
||||
@_redis_circuit_breaker_guard
|
||||
|
|
@ -1185,7 +1185,7 @@ class RedisCache(BaseCache):
|
|||
event_metadata={"key": key},
|
||||
)
|
||||
)
|
||||
print_verbose(f"litellm.caching.caching: async get() - Got exception from REDIS: {e!s}")
|
||||
print_verbose(f"litellm.caching.caching: async get() - Got exception from REDIS: {e}")
|
||||
_record_swallowed_redis_failure(self._circuit_breaker, e)
|
||||
|
||||
@_redis_circuit_breaker_guard
|
||||
|
|
@ -1257,7 +1257,7 @@ class RedisCache(BaseCache):
|
|||
parent_otel_span=parent_otel_span,
|
||||
)
|
||||
)
|
||||
verbose_logger.error(f"Error occurred in async batch get cache - {e!s}")
|
||||
verbose_logger.error(f"Error occurred in async batch get cache - {e}")
|
||||
_record_swallowed_redis_failure(self._circuit_breaker, e)
|
||||
return key_value_dict
|
||||
|
||||
|
|
@ -1292,7 +1292,7 @@ class RedisCache(BaseCache):
|
|||
error=e,
|
||||
call_type=f"sync_ping <- {_get_call_stack_info()}",
|
||||
)
|
||||
verbose_logger.error(f"LiteLLM Redis Cache PING: - Got exception from REDIS : {e!s}")
|
||||
verbose_logger.error(f"LiteLLM Redis Cache PING: - Got exception from REDIS : {e}")
|
||||
raise e
|
||||
|
||||
async def ping(self) -> bool:
|
||||
|
|
@ -1326,7 +1326,7 @@ class RedisCache(BaseCache):
|
|||
call_type=f"async_ping <- {_get_call_stack_info()}",
|
||||
)
|
||||
)
|
||||
verbose_logger.error(f"LiteLLM Redis Cache PING: - Got exception from REDIS : {e!s}")
|
||||
verbose_logger.error(f"LiteLLM Redis Cache PING: - Got exception from REDIS : {e}")
|
||||
raise e
|
||||
|
||||
@_redis_circuit_breaker_guard
|
||||
|
|
@ -1388,10 +1388,10 @@ class RedisCache(BaseCache):
|
|||
else:
|
||||
return {"status": "failed", "message": "Redis ping returned False"}
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"Redis connection test failed: {e!s}")
|
||||
verbose_logger.error(f"Redis connection test failed: {e}")
|
||||
return {
|
||||
"status": "failed",
|
||||
"message": f"Redis connection failed: {e!s}",
|
||||
"message": f"Redis connection failed: {e}",
|
||||
"error": str(e),
|
||||
}
|
||||
|
||||
|
|
@ -1565,7 +1565,7 @@ class RedisCache(BaseCache):
|
|||
call_type=f"async_rpush <- {_get_call_stack_info()}",
|
||||
)
|
||||
)
|
||||
verbose_logger.error(f"LiteLLM Redis Cache RPUSH: - Got exception from REDIS : {e!s}")
|
||||
verbose_logger.error(f"LiteLLM Redis Cache RPUSH: - Got exception from REDIS : {e}")
|
||||
raise e
|
||||
|
||||
async def _pipeline_rpush_helper(
|
||||
|
|
@ -1711,7 +1711,7 @@ class RedisCache(BaseCache):
|
|||
call_type=f"async_lpop <- {_get_call_stack_info()}",
|
||||
)
|
||||
)
|
||||
verbose_logger.error(f"LiteLLM Redis Cache LPOP: - Got exception from REDIS : {e!s}")
|
||||
verbose_logger.error(f"LiteLLM Redis Cache LPOP: - Got exception from REDIS : {e}")
|
||||
raise e
|
||||
|
||||
async def _pipeline_lpop_helper(
|
||||
|
|
|
|||
|
|
@ -100,9 +100,9 @@ class RedisClusterCache(RedisCache):
|
|||
except Exception as e:
|
||||
from litellm._logging import verbose_logger
|
||||
|
||||
verbose_logger.error(f"Redis Cluster connection test failed: {e!s}")
|
||||
verbose_logger.error(f"Redis Cluster connection test failed: {e}")
|
||||
return {
|
||||
"status": "failed",
|
||||
"message": f"Redis Cluster connection failed: {e!s}",
|
||||
"message": f"Redis Cluster connection failed: {e}",
|
||||
"error": str(e),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ class RedisSemanticCache(BaseCache):
|
|||
try:
|
||||
cached_response = ast.literal_eval(cached_response)
|
||||
except (ValueError, SyntaxError) as e:
|
||||
print_verbose(f"Error parsing cached response: {e!s}")
|
||||
print_verbose(f"Error parsing cached response: {e}")
|
||||
return None
|
||||
|
||||
return cached_response
|
||||
|
|
@ -403,7 +403,7 @@ class RedisSemanticCache(BaseCache):
|
|||
store_kwargs["ttl"] = int(ttl)
|
||||
self.llmcache.store(prompt, value_str, **store_kwargs)
|
||||
except Exception as e:
|
||||
print_verbose(f"Error setting {value_str or value} in the Redis semantic cache: {e!s}")
|
||||
print_verbose(f"Error setting {value_str or value} in the Redis semantic cache: {e}")
|
||||
|
||||
def get_cache(self, key: str, **kwargs) -> Any:
|
||||
"""
|
||||
|
|
@ -468,7 +468,7 @@ class RedisSemanticCache(BaseCache):
|
|||
|
||||
return self._get_cache_logic(cached_response=cached_response)
|
||||
except Exception as e:
|
||||
print_verbose(f"Error retrieving from Redis semantic cache: {e!s}")
|
||||
print_verbose(f"Error retrieving from Redis semantic cache: {e}")
|
||||
kwargs.setdefault("metadata", {})["semantic-similarity"] = 0.0
|
||||
|
||||
async def _get_async_embedding(self, prompt: str, metadata: dict[str, Any] | None = None) -> list[float]:
|
||||
|
|
@ -505,8 +505,8 @@ class RedisSemanticCache(BaseCache):
|
|||
)
|
||||
return embedding_response["data"][0]["embedding"]
|
||||
except Exception as e:
|
||||
print_verbose(f"Error generating async embedding: {e!s}")
|
||||
raise ValueError(f"Failed to generate embedding: {e!s}") from e
|
||||
print_verbose(f"Error generating async embedding: {e}")
|
||||
raise ValueError(f"Failed to generate embedding: {e}") from e
|
||||
|
||||
async def async_set_cache(self, key: str, value: Any, **kwargs) -> None:
|
||||
"""
|
||||
|
|
@ -546,7 +546,7 @@ class RedisSemanticCache(BaseCache):
|
|||
**store_kwargs,
|
||||
)
|
||||
except Exception as e:
|
||||
print_verbose(f"Error in async_set_cache: {e!s}")
|
||||
print_verbose(f"Error in async_set_cache: {e}")
|
||||
|
||||
async def async_get_cache(self, key: str, **kwargs) -> Any:
|
||||
"""
|
||||
|
|
@ -612,7 +612,7 @@ class RedisSemanticCache(BaseCache):
|
|||
|
||||
return self._get_cache_logic(cached_response=cached_response)
|
||||
except Exception as e:
|
||||
print_verbose(f"Error in async_get_cache: {e!s}")
|
||||
print_verbose(f"Error in async_get_cache: {e}")
|
||||
kwargs.setdefault("metadata", {})["semantic-similarity"] = 0.0
|
||||
|
||||
async def _index_info(self) -> dict[str, Any]:
|
||||
|
|
@ -639,4 +639,4 @@ class RedisSemanticCache(BaseCache):
|
|||
tasks.append(self.async_set_cache(val[0], val[1], **kwargs))
|
||||
await asyncio.gather(*tasks)
|
||||
except Exception as e:
|
||||
print_verbose(f"Error in async_set_cache_pipeline: {e!s}")
|
||||
print_verbose(f"Error in async_set_cache_pipeline: {e}")
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ class ValkeySemanticCache(RedisSemanticCache):
|
|||
if ttl is not None:
|
||||
self.sync_client.expire(doc_key, ttl)
|
||||
except Exception as e:
|
||||
print_verbose(f"Error in Valkey semantic-cache set_cache: {e!s}")
|
||||
print_verbose(f"Error in Valkey semantic-cache set_cache: {e}")
|
||||
|
||||
def get_cache(self, key: str, **kwargs: Any) -> Any:
|
||||
print_verbose(f"Valkey semantic-cache get_cache, kwargs: {kwargs}")
|
||||
|
|
@ -268,7 +268,7 @@ class ValkeySemanticCache(RedisSemanticCache):
|
|||
)
|
||||
return self._resolve_hit(self._first_hit(search_result), key, **kwargs)
|
||||
except Exception as e:
|
||||
print_verbose(f"Error in Valkey semantic-cache get_cache: {e!s}")
|
||||
print_verbose(f"Error in Valkey semantic-cache get_cache: {e}")
|
||||
kwargs.setdefault("metadata", {})["semantic-similarity"] = 0.0
|
||||
|
||||
async def async_set_cache(self, key: str, value: Any, **kwargs: Any) -> None:
|
||||
|
|
@ -288,7 +288,7 @@ class ValkeySemanticCache(RedisSemanticCache):
|
|||
if ttl is not None:
|
||||
await self.async_client.expire(doc_key, ttl)
|
||||
except Exception as e:
|
||||
print_verbose(f"Error in async Valkey semantic-cache set_cache: {e!s}")
|
||||
print_verbose(f"Error in async Valkey semantic-cache set_cache: {e}")
|
||||
|
||||
async def async_get_cache(self, key: str, **kwargs: Any) -> Any:
|
||||
print_verbose(f"Async Valkey semantic-cache get_cache, kwargs: {kwargs}")
|
||||
|
|
@ -307,14 +307,14 @@ class ValkeySemanticCache(RedisSemanticCache):
|
|||
)
|
||||
return self._resolve_hit(self._first_hit(search_result), key, **kwargs)
|
||||
except Exception as e:
|
||||
print_verbose(f"Error in async Valkey semantic-cache get_cache: {e!s}")
|
||||
print_verbose(f"Error in async Valkey semantic-cache get_cache: {e}")
|
||||
kwargs.setdefault("metadata", {})["semantic-similarity"] = 0.0
|
||||
|
||||
async def async_set_cache_pipeline(self, cache_list: list[tuple[str, Any]], **kwargs: Any) -> None:
|
||||
try:
|
||||
await asyncio.gather(*[self.async_set_cache(key, value, **kwargs) for key, value in cache_list])
|
||||
except Exception as e:
|
||||
print_verbose(f"Error in Valkey semantic-cache async_set_cache_pipeline: {e!s}")
|
||||
print_verbose(f"Error in Valkey semantic-cache async_set_cache_pipeline: {e}")
|
||||
|
||||
async def _index_info(self) -> dict:
|
||||
return await self.async_client.ft(self.index_name).info()
|
||||
|
|
|
|||
|
|
@ -197,6 +197,16 @@ RUNWAYML_POLLING_TIMEOUT = int(os.getenv("RUNWAYML_POLLING_TIMEOUT", 600)) # 10
|
|||
########## Networking constants ##############################################################
|
||||
_DEFAULT_TTL_FOR_HTTPX_CLIENTS = 3600 # 1 hour, re-use the same httpx client for 1 hour
|
||||
|
||||
# The earliest an evicted, litellm-created client may be closed. A request handed the
|
||||
# client just before eviction is still using it, so nothing is closed inside this window;
|
||||
# past it, the client is closed once it reports no connection in flight.
|
||||
EVICTED_LLM_CLIENT_CLOSE_GRACE_SECONDS = 900
|
||||
|
||||
# How many evicted clients may be queued for closing at once. Past this, an evicted client
|
||||
# is left to the collector rather than letting a cache-churning workload grow the queue
|
||||
# without bound. Each queued entry is ~100 bytes and comes due within one grace window.
|
||||
EVICTED_LLM_CLIENT_CLOSE_MAX_PENDING = 10_000
|
||||
|
||||
# Aiohttp connection pooling - prevents memory leaks from unbounded connection growth
|
||||
# Set to 0 for unlimited (not recommended for production)
|
||||
AIOHTTP_CONNECTOR_LIMIT = int(os.getenv("AIOHTTP_CONNECTOR_LIMIT", 1000))
|
||||
|
|
|
|||
|
|
@ -715,7 +715,7 @@ def _get_provider_for_cost_calc(
|
|||
_, custom_llm_provider, _, _ = litellm.get_llm_provider(model=model)
|
||||
except Exception as e:
|
||||
verbose_logger.debug(
|
||||
f"litellm.cost_calculator.py::_get_provider_for_cost_calc() - Error inferring custom_llm_provider - {e!s}"
|
||||
f"litellm.cost_calculator.py::_get_provider_for_cost_calc() - Error inferring custom_llm_provider - {e}"
|
||||
)
|
||||
return None
|
||||
|
||||
|
|
@ -1092,7 +1092,7 @@ def _store_cost_breakdown_in_logging_obj(
|
|||
)
|
||||
|
||||
except Exception as breakdown_error:
|
||||
verbose_logger.debug(f"Error storing cost breakdown: {breakdown_error!s}")
|
||||
verbose_logger.debug(f"Error storing cost breakdown: {breakdown_error}")
|
||||
# Don't fail the main cost calculation if breakdown storage fails
|
||||
|
||||
|
||||
|
|
@ -1315,7 +1315,7 @@ def completion_cost(
|
|||
) # strip the llm provider from the model name -> for image gen cost calculation
|
||||
except Exception as e:
|
||||
verbose_logger.debug(
|
||||
f"litellm.cost_calculator.py::completion_cost() - Error inferring custom_llm_provider - {e!s}"
|
||||
f"litellm.cost_calculator.py::completion_cost() - Error inferring custom_llm_provider - {e}"
|
||||
)
|
||||
if CostCalculatorUtils._call_type_has_image_response(call_type) and isinstance(
|
||||
completion_response, ImageResponse
|
||||
|
|
@ -1662,7 +1662,7 @@ def completion_cost(
|
|||
return _final_cost
|
||||
except Exception as e:
|
||||
verbose_logger.debug(
|
||||
f"litellm.cost_calculator.py::completion_cost() - Error calculating cost for model={model} - {e!s}"
|
||||
f"litellm.cost_calculator.py::completion_cost() - Error calculating cost for model={model} - {e}"
|
||||
)
|
||||
if idx == len(potential_model_names) - 1:
|
||||
raise e
|
||||
|
|
|
|||
|
|
@ -1140,7 +1140,7 @@ class MidStreamFallbackError(ServiceUnavailableError): # type: ignore
|
|||
if self.max_retries:
|
||||
_message += f", LiteLLM Max Retries: {self.max_retries}"
|
||||
if self.original_exception:
|
||||
_message += f" Original exception: {type(self.original_exception).__name__}: {self.original_exception!s}"
|
||||
_message += f" Original exception: {type(self.original_exception).__name__}: {self.original_exception}"
|
||||
return _message
|
||||
|
||||
def __repr__(self):
|
||||
|
|
|
|||
|
|
@ -515,7 +515,7 @@ class MCPClient:
|
|||
_log(
|
||||
f"MCP client list_tools failed - "
|
||||
f"Error Type: {error_type}, "
|
||||
f"Error: {e!s}, "
|
||||
f"Error: {e}, "
|
||||
f"Server: {self.server_url or 'stdio'}, "
|
||||
f"Transport: {self.transport_type}"
|
||||
)
|
||||
|
|
@ -536,7 +536,7 @@ class MCPClient:
|
|||
def error_tool_result(exc: Exception) -> MCPCallToolResult:
|
||||
"""The error result ``call_tool`` returns when it swallows a failure (no re-execution)."""
|
||||
return MCPCallToolResult(
|
||||
content=[TextContent(type="text", text=f"{type(exc).__name__}: {exc!s}")],
|
||||
content=[TextContent(type="text", text=f"{type(exc).__name__}: {exc}")],
|
||||
isError=True,
|
||||
)
|
||||
|
||||
|
|
@ -601,7 +601,7 @@ class MCPClient:
|
|||
_log(
|
||||
f"MCP client call_tool failed - "
|
||||
f"Error Type: {error_type}, "
|
||||
f"Error: {e!s}, "
|
||||
f"Error: {e}, "
|
||||
f"Tool: {call_tool_request_params.name}, "
|
||||
f"Server: {self.server_url or 'stdio'}, "
|
||||
f"Transport: {self.transport_type}"
|
||||
|
|
@ -640,7 +640,7 @@ class MCPClient:
|
|||
verbose_logger.error(
|
||||
f"MCP client list_prompts failed - "
|
||||
f"Error Type: {error_type}, "
|
||||
f"Error: {e!s}, "
|
||||
f"Error: {e}, "
|
||||
f"Server: {self.server_url or 'stdio'}, "
|
||||
f"Transport: {self.transport_type}"
|
||||
)
|
||||
|
|
@ -681,7 +681,7 @@ class MCPClient:
|
|||
verbose_logger.error(
|
||||
f"MCP client get_prompt failed - "
|
||||
f"Error Type: {error_type}, "
|
||||
f"Error: {e!s}, "
|
||||
f"Error: {e}, "
|
||||
f"Prompt: {get_prompt_request_params.name}, "
|
||||
f"Server: {self.server_url or 'stdio'}, "
|
||||
f"Transport: {self.transport_type}"
|
||||
|
|
@ -717,7 +717,7 @@ class MCPClient:
|
|||
verbose_logger.error(
|
||||
f"MCP client list_resources failed - "
|
||||
f"Error Type: {error_type}, "
|
||||
f"Error: {e!s}, "
|
||||
f"Error: {e}, "
|
||||
f"Server: {self.server_url or 'stdio'}, "
|
||||
f"Transport: {self.transport_type}"
|
||||
)
|
||||
|
|
@ -753,7 +753,7 @@ class MCPClient:
|
|||
verbose_logger.error(
|
||||
f"MCP client list_resource_templates failed - "
|
||||
f"Error Type: {error_type}, "
|
||||
f"Error: {e!s}, "
|
||||
f"Error: {e}, "
|
||||
f"Server: {self.server_url or 'stdio'}, "
|
||||
f"Transport: {self.transport_type}"
|
||||
)
|
||||
|
|
@ -791,7 +791,7 @@ class MCPClient:
|
|||
verbose_logger.error(
|
||||
f"MCP client read_resource failed - "
|
||||
f"Error Type: {error_type}, "
|
||||
f"Error: {e!s}, "
|
||||
f"Error: {e}, "
|
||||
f"Url: {url}, "
|
||||
f"Server: {self.server_url or 'stdio'}, "
|
||||
f"Transport: {self.transport_type}"
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class GenerateContentToCompletionHandler:
|
|||
return generate_content_response
|
||||
|
||||
except Exception as e:
|
||||
raise ValueError(f"Error calling litellm.acompletion for generate_content: {e!s}")
|
||||
raise ValueError(f"Error calling litellm.acompletion for generate_content: {e}")
|
||||
|
||||
@staticmethod
|
||||
def generate_content_handler(
|
||||
|
|
@ -159,4 +159,4 @@ class GenerateContentToCompletionHandler:
|
|||
return generate_content_response
|
||||
|
||||
except Exception as e:
|
||||
raise ValueError(f"Error calling litellm.completion for generate_content: {e!s}")
|
||||
raise ValueError(f"Error calling litellm.completion for generate_content: {e}")
|
||||
|
|
|
|||
|
|
@ -70,6 +70,6 @@ async def send_to_webhook(slackAlertingInstance: SlackAlertingType, item, count)
|
|||
if response.status_code != 200:
|
||||
verbose_proxy_logger.debug(f"Error sending slack alert to url={item['url']}. Error={response.text}")
|
||||
except Exception as e:
|
||||
verbose_proxy_logger.debug(f"Error sending slack alert: {e!s}")
|
||||
verbose_proxy_logger.debug(f"Error sending slack alert: {e}")
|
||||
finally:
|
||||
_print_alerting_payload_warning(payload, slackAlertingInstance=slackAlertingInstance)
|
||||
|
|
|
|||
|
|
@ -1467,7 +1467,7 @@ Model Info:
|
|||
try:
|
||||
await self._flush_digest_buckets()
|
||||
except Exception as e:
|
||||
verbose_proxy_logger.debug(f"Error flushing digest buckets: {e!s}")
|
||||
verbose_proxy_logger.debug(f"Error flushing digest buckets: {e}")
|
||||
await self.flush_queue()
|
||||
|
||||
async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):
|
||||
|
|
@ -1502,7 +1502,7 @@ Model Info:
|
|||
)
|
||||
except Exception as e:
|
||||
verbose_proxy_logger.error(
|
||||
f"[Non-Blocking Error] Slack Alerting: Got error in logging LLM deployment latency: {e!s}"
|
||||
f"[Non-Blocking Error] Slack Alerting: Got error in logging LLM deployment latency: {e}"
|
||||
)
|
||||
|
||||
async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time):
|
||||
|
|
@ -1522,7 +1522,7 @@ Model Info:
|
|||
)
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"Exception raises -{e!s}")
|
||||
verbose_logger.debug(f"Exception raises -{e}")
|
||||
|
||||
if isinstance(kwargs.get("exception", ""), APIError):
|
||||
if "outage_alerts" in self.alert_types:
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ class ArizeLogger(OpenTelemetry):
|
|||
except Exception as e:
|
||||
return {
|
||||
"status": "unhealthy",
|
||||
"error_message": f"Arize health check failed: {e!s}",
|
||||
"error_message": f"Arize health check failed: {e}",
|
||||
}
|
||||
|
||||
def construct_dynamic_otel_headers(
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ class AzureSentinelLogger(CustomBatchLogger):
|
|||
await self.async_send_batch()
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Azure Sentinel Layer Error - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"Azure Sentinel Layer Error - {e}\n{traceback.format_exc()}")
|
||||
|
||||
async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time):
|
||||
"""
|
||||
|
|
@ -233,7 +233,7 @@ class AzureSentinelLogger(CustomBatchLogger):
|
|||
await self.async_send_batch()
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Azure Sentinel Layer Error - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"Azure Sentinel Layer Error - {e}\n{traceback.format_exc()}")
|
||||
|
||||
async def async_log_audit_log_event(self, audit_log: StandardAuditLogPayload) -> None:
|
||||
"""
|
||||
|
|
@ -256,7 +256,7 @@ class AzureSentinelLogger(CustomBatchLogger):
|
|||
await self.async_send_audit_batch()
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Azure Sentinel Audit Log Layer Error - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"Azure Sentinel Audit Log Layer Error - {e}\n{traceback.format_exc()}")
|
||||
|
||||
async def async_send_batch(self):
|
||||
"""
|
||||
|
|
@ -323,7 +323,7 @@ class AzureSentinelLogger(CustomBatchLogger):
|
|||
)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Azure Sentinel Error sending batch API - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"Azure Sentinel Error sending batch API - {e}\n{traceback.format_exc()}")
|
||||
finally:
|
||||
log_queue.clear()
|
||||
|
||||
|
|
|
|||
|
|
@ -53,9 +53,7 @@ class AzureBlobStorageLogger(CustomBatchLogger):
|
|||
self.log_queue: list[StandardLoggingPayload] = []
|
||||
super().__init__(**kwargs, flush_lock=self.flush_lock)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"AzureBlobStorageLogger: Got exception on init AzureBlobStorageLogger client {e!s}"
|
||||
)
|
||||
verbose_logger.exception(f"AzureBlobStorageLogger: Got exception on init AzureBlobStorageLogger client {e}")
|
||||
raise e
|
||||
|
||||
async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):
|
||||
|
|
@ -79,7 +77,7 @@ class AzureBlobStorageLogger(CustomBatchLogger):
|
|||
self.log_queue.append(standard_logging_payload)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"AzureBlobStorageLogger Layer Error - {e!s}")
|
||||
verbose_logger.exception(f"AzureBlobStorageLogger Layer Error - {e}")
|
||||
|
||||
async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time):
|
||||
"""
|
||||
|
|
@ -101,7 +99,7 @@ class AzureBlobStorageLogger(CustomBatchLogger):
|
|||
|
||||
self.log_queue.append(standard_logging_payload)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"AzureBlobStorageLogger Layer Error - {e!s}")
|
||||
verbose_logger.exception(f"AzureBlobStorageLogger Layer Error - {e}")
|
||||
|
||||
async def async_send_batch(self):
|
||||
"""
|
||||
|
|
@ -124,7 +122,7 @@ class AzureBlobStorageLogger(CustomBatchLogger):
|
|||
await self.async_upload_payload_to_azure_blob_storage(payload=payload)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"AzureBlobStorageLogger Error sending batch API - {e!s}")
|
||||
verbose_logger.exception(f"AzureBlobStorageLogger Error sending batch API - {e}")
|
||||
|
||||
async def async_upload_payload_to_azure_blob_storage(self, payload: StandardLoggingPayload):
|
||||
"""
|
||||
|
|
@ -153,7 +151,7 @@ class AzureBlobStorageLogger(CustomBatchLogger):
|
|||
verbose_logger.debug(f"Successfully uploaded log to Azure Blob Storage: {filename}")
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error uploading to Azure Blob Storage: {e!s}")
|
||||
verbose_logger.exception(f"Error uploading to Azure Blob Storage: {e}")
|
||||
raise e
|
||||
|
||||
async def _create_file(self, client: AsyncHTTPHandler, base_url: str):
|
||||
|
|
@ -169,7 +167,7 @@ class AzureBlobStorageLogger(CustomBatchLogger):
|
|||
response.raise_for_status()
|
||||
verbose_logger.debug("Successfully created file resource")
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error creating file resource: {e!s}")
|
||||
verbose_logger.exception(f"Error creating file resource: {e}")
|
||||
raise
|
||||
|
||||
async def _append_data(self, client: AsyncHTTPHandler, base_url: str, json_payload: str):
|
||||
|
|
@ -189,7 +187,7 @@ class AzureBlobStorageLogger(CustomBatchLogger):
|
|||
response.raise_for_status()
|
||||
verbose_logger.debug("Successfully appended data")
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error appending data: {e!s}")
|
||||
verbose_logger.exception(f"Error appending data: {e}")
|
||||
raise
|
||||
|
||||
async def _flush_data(self, client: AsyncHTTPHandler, base_url: str, position: int):
|
||||
|
|
@ -205,7 +203,7 @@ class AzureBlobStorageLogger(CustomBatchLogger):
|
|||
response.raise_for_status()
|
||||
verbose_logger.debug("Successfully flushed data")
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error flushing data: {e!s}")
|
||||
verbose_logger.exception(f"Error flushing data: {e}")
|
||||
raise
|
||||
|
||||
####### Helper methods to managing Authentication to Azure Storage #######
|
||||
|
|
@ -345,4 +343,4 @@ class AzureBlobStorageLogger(CustomBatchLogger):
|
|||
verbose_logger.debug(f"Successfully uploaded and wrote to {today}/{file_name}")
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error occurred: {e!s}")
|
||||
verbose_logger.exception(f"Error occurred: {e}")
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ class CloudZeroLogger(CustomLogger):
|
|||
verbose_logger.debug(f"CloudZero Logger: Successfully exported {len(cbf_data)} records to CloudZero")
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"CloudZero Logger: Error exporting usage data: {e!s}")
|
||||
verbose_logger.error(f"CloudZero Logger: Error exporting usage data: {e}")
|
||||
raise
|
||||
|
||||
async def dry_run_export_usage_data(self, limit: int | None = 10000):
|
||||
|
|
@ -244,8 +244,8 @@ class CloudZeroLogger(CustomLogger):
|
|||
}
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"CloudZero Logger: Error in dry run export: {e!s}")
|
||||
verbose_logger.error(f"CloudZero Dry Run Error: {e!s}")
|
||||
verbose_logger.error(f"CloudZero Logger: Error in dry run export: {e}")
|
||||
verbose_logger.error(f"CloudZero Dry Run Error: {e}")
|
||||
raise
|
||||
|
||||
def _display_cbf_data_on_screen(self, cbf_data):
|
||||
|
|
|
|||
|
|
@ -98,4 +98,4 @@ class LiteLLMDatabase:
|
|||
# This prevents schema mismatch errors when data types vary across rows
|
||||
return pl.DataFrame(db_response, infer_schema_length=None)
|
||||
except Exception as e:
|
||||
raise Exception(f"Error retrieving usage data: {e!s}")
|
||||
raise Exception(f"Error retrieving usage data: {e}")
|
||||
|
|
|
|||
|
|
@ -927,7 +927,7 @@ class CustomLogger: # https://docs.litellm.ai/docs/observability/custom_callbac
|
|||
except Exception as e:
|
||||
from litellm._logging import verbose_logger
|
||||
|
||||
verbose_logger.debug(f"Error in handle_callback_failure for {callback_name}: {e!s}")
|
||||
verbose_logger.debug(f"Error in handle_callback_failure for {callback_name}: {e}")
|
||||
|
||||
async def _strip_base64_from_messages(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ class DataDogLogger(
|
|||
batch_size=_resolve_dd_batch_size(),
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Datadog: Got exception on init Datadog client {e!s}")
|
||||
verbose_logger.exception(f"Datadog: Got exception on init Datadog client {e}")
|
||||
raise e
|
||||
|
||||
def _get_datadog_params(self) -> dict:
|
||||
|
|
@ -257,7 +257,7 @@ class DataDogLogger(
|
|||
await self._log_async_event(kwargs, response_obj, start_time, end_time)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Datadog Layer Error - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"Datadog Layer Error - {e}\n{traceback.format_exc()}")
|
||||
|
||||
async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time):
|
||||
try:
|
||||
|
|
@ -265,7 +265,7 @@ class DataDogLogger(
|
|||
await self._log_async_event(kwargs, response_obj, start_time, end_time)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Datadog Layer Error - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"Datadog Layer Error - {e}\n{traceback.format_exc()}")
|
||||
|
||||
async def async_post_call_failure_hook(
|
||||
self,
|
||||
|
|
@ -340,7 +340,7 @@ class DataDogLogger(
|
|||
if len(self.log_queue) >= self.batch_size:
|
||||
await self.flush_queue()
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Datadog: async_post_call_failure_hook - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"Datadog: async_post_call_failure_hook - {e}\n{traceback.format_exc()}")
|
||||
return None
|
||||
|
||||
async def async_send_batch(self):
|
||||
|
|
@ -380,7 +380,7 @@ class DataDogLogger(
|
|||
|
||||
except Exception as e:
|
||||
self.log_queue = batch_to_send + self.log_queue
|
||||
verbose_logger.exception(f"Datadog Error sending batch API - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"Datadog Error sending batch API - {e}\n{traceback.format_exc()}")
|
||||
|
||||
async def _send_with_413_split(self, batch: list) -> list:
|
||||
"""
|
||||
|
|
@ -411,7 +411,7 @@ class DataDogLogger(
|
|||
if isinstance(e, MaskedHTTPStatusError) and e.status_code == 413:
|
||||
response = e.response
|
||||
else:
|
||||
verbose_logger.exception(f"Datadog Error sending batch API - {e!s}")
|
||||
verbose_logger.exception(f"Datadog Error sending batch API - {e}")
|
||||
return self._undelivered(chunk, pending)
|
||||
|
||||
if response.status_code == 413:
|
||||
|
|
@ -515,7 +515,7 @@ class DataDogLogger(
|
|||
)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Datadog Layer Error - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"Datadog Layer Error - {e}\n{traceback.format_exc()}")
|
||||
|
||||
async def _log_async_event(self, kwargs, response_obj, start_time, end_time):
|
||||
dd_payload = self.create_datadog_logging_payload(
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class DatadogCostManagementLogger(CustomBatchLogger):
|
|||
await self.async_send_batch()
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Datadog Cost Management: Error in async_log_success_event: {e!s}")
|
||||
verbose_logger.exception(f"Datadog Cost Management: Error in async_log_success_event: {e}")
|
||||
|
||||
async def async_send_batch(self):
|
||||
if not self.log_queue:
|
||||
|
|
@ -104,7 +104,7 @@ class DatadogCostManagementLogger(CustomBatchLogger):
|
|||
await self._upload_to_datadog(aggregated_entries)
|
||||
except Exception as e:
|
||||
self.log_queue = batch_to_send + self.log_queue
|
||||
verbose_logger.exception(f"Datadog Cost Management: Error in async_send_batch: {e!s}")
|
||||
verbose_logger.exception(f"Datadog Cost Management: Error in async_send_batch: {e}")
|
||||
|
||||
def _aggregate_costs(self, logs: list[StandardLoggingPayload]) -> list[DatadogFOCUSCostEntry]:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ class DataDogLLMObsLogger(CustomBatchLogger):
|
|||
kwargs.update(dict_datadog_llm_obs_params)
|
||||
CustomBatchLogger.__init__(self, **kwargs, flush_lock=self.flush_lock)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"DataDogLLMObs: Error initializing - {e!s}")
|
||||
verbose_logger.exception(f"DataDogLLMObs: Error initializing - {e}")
|
||||
raise e
|
||||
|
||||
def _configure_dd_agent(self, dd_agent_host: str):
|
||||
|
|
@ -145,7 +145,7 @@ class DataDogLLMObsLogger(CustomBatchLogger):
|
|||
if len(self.log_queue) >= self.batch_size:
|
||||
await self.async_send_batch()
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"DataDogLLMObs: Error logging success event - {e!s}")
|
||||
verbose_logger.exception(f"DataDogLLMObs: Error logging success event - {e}")
|
||||
|
||||
async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time):
|
||||
try:
|
||||
|
|
@ -157,7 +157,7 @@ class DataDogLLMObsLogger(CustomBatchLogger):
|
|||
if len(self.log_queue) >= self.batch_size:
|
||||
await self.async_send_batch()
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"DataDogLLMObs: Error logging failure event - {e!s}")
|
||||
verbose_logger.exception(f"DataDogLLMObs: Error logging failure event - {e}")
|
||||
|
||||
async def async_send_batch(self):
|
||||
try:
|
||||
|
|
@ -214,7 +214,7 @@ class DataDogLLMObsLogger(CustomBatchLogger):
|
|||
except httpx.HTTPStatusError as e:
|
||||
verbose_logger.exception(f"DataDogLLMObs: Error sending batch - {e.response.text}")
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"DataDogLLMObs: Error sending batch - {e!s}")
|
||||
verbose_logger.exception(f"DataDogLLMObs: Error sending batch - {e}")
|
||||
|
||||
def create_llm_obs_payload(self, kwargs: dict, start_time: datetime, end_time: datetime) -> LLMObsPayload:
|
||||
standard_logging_payload: StandardLoggingPayload | None = kwargs.get("standard_logging_object")
|
||||
|
|
@ -707,7 +707,7 @@ class DataDogLLMObsLogger(CustomBatchLogger):
|
|||
|
||||
kv_pairs[f"tool_calls.{idx}.function.arguments"] = json.dumps(function_arguments)
|
||||
except (KeyError, TypeError, ValueError) as e:
|
||||
verbose_logger.debug(f"DataDogLLMObs: Error processing tool call {idx}: {e!s}")
|
||||
verbose_logger.debug(f"DataDogLLMObs: Error processing tool call {idx}: {e}")
|
||||
continue
|
||||
|
||||
return kv_pairs
|
||||
|
|
@ -747,6 +747,6 @@ class DataDogLLMObsLogger(CustomBatchLogger):
|
|||
tool_call_metadata[f"output_{key}"] = value
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"DataDogLLMObs: Error extracting tool call metadata: {e!s}")
|
||||
verbose_logger.debug(f"DataDogLLMObs: Error extracting tool call metadata: {e}")
|
||||
|
||||
return tool_call_metadata
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ class DatadogMetricsLogger(CustomBatchLogger):
|
|||
await self.flush_queue()
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Datadog Metrics: Error in async_log_success_event: {e!s}")
|
||||
verbose_logger.exception(f"Datadog Metrics: Error in async_log_success_event: {e}")
|
||||
|
||||
async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time):
|
||||
try:
|
||||
|
|
@ -202,7 +202,7 @@ class DatadogMetricsLogger(CustomBatchLogger):
|
|||
await self.flush_queue()
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Datadog Metrics: Error in async_log_failure_event: {e!s}")
|
||||
verbose_logger.exception(f"Datadog Metrics: Error in async_log_failure_event: {e}")
|
||||
|
||||
async def async_send_batch(self):
|
||||
if not self.log_queue:
|
||||
|
|
@ -214,7 +214,7 @@ class DatadogMetricsLogger(CustomBatchLogger):
|
|||
try:
|
||||
await self._upload_to_datadog(payload_data)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Datadog Metrics: Error in async_send_batch: {e!s}")
|
||||
verbose_logger.exception(f"Datadog Metrics: Error in async_send_batch: {e}")
|
||||
raise
|
||||
|
||||
async def _upload_to_datadog(self, payload: DatadogMetricsPayload):
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class DyanmoDBLogger:
|
|||
# Assuming log_data is a dictionary with log information
|
||||
response = table.put_item(Item=payload)
|
||||
|
||||
print_verbose(f"Response from DynamoDB:{response!s}")
|
||||
print_verbose(f"Response from DynamoDB:{response}")
|
||||
|
||||
print_verbose(f"DynamoDB Layer Logging - final response object: {response_obj}")
|
||||
return response
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ class GalileoObserve(CustomLogger):
|
|||
except Exception as e:
|
||||
return IntegrationHealthCheckStatus(
|
||||
status="unhealthy",
|
||||
error_message=f"Galileo health check failed: {e!s}",
|
||||
error_message=f"Galileo health check failed: {e}",
|
||||
)
|
||||
|
||||
async def async_set_galileo_headers(self) -> None:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ class GCSBucketLogger(GCSBucketBase, AdditionalLoggingUtils):
|
|||
await self.log_queue.put(GCSLogQueueItem(payload=logging_payload, kwargs=kwargs, response_obj=response_obj))
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"GCS Bucket logging error: {e!s}")
|
||||
verbose_logger.exception(f"GCS Bucket logging error: {e}")
|
||||
|
||||
async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time):
|
||||
try:
|
||||
|
|
@ -95,7 +95,7 @@ class GCSBucketLogger(GCSBucketBase, AdditionalLoggingUtils):
|
|||
await self.log_queue.put(GCSLogQueueItem(payload=logging_payload, kwargs=kwargs, response_obj=response_obj))
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"GCS Bucket logging error: {e!s}")
|
||||
verbose_logger.exception(f"GCS Bucket logging error: {e}")
|
||||
|
||||
def _drain_queue_batch(self) -> list[GCSLogQueueItem]:
|
||||
"""
|
||||
|
|
@ -218,7 +218,7 @@ class GCSBucketLogger(GCSBucketBase, AdditionalLoggingUtils):
|
|||
except Exception as e:
|
||||
success_count = 0
|
||||
error_count = len(items)
|
||||
verbose_logger.exception(f"GCS Bucket error logging batch payload to GCS bucket: {e!s}")
|
||||
verbose_logger.exception(f"GCS Bucket error logging batch payload to GCS bucket: {e}")
|
||||
return (success_count, error_count)
|
||||
|
||||
async def _send_individual_logs(self, items: list[GCSLogQueueItem]) -> None:
|
||||
|
|
@ -255,7 +255,7 @@ class GCSBucketLogger(GCSBucketBase, AdditionalLoggingUtils):
|
|||
logging_payload=item["payload"],
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"GCS Bucket error logging individual payload to GCS bucket: {e!s}")
|
||||
verbose_logger.exception(f"GCS Bucket error logging individual payload to GCS bucket: {e}")
|
||||
|
||||
async def async_send_batch(self):
|
||||
"""
|
||||
|
|
@ -336,7 +336,7 @@ class GCSBucketLogger(GCSBucketBase, AdditionalLoggingUtils):
|
|||
loaded_response = json.loads(response)
|
||||
return loaded_response
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"Failed to fetch payload for date {date_str}: {e!s}")
|
||||
verbose_logger.debug(f"Failed to fetch payload for date {date_str}: {e}")
|
||||
continue
|
||||
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ class GcsPubSubLogger(CustomBatchLogger):
|
|||
await self.async_send_batch()
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"PubSub Layer Error - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"PubSub Layer Error - {e}\n{traceback.format_exc()}")
|
||||
|
||||
async def async_send_batch(self):
|
||||
"""
|
||||
|
|
@ -148,7 +148,7 @@ class GcsPubSubLogger(CustomBatchLogger):
|
|||
await self.publish_message(message)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"PubSub Error sending batch - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"PubSub Error sending batch - {e}\n{traceback.format_exc()}")
|
||||
finally:
|
||||
self.log_queue.clear()
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ def load_compatible_callbacks() -> dict:
|
|||
with open(json_path, "r") as f:
|
||||
return json.load(f)
|
||||
except Exception as e:
|
||||
verbose_logger.warning(f"Error loading generic_api_compatible_callbacks.json: {e!s}")
|
||||
verbose_logger.warning(f"Error loading generic_api_compatible_callbacks.json: {e}")
|
||||
return {}
|
||||
|
||||
|
||||
|
|
@ -214,7 +214,7 @@ class GenericAPILogger(CustomBatchLogger):
|
|||
key, value = item.split("=", 1)
|
||||
headers_dict[key.strip()] = value.strip()
|
||||
except Exception as e:
|
||||
verbose_logger.warning(f"Error parsing headers from environment variables: {e!s}")
|
||||
verbose_logger.warning(f"Error parsing headers from environment variables: {e}")
|
||||
|
||||
# 2. Update with litellm generic headers if available
|
||||
if litellm.generic_logger_headers:
|
||||
|
|
@ -308,7 +308,7 @@ class GenericAPILogger(CustomBatchLogger):
|
|||
await self.async_send_batch()
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Generic API Logger Error - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"Generic API Logger Error - {e}\n{traceback.format_exc()}")
|
||||
|
||||
async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time):
|
||||
"""
|
||||
|
|
@ -339,7 +339,7 @@ class GenericAPILogger(CustomBatchLogger):
|
|||
await self.async_send_batch()
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Generic API Logger Error - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"Generic API Logger Error - {e}\n{traceback.format_exc()}")
|
||||
|
||||
async def async_send_batch(self):
|
||||
"""
|
||||
|
|
@ -395,7 +395,7 @@ class GenericAPILogger(CustomBatchLogger):
|
|||
)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Generic API Logger Error sending batch - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"Generic API Logger Error sending batch - {e}\n{traceback.format_exc()}")
|
||||
finally:
|
||||
self.log_queue.clear()
|
||||
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ class LangFuseLogger:
|
|||
|
||||
return {"trace_id": trace_id, "generation_id": generation_id}
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Langfuse Layer Error(): Exception occured - {e!s}")
|
||||
verbose_logger.exception(f"Langfuse Layer Error(): Exception occured - {e}")
|
||||
return {"trace_id": None, "generation_id": None}
|
||||
|
||||
def _get_langfuse_input_output_content(
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ class LangfusePromptManagement(LangFuseLogger, PromptManagementBase, CustomLogge
|
|||
except Exception as e:
|
||||
from litellm._logging import verbose_logger
|
||||
|
||||
verbose_logger.exception(f"Langfuse Layer Error - Exception occurred while logging success event: {e!s}")
|
||||
verbose_logger.exception(f"Langfuse Layer Error - Exception occurred while logging success event: {e}")
|
||||
self.handle_callback_failure(callback_name="langfuse")
|
||||
|
||||
async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time):
|
||||
|
|
@ -347,5 +347,5 @@ class LangfusePromptManagement(LangFuseLogger, PromptManagementBase, CustomLogge
|
|||
except Exception as e:
|
||||
from litellm._logging import verbose_logger
|
||||
|
||||
verbose_logger.exception(f"Langfuse Layer Error - Exception occurred while logging failure event: {e!s}")
|
||||
verbose_logger.exception(f"Langfuse Layer Error - Exception occurred while logging failure event: {e}")
|
||||
self.handle_callback_failure(callback_name="langfuse")
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class LogfireLogger:
|
|||
if logfire.DEFAULT_LOGFIRE_INSTANCE.config.send_to_logfire:
|
||||
logfire.configure(token=os.getenv("LOGFIRE_TOKEN"))
|
||||
except Exception as e:
|
||||
print_verbose(f"Got exception on init logfire client {e!s}")
|
||||
print_verbose(f"Got exception on init logfire client {e}")
|
||||
raise e
|
||||
|
||||
def _get_span_config(self, payload) -> SpanConfig:
|
||||
|
|
@ -159,4 +159,4 @@ class LogfireLogger:
|
|||
|
||||
print_verbose(f"Logfire Layer Logging - final response object: {response_obj}")
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"Logfire Layer Error - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.debug(f"Logfire Layer Error - {e}\n{traceback.format_exc()}")
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ class OpikLogger(CustomBatchLogger):
|
|||
self.flush_lock: asyncio.Lock | None = asyncio.Lock()
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"OpikLogger - Asynchronous processing not initialized as we are not running in an async context {e!s}"
|
||||
f"OpikLogger - Asynchronous processing not initialized as we are not running in an async context {e}"
|
||||
)
|
||||
self.flush_lock = None
|
||||
|
||||
|
|
@ -161,7 +161,7 @@ class OpikLogger(CustomBatchLogger):
|
|||
verbose_logger.debug("OpikLogger - Flushing batch")
|
||||
await self.flush_queue()
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"OpikLogger failed to log success event - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"OpikLogger failed to log success event - {e}\n{traceback.format_exc()}")
|
||||
|
||||
def _sync_send(self, url: str, headers: dict[str, str], batch: dict[str, Any]) -> None:
|
||||
try:
|
||||
|
|
@ -174,7 +174,7 @@ class OpikLogger(CustomBatchLogger):
|
|||
if response.status_code != 204:
|
||||
raise Exception(f"Response from opik API status_code: {response.status_code}, text: {response.text}")
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"OpikLogger failed to send batch - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"OpikLogger failed to send batch - {e}\n{traceback.format_exc()}")
|
||||
|
||||
def log_success_event(
|
||||
self,
|
||||
|
|
@ -245,7 +245,7 @@ class OpikLogger(CustomBatchLogger):
|
|||
batch={"spans": [span_payload.__dict__]},
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"OpikLogger failed to log success event - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"OpikLogger failed to log success event - {e}\n{traceback.format_exc()}")
|
||||
|
||||
async def _submit_batch(self, url: str, headers: dict[str, str], batch: dict[str, Any]) -> None:
|
||||
try:
|
||||
|
|
@ -261,7 +261,7 @@ class OpikLogger(CustomBatchLogger):
|
|||
else:
|
||||
verbose_logger.info(f"OpikLogger - {len(self.log_queue)} Opik events submitted")
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"OpikLogger failed to send batch - {e!s}")
|
||||
verbose_logger.exception(f"OpikLogger failed to send batch - {e}")
|
||||
|
||||
def _create_opik_headers(self) -> dict[str, str]:
|
||||
headers: dict[str, str] = {}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class PostHogLogger(CustomBatchLogger):
|
|||
super().__init__(**kwargs, flush_lock=None, batch_size=POSTHOG_MAX_BATCH_SIZE)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"PostHog: Got exception on init PostHog client {e!s}")
|
||||
verbose_logger.exception(f"PostHog: Got exception on init PostHog client {e}")
|
||||
raise e
|
||||
|
||||
def log_success_event(self, kwargs, response_obj, start_time, end_time):
|
||||
|
|
@ -107,7 +107,7 @@ class PostHogLogger(CustomBatchLogger):
|
|||
verbose_logger.debug("PostHog: Sync event successfully sent")
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"PostHog Sync Layer Error - {e!s}")
|
||||
verbose_logger.exception(f"PostHog Sync Layer Error - {e}")
|
||||
|
||||
async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):
|
||||
try:
|
||||
|
|
@ -115,7 +115,7 @@ class PostHogLogger(CustomBatchLogger):
|
|||
self._ensure_async_setup() # Lazy initialization
|
||||
await self._log_async_event(kwargs, response_obj, start_time, end_time)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"PostHog Layer Error - {e!s}")
|
||||
verbose_logger.exception(f"PostHog Layer Error - {e}")
|
||||
|
||||
async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time):
|
||||
try:
|
||||
|
|
@ -123,7 +123,7 @@ class PostHogLogger(CustomBatchLogger):
|
|||
self._ensure_async_setup() # Lazy initialization
|
||||
await self._log_async_event(kwargs, response_obj, start_time, end_time)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"PostHog Layer Error - {e!s}")
|
||||
verbose_logger.exception(f"PostHog Layer Error - {e}")
|
||||
|
||||
async def _log_async_event(self, kwargs, response_obj=None, start_time=0.0, end_time=0.0):
|
||||
# Note: response_obj, start_time, end_time not used - all data comes from kwargs
|
||||
|
|
@ -367,7 +367,7 @@ class PostHogLogger(CustomBatchLogger):
|
|||
else:
|
||||
verbose_logger.debug(f"PostHog: Batch of {len(self.log_queue)} events successfully sent")
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"PostHog Error sending batch API - {e!s}")
|
||||
verbose_logger.exception(f"PostHog Error sending batch API - {e}")
|
||||
|
||||
def _ensure_async_setup(self):
|
||||
if not self._async_initialized:
|
||||
|
|
@ -377,7 +377,7 @@ class PostHogLogger(CustomBatchLogger):
|
|||
self._async_initialized = True
|
||||
verbose_logger.debug("PostHog: Async components initialized")
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"PostHog: Failed to initialize async components: {e!s}")
|
||||
verbose_logger.error(f"PostHog: Failed to initialize async components: {e}")
|
||||
raise
|
||||
|
||||
def _extract_metadata(self, kwargs: dict[str, Any]) -> dict[str, Any]:
|
||||
|
|
@ -445,4 +445,4 @@ class PostHogLogger(CustomBatchLogger):
|
|||
self.log_queue.clear()
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"PostHog: Error flushing events on exit: {e!s}")
|
||||
verbose_logger.error(f"PostHog: Error flushing events on exit: {e}")
|
||||
|
|
|
|||
|
|
@ -683,7 +683,7 @@ class PrometheusLogger(CustomLogger):
|
|||
)
|
||||
|
||||
except Exception as e:
|
||||
print_verbose(f"Got exception on init prometheus client {e!s}")
|
||||
print_verbose(f"Got exception on init prometheus client {e}")
|
||||
raise e
|
||||
|
||||
def _parse_prometheus_config(self) -> dict[str, list[str]]:
|
||||
|
|
@ -2132,7 +2132,7 @@ class PrometheusLogger(CustomLogger):
|
|||
response_cost=0,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"prometheus Layer Error(): Exception occured - {e!s}")
|
||||
verbose_logger.exception(f"prometheus Layer Error(): Exception occured - {e}")
|
||||
|
||||
def _extract_status_code(
|
||||
self,
|
||||
|
|
@ -2383,7 +2383,7 @@ class PrometheusLogger(CustomLogger):
|
|||
)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"prometheus Layer Error(): Exception occured - {e!s}")
|
||||
verbose_logger.exception(f"prometheus Layer Error(): Exception occured - {e}")
|
||||
|
||||
async def async_post_call_success_hook(self, data: dict, user_api_key_dict: UserAPIKeyAuth, response):
|
||||
"""
|
||||
|
|
@ -2608,7 +2608,7 @@ class PrometheusLogger(CustomLogger):
|
|||
)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"Prometheus Error: set_llm_deployment_failure_metrics. Exception occured - {e!s}")
|
||||
verbose_logger.debug(f"Prometheus Error: set_llm_deployment_failure_metrics. Exception occured - {e}")
|
||||
|
||||
def _set_deployment_tpm_rpm_limit_metrics(
|
||||
self,
|
||||
|
|
@ -2722,9 +2722,7 @@ class PrometheusLogger(CustomLogger):
|
|||
)
|
||||
self.litellm_remaining_requests_metric.labels(**_labels).set(remaining_requests)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"Prometheus Error: _async_set_router_remaining_metrics. Exception occured - {e!s}"
|
||||
)
|
||||
verbose_logger.exception(f"Prometheus Error: _async_set_router_remaining_metrics. Exception occured - {e}")
|
||||
|
||||
def set_llm_deployment_success_metrics(
|
||||
self,
|
||||
|
|
@ -2867,7 +2865,7 @@ class PrometheusLogger(CustomLogger):
|
|||
self.litellm_deployment_latency_per_output_token.labels(**_labels).observe(latency_per_token)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Prometheus Error: set_llm_deployment_success_metrics. Exception occured - {e!s}")
|
||||
verbose_logger.exception(f"Prometheus Error: set_llm_deployment_success_metrics. Exception occured - {e}")
|
||||
return
|
||||
|
||||
def _record_guardrail_metrics(
|
||||
|
|
@ -2912,7 +2910,7 @@ class PrometheusLogger(CustomLogger):
|
|||
hook_type=hook_type,
|
||||
).inc()
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"Error recording guardrail metrics: {e!s}")
|
||||
verbose_logger.debug(f"Error recording guardrail metrics: {e}")
|
||||
|
||||
########################################
|
||||
# Managed Batch Metric Recording Methods
|
||||
|
|
@ -3315,7 +3313,7 @@ class PrometheusLogger(CustomLogger):
|
|||
await set_metrics_function(data)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error initializing {data_type} budget metrics: {e!s}")
|
||||
verbose_logger.exception(f"Error initializing {data_type} budget metrics: {e}")
|
||||
|
||||
async def _initialize_team_budget_metrics(self):
|
||||
"""
|
||||
|
|
@ -3506,7 +3504,7 @@ class PrometheusLogger(CustomLogger):
|
|||
self.litellm_teams_count_metric.set(total_teams)
|
||||
verbose_logger.debug(f"Prometheus: set litellm_teams_count to {total_teams}")
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error initializing user/team count metrics: {e!s}")
|
||||
verbose_logger.exception(f"Error initializing user/team count metrics: {e}")
|
||||
|
||||
async def _set_key_list_budget_metrics(self, keys: list[str | UserAPIKeyAuth]):
|
||||
"""Helper function to set budget metrics for a list of keys"""
|
||||
|
|
@ -3597,7 +3595,7 @@ class PrometheusLogger(CustomLogger):
|
|||
user_api_key_cache=user_api_key_cache,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"[Non-Blocking] Prometheus: Error getting team info: {e!s}")
|
||||
verbose_logger.debug(f"[Non-Blocking] Prometheus: Error getting team info: {e}")
|
||||
return team_object
|
||||
|
||||
if team_info:
|
||||
|
|
@ -3695,7 +3693,7 @@ class PrometheusLogger(CustomLogger):
|
|||
include_budget_table=True,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"[Non-Blocking] Prometheus: Error getting org info: {e!s}")
|
||||
verbose_logger.debug(f"[Non-Blocking] Prometheus: Error getting org info: {e}")
|
||||
return
|
||||
|
||||
if org_info is None:
|
||||
|
|
@ -3852,7 +3850,7 @@ class PrometheusLogger(CustomLogger):
|
|||
if key_object:
|
||||
user_api_key_dict.budget_reset_at = key_object.budget_reset_at
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"[Non-Blocking] Prometheus: Error getting key info: {e!s}")
|
||||
verbose_logger.debug(f"[Non-Blocking] Prometheus: Error getting key info: {e}")
|
||||
|
||||
return user_api_key_dict
|
||||
|
||||
|
|
@ -3917,7 +3915,7 @@ class PrometheusLogger(CustomLogger):
|
|||
check_db_only=False,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"[Non-Blocking] Prometheus: Error getting user info: {e!s}")
|
||||
verbose_logger.debug(f"[Non-Blocking] Prometheus: Error getting user info: {e}")
|
||||
return user_object
|
||||
|
||||
if user_info:
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class PrometheusServicesLogger:
|
|||
self.mock_testing_failure_calls = 0
|
||||
|
||||
except Exception as e:
|
||||
print_verbose(f"Got exception on init prometheus client {e!s}")
|
||||
print_verbose(f"Got exception on init prometheus client {e}")
|
||||
raise e
|
||||
|
||||
def _get_service_metrics_initialize(self, service: ServiceTypes) -> list[ServiceMetrics]:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -78,7 +78,7 @@ class S3Logger:
|
|||
**kwargs,
|
||||
)
|
||||
except Exception as e:
|
||||
print_verbose(f"Got exception on init s3 client {e!s}")
|
||||
print_verbose(f"Got exception on init s3 client {e}")
|
||||
raise e
|
||||
|
||||
async def _async_log_event(self, kwargs, response_obj, start_time, end_time, print_verbose):
|
||||
|
|
@ -163,12 +163,12 @@ class S3Logger:
|
|||
**sse_params,
|
||||
)
|
||||
|
||||
print_verbose(f"Response from s3:{response!s}")
|
||||
print_verbose(f"Response from s3:{response}")
|
||||
|
||||
print_verbose(f"s3 Layer Logging - final response object: {response_obj}")
|
||||
return response
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"s3 Layer Error - {e!s}")
|
||||
verbose_logger.exception(f"s3 Layer Error - {e}")
|
||||
|
||||
|
||||
def _validated_sse_value(name: str, value: str | None) -> str | None:
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM):
|
|||
BaseAWSLLM.__init__(self)
|
||||
|
||||
except Exception as e:
|
||||
print_verbose(f"Got exception on init s3 client {e!s}")
|
||||
print_verbose(f"Got exception on init s3 client {e}")
|
||||
raise e
|
||||
|
||||
def _init_s3_params(
|
||||
|
|
@ -284,7 +284,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM):
|
|||
self.batch_size,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"s3 Layer Error - {e!s}")
|
||||
verbose_logger.exception(f"s3 Layer Error - {e}")
|
||||
self.handle_callback_failure(callback_name="S3Logger")
|
||||
|
||||
async def async_upload_data_to_s3(self, batch_logging_element: s3BatchLoggingElement):
|
||||
|
|
@ -383,7 +383,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM):
|
|||
response.raise_for_status()
|
||||
break
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error uploading to s3: {e!s}")
|
||||
verbose_logger.exception(f"Error uploading to s3: {e}")
|
||||
self.handle_callback_failure(callback_name="S3Logger")
|
||||
|
||||
async def async_send_batch(self):
|
||||
|
|
@ -557,7 +557,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM):
|
|||
response.raise_for_status()
|
||||
break
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error uploading to s3: {e!s}")
|
||||
verbose_logger.exception(f"Error uploading to s3: {e}")
|
||||
self.handle_callback_failure(callback_name="S3Logger")
|
||||
|
||||
async def _download_object_from_s3(self, s3_object_key: str) -> dict | None:
|
||||
|
|
@ -642,7 +642,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM):
|
|||
return response.json()
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error downloading from S3: {e!s}")
|
||||
verbose_logger.exception(f"Error downloading from S3: {e}")
|
||||
return None
|
||||
|
||||
async def get_proxy_server_request_from_cold_storage_with_object_key(
|
||||
|
|
@ -666,5 +666,5 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM):
|
|||
downloaded_object = await self._download_object_from_s3(object_key)
|
||||
return downloaded_object
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error retrieving object {object_key} from cold storage: {e!s}")
|
||||
verbose_logger.exception(f"Error retrieving object {object_key} from cold storage: {e}")
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ class SQSLogger(CustomBatchLogger, BaseAWSLLM):
|
|||
BaseAWSLLM.__init__(self)
|
||||
|
||||
except Exception as e:
|
||||
print_verbose(f"Got exception on init sqs client {e!s}")
|
||||
print_verbose(f"Got exception on init sqs client {e}")
|
||||
raise e
|
||||
|
||||
def _init_sqs_params(
|
||||
|
|
@ -215,7 +215,7 @@ class SQSLogger(CustomBatchLogger, BaseAWSLLM):
|
|||
self.batch_size,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"sqs Layer Error - {e!s}")
|
||||
verbose_logger.exception(f"sqs Layer Error - {e}")
|
||||
|
||||
async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time):
|
||||
try:
|
||||
|
|
@ -233,7 +233,7 @@ class SQSLogger(CustomBatchLogger, BaseAWSLLM):
|
|||
)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Datadog Layer Error - {e!s}\n{traceback.format_exc()}")
|
||||
verbose_logger.exception(f"Datadog Layer Error - {e}\n{traceback.format_exc()}")
|
||||
|
||||
async def async_send_batch(self) -> None:
|
||||
verbose_logger.debug(f"sqs logger - sending batch of {len(self.log_queue)}")
|
||||
|
|
@ -305,7 +305,7 @@ class SQSLogger(CustomBatchLogger, BaseAWSLLM):
|
|||
)
|
||||
response.raise_for_status()
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error sending to SQS: {e!s}")
|
||||
verbose_logger.exception(f"Error sending to SQS: {e}")
|
||||
|
||||
async def async_health_check(self) -> IntegrationHealthCheckStatus:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ class VectorStorePreCallHook(CustomLogger):
|
|||
return model, modified_messages, non_default_params
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error in VectorStorePreCallHook: {e!s}")
|
||||
verbose_logger.exception(f"Error in VectorStorePreCallHook: {e}")
|
||||
# Return original parameters on error
|
||||
return model, messages, non_default_params
|
||||
|
||||
|
|
@ -275,7 +275,7 @@ class VectorStorePreCallHook(CustomLogger):
|
|||
return response
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error adding search results to response: {e!s}")
|
||||
verbose_logger.exception(f"Error adding search results to response: {e}")
|
||||
# Don't fail the request if search results fail to be added
|
||||
return None
|
||||
|
||||
|
|
@ -322,6 +322,6 @@ class VectorStorePreCallHook(CustomLogger):
|
|||
return response_chunk
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error adding search results to streaming chunk: {e!s}")
|
||||
verbose_logger.exception(f"Error adding search results to streaming chunk: {e}")
|
||||
# Don't fail the request if search results fail to be added
|
||||
return response_chunk
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ class WebSearchInterceptionLogger(CustomLogger):
|
|||
content.append({"type": "text", "text": search_result_text})
|
||||
|
||||
response: dict[str, object] = {
|
||||
"id": f"msg_{uuid.uuid4()!s}",
|
||||
"id": f"msg_{uuid.uuid4()}",
|
||||
"type": "message",
|
||||
"role": "assistant",
|
||||
"model": model,
|
||||
|
|
@ -1038,8 +1038,8 @@ class WebSearchInterceptionLogger(CustomLogger):
|
|||
@staticmethod
|
||||
def _extract_search_text(result: object) -> str:
|
||||
if isinstance(result, Exception):
|
||||
verbose_logger.error(f"WebSearchInterception: Responses search failed with error: {result!s}")
|
||||
return f"Search failed: {result!s}"
|
||||
verbose_logger.error(f"WebSearchInterception: Responses search failed with error: {result}")
|
||||
return f"Search failed: {result}"
|
||||
if isinstance(result, tuple) and len(result) == 2:
|
||||
text_value, _ = result
|
||||
return text_value if isinstance(text_value, str) else str(text_value)
|
||||
|
|
@ -1194,8 +1194,8 @@ class WebSearchInterceptionLogger(CustomLogger):
|
|||
structured_results: list[SearchResponse | None] = []
|
||||
for i, result in enumerate(search_results):
|
||||
if isinstance(result, Exception):
|
||||
verbose_logger.error(f"WebSearchInterception: Search {i} failed with error: {result!s}")
|
||||
final_search_results.append(f"Search failed: {result!s}")
|
||||
verbose_logger.error(f"WebSearchInterception: Search {i} failed with error: {result}")
|
||||
final_search_results.append(f"Search failed: {result}")
|
||||
structured_results.append(None)
|
||||
elif isinstance(result, tuple) and len(result) == 2:
|
||||
text_value, structured_value = result
|
||||
|
|
@ -1308,7 +1308,7 @@ class WebSearchInterceptionLogger(CustomLogger):
|
|||
)
|
||||
return search_result_text, result
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"WebSearchInterception: Search failed for '{query}': {e!s}")
|
||||
verbose_logger.error(f"WebSearchInterception: Search failed for '{query}': {e}")
|
||||
raise
|
||||
|
||||
async def _authorize_search_tool(
|
||||
|
|
@ -1486,8 +1486,8 @@ class WebSearchInterceptionLogger(CustomLogger):
|
|||
final_search_results: list[str] = []
|
||||
for i, result in enumerate(search_results):
|
||||
if isinstance(result, Exception):
|
||||
verbose_logger.error(f"WebSearchInterception: Search {i} failed with error: {result!s}")
|
||||
final_search_results.append(f"Search failed: {result!s}")
|
||||
verbose_logger.error(f"WebSearchInterception: Search {i} failed with error: {result}")
|
||||
final_search_results.append(f"Search failed: {result}")
|
||||
elif isinstance(result, tuple) and len(result) == 2:
|
||||
text_value, _ = result
|
||||
final_search_results.append(cast(str, text_value) if isinstance(text_value, str) else str(text_value))
|
||||
|
|
|
|||
|
|
@ -679,7 +679,7 @@ def _map_replicate_exception(
|
|||
)
|
||||
raise APIError(
|
||||
status_code=500,
|
||||
message=f"ReplicateException - {original_exception!s}",
|
||||
message=f"ReplicateException - {original_exception}",
|
||||
llm_provider="replicate",
|
||||
model=model,
|
||||
request=httpx.Request(
|
||||
|
|
@ -2459,7 +2459,7 @@ def exception_type( # type: ignore
|
|||
): # deal with edge-case invalid request error bug in openai-python sdk
|
||||
exception_mapping_worked = True
|
||||
raise BadRequestError(
|
||||
message=f"{exception_provider} BadRequestError : This can happen due to missing AZURE_API_VERSION: {original_exception!s}",
|
||||
message=f"{exception_provider} BadRequestError : This can happen due to missing AZURE_API_VERSION: {original_exception}",
|
||||
model=model,
|
||||
llm_provider=custom_llm_provider,
|
||||
response=getattr(original_exception, "response", None),
|
||||
|
|
@ -2478,7 +2478,7 @@ def exception_type( # type: ignore
|
|||
)
|
||||
else:
|
||||
raise APIConnectionError(
|
||||
message=f"{original_exception!s}\n{_redact_string(traceback.format_exc())}",
|
||||
message=f"{original_exception}\n{_redact_string(traceback.format_exc())}",
|
||||
llm_provider=custom_llm_provider,
|
||||
model=model,
|
||||
request=httpx.Request(method="POST", url="https://api.openai.com/v1/"), # stub the request
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ async def async_completion_with_fallbacks(**kwargs):
|
|||
)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Fallback attempt failed for model {model}: {e!s}")
|
||||
verbose_logger.exception(f"Fallback attempt failed for model {model}: {e}")
|
||||
most_recent_exception_str = str(e)
|
||||
continue
|
||||
|
||||
|
|
|
|||
|
|
@ -501,9 +501,9 @@ def get_llm_provider(
|
|||
if isinstance(e, litellm.exceptions.BadRequestError):
|
||||
raise e
|
||||
else:
|
||||
error_str = f"GetLLMProvider Exception - {e!s}\n\noriginal model: {model}"
|
||||
error_str = f"GetLLMProvider Exception - {e}\n\noriginal model: {model}"
|
||||
raise litellm.exceptions.BadRequestError( # type: ignore
|
||||
message=f"GetLLMProvider Exception - {e!s}\n\noriginal model: {model}",
|
||||
message=f"GetLLMProvider Exception - {e}\n\noriginal model: {model}",
|
||||
model=model,
|
||||
response=None,
|
||||
llm_provider="",
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ def get_model_cost_map(url: str) -> dict:
|
|||
str(e),
|
||||
)
|
||||
_cost_map_source_info.source = "local"
|
||||
_cost_map_source_info.fallback_reason = f"Remote fetch failed: {e!s}"
|
||||
_cost_map_source_info.fallback_reason = f"Remote fetch failed: {e}"
|
||||
return _finalize_model_cost_map(GetModelCostMap.load_local_model_cost_map())
|
||||
|
||||
# Validate using cached count (cheap int comparison, no file I/O)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from collections.abc import Iterator
|
||||
from collections.abc import Iterator, Mapping
|
||||
from typing import Any
|
||||
|
||||
from litellm.types.utils import StandardCallbackDynamicParams
|
||||
from litellm.types.utils import TRUSTED_CALLBACK_VARS_FIELD, StandardCallbackDynamicParams
|
||||
|
||||
_CLIENT_CALLBACK_METADATA_SLOTS: tuple[str, ...] = ("litellm_metadata", "metadata")
|
||||
|
||||
|
|
@ -75,14 +75,32 @@ _supported_callback_params = [
|
|||
"turn_off_message_logging",
|
||||
]
|
||||
|
||||
_request_blocked_callback_params = {
|
||||
"gcs_bucket_name",
|
||||
"gcs_path_service_account",
|
||||
"dd_api_key",
|
||||
"dd_site",
|
||||
"dd_agent_host",
|
||||
"dd_agent_port",
|
||||
}
|
||||
_request_blocked_callback_params = frozenset(
|
||||
{
|
||||
"gcs_bucket_name",
|
||||
"gcs_path_service_account",
|
||||
"dd_api_key",
|
||||
"dd_site",
|
||||
"dd_agent_host",
|
||||
"dd_agent_port",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def get_trusted_callback_params(kwargs: Mapping[str, Any] | None) -> tuple[tuple[str, str], ...]:
|
||||
"""
|
||||
Read callback params the proxy itself stamped from admin-configured team/key callback settings.
|
||||
|
||||
Request-body values never reach this field: the proxy strips it from client input before
|
||||
setting it, so callbacks can consume credentials and destinations here without re-validating.
|
||||
|
||||
Returned as pairs rather than a mapping because the caller keeps this on the Logging object,
|
||||
which the proxy deep-copies; a mappingproxy is not copyable and a dict would be mutable.
|
||||
"""
|
||||
trusted_vars = kwargs.get(TRUSTED_CALLBACK_VARS_FIELD) if kwargs else None
|
||||
if not isinstance(trusted_vars, Mapping):
|
||||
return ()
|
||||
return tuple((key, str(value)) for key, value in trusted_vars.items() if isinstance(key, str))
|
||||
|
||||
|
||||
def initialize_standard_callback_dynamic_params(
|
||||
|
|
|
|||
|
|
@ -166,6 +166,9 @@ from ..integrations.s3_v2 import S3Logger as S3V2Logger
|
|||
from ..integrations.supabase import Supabase
|
||||
from ..integrations.traceloop import TraceloopLogger
|
||||
from .exception_mapping_utils import _get_response_headers
|
||||
from .initialize_dynamic_callback_params import (
|
||||
get_trusted_callback_params,
|
||||
)
|
||||
from .initialize_dynamic_callback_params import (
|
||||
initialize_standard_callback_dynamic_params as _initialize_standard_callback_dynamic_params,
|
||||
)
|
||||
|
|
@ -199,7 +202,7 @@ try:
|
|||
EnterpriseStandardLoggingPayloadSetup
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"[Non-Blocking] Unable to import GenericAPILogger - LiteLLM Enterprise Feature - {e!s}")
|
||||
verbose_logger.debug(f"[Non-Blocking] Unable to import GenericAPILogger - LiteLLM Enterprise Feature - {e}")
|
||||
GenericAPILogger = CustomLogger # type: ignore
|
||||
ResendEmailLogger = CustomLogger # type: ignore
|
||||
SendGridEmailLogger = CustomLogger # type: ignore
|
||||
|
|
@ -362,6 +365,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
self.standard_callback_dynamic_params: StandardCallbackDynamicParams = (
|
||||
self.initialize_standard_callback_dynamic_params(kwargs)
|
||||
)
|
||||
self._trusted_callback_vars: tuple[tuple[str, str], ...] = get_trusted_callback_params(kwargs)
|
||||
|
||||
# Process dynamic callbacks (after standard_callback_dynamic_params is initialized,
|
||||
# so team-scoped credentials are available for callback initialization)
|
||||
|
|
@ -459,9 +463,10 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
# pass only the relevant dynamic params as custom_logger_init_args.
|
||||
_custom_logger_init_args: dict | None = None
|
||||
if callback == "datadog":
|
||||
_custom_logger_init_args = {
|
||||
k: v for k, v in self.standard_callback_dynamic_params.items() if k.startswith("dd_")
|
||||
}
|
||||
# dd_* params are blocked from standard_callback_dynamic_params
|
||||
# (request-level security); only the proxy-stamped team/key
|
||||
# callback vars are admin-configured and trusted.
|
||||
_custom_logger_init_args = {k: v for k, v in self._trusted_callback_vars if k.startswith("dd_")}
|
||||
|
||||
callback_class = _init_custom_logger_compatible_class(
|
||||
callback, # type: ignore[arg-type]
|
||||
|
|
@ -968,7 +973,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
error=str(e),
|
||||
)
|
||||
_metadata["raw_request"] = f"Unable to Log \
|
||||
raw request: {e!s}"
|
||||
raw request: {e}"
|
||||
if getattr(self, "logger_fn", None) and callable(self.logger_fn):
|
||||
try:
|
||||
self.logger_fn(
|
||||
|
|
@ -976,7 +981,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
) # Expectation: any logger function passed in by the user should accept a dict object
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while logging {e!s}"
|
||||
f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while logging {e}"
|
||||
)
|
||||
|
||||
self.model_call_details["api_call_start_time"] = datetime.datetime.now()
|
||||
|
|
@ -1036,14 +1041,14 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
callback_func=callback,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"litellm.Logging.pre_call(): Exception occured - {e!s}")
|
||||
verbose_logger.exception(f"litellm.Logging.pre_call(): Exception occured - {e}")
|
||||
verbose_logger.debug(
|
||||
f"LiteLLM.Logging: is sentry capture exception initialized {capture_exception}"
|
||||
)
|
||||
if capture_exception: # log this error to sentry for debugging
|
||||
capture_exception(e)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while logging {e!s}")
|
||||
verbose_logger.exception(f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while logging {e}")
|
||||
verbose_logger.error(f"LiteLLM.Logging: is sentry capture exception initialized {capture_exception}")
|
||||
if capture_exception: # log this error to sentry for debugging
|
||||
capture_exception(e)
|
||||
|
|
@ -1159,7 +1164,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
) # Expectation: any logger function passed in by the user should accept a dict object
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while logging {e!s}"
|
||||
f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while logging {e}"
|
||||
)
|
||||
original_response = redact_message_input_output_from_logging(
|
||||
model_call_details=(self.model_call_details if hasattr(self, "model_call_details") else {}),
|
||||
|
|
@ -1196,7 +1201,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while post-call logging with integrations {e!s}"
|
||||
f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while post-call logging with integrations {e}"
|
||||
)
|
||||
verbose_logger.debug(
|
||||
f"LiteLLM.Logging: is sentry capture exception initialized {capture_exception}"
|
||||
|
|
@ -1204,7 +1209,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
if capture_exception: # log this error to sentry for debugging
|
||||
capture_exception(e)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while logging {e!s}")
|
||||
verbose_logger.exception(f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while logging {e}")
|
||||
|
||||
async def async_post_mcp_tool_call_hook(
|
||||
self,
|
||||
|
|
@ -1244,7 +1249,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
if response is not None:
|
||||
response_obj = self._parse_post_mcp_call_hook_response(response=response)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while logging {e!s}")
|
||||
verbose_logger.exception(f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while logging {e}")
|
||||
return response_obj
|
||||
|
||||
def _parse_post_mcp_call_hook_response(self, response: MCPPostCallResponseObject | None) -> Any:
|
||||
|
|
@ -1889,7 +1894,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
|
||||
return start_time, end_time, result
|
||||
except Exception as e:
|
||||
raise Exception(f"[Non-Blocking] LiteLLM.Success_Call Error: {e!s}")
|
||||
raise Exception(f"[Non-Blocking] LiteLLM.Success_Call Error: {e}")
|
||||
|
||||
def _is_recognized_call_type_for_logging(
|
||||
self,
|
||||
|
|
@ -2378,7 +2383,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
pass
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while success logging {e!s}",
|
||||
f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while success logging {e}",
|
||||
)
|
||||
|
||||
async def async_success_handler(self, result=None, start_time=None, end_time=None, cache_hit=None, **kwargs):
|
||||
|
|
@ -2694,7 +2699,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
break # Only increment once
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"Error in _handle_callback_failure: {e!s}")
|
||||
verbose_logger.debug(f"Error in _handle_callback_failure: {e}")
|
||||
|
||||
def _failure_handler_helper_fn(self, exception, traceback_exception, start_time=None, end_time=None):
|
||||
if start_time is None:
|
||||
|
|
@ -2931,14 +2936,14 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
|
||||
except Exception as e:
|
||||
print_verbose(
|
||||
f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while failure logging with integrations {e!s}"
|
||||
f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while failure logging with integrations {e}"
|
||||
)
|
||||
print_verbose(f"LiteLLM.Logging: is sentry capture exception initialized {capture_exception}")
|
||||
if capture_exception: # log this error to sentry for debugging
|
||||
capture_exception(e)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while failure logging {e!s}"
|
||||
f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while failure logging {e}"
|
||||
)
|
||||
|
||||
async def async_failure_handler(self, exception, traceback_exception, start_time=None, end_time=None):
|
||||
|
|
@ -2995,7 +3000,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"LiteLLM.LoggingError: [Non-Blocking] Exception occurred while failure \
|
||||
logging {e!s}\nCallback={callback}"
|
||||
logging {e}\nCallback={callback}"
|
||||
)
|
||||
# Track callback logging failures in Prometheus
|
||||
self._handle_callback_failure(callback=callback)
|
||||
|
|
@ -5426,7 +5431,7 @@ def get_standard_logging_object_payload(
|
|||
|
||||
return payload
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error creating standard logging object - {e!s}")
|
||||
verbose_logger.exception(f"Error creating standard logging object - {e}")
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ def _generic_cost_per_character(
|
|||
prompt_cost = prompt_characters * custom_prompt_cost
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"litellm.litellm_core_utils.llm_cost_calc.utils.py::cost_per_character(): Exception occured - {e!s}\nDefaulting to None"
|
||||
f"litellm.litellm_core_utils.llm_cost_calc.utils.py::cost_per_character(): Exception occured - {e}\nDefaulting to None"
|
||||
)
|
||||
|
||||
prompt_cost = None
|
||||
|
|
@ -165,7 +165,7 @@ def _generic_cost_per_character(
|
|||
completion_cost = completion_characters * custom_completion_cost
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"litellm.litellm_core_utils.llm_cost_calc.utils.py::cost_per_character(): Exception occured - {e!s}\nDefaulting to None"
|
||||
f"litellm.litellm_core_utils.llm_cost_calc.utils.py::cost_per_character(): Exception occured - {e}\nDefaulting to None"
|
||||
)
|
||||
|
||||
completion_cost = None
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ def get_api_base(model: str, optional_params: dict | LiteLLM_Params) -> str | No
|
|||
api_key=_optional_params.api_key,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"Error occurred in getting api base - {e!s}")
|
||||
verbose_logger.debug(f"Error occurred in getting api base - {e}")
|
||||
custom_llm_provider = None
|
||||
dynamic_api_base = None
|
||||
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ def _get_parent_otel_span_from_logging_obj(
|
|||
return _get_parent_otel_span_from_kwargs(logging_obj.model_call_details)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error in _get_parent_otel_span_from_logging_obj: {e!s}")
|
||||
verbose_logger.exception(f"Error in _get_parent_otel_span_from_logging_obj: {e}")
|
||||
return None
|
||||
|
||||
|
||||
|
|
@ -265,7 +265,7 @@ def _set_duration_in_model_call_details(
|
|||
else:
|
||||
verbose_logger.debug("`logging_obj` not found - unable to track `llm_api_duration_ms")
|
||||
except Exception as e:
|
||||
verbose_logger.warning(f"Error setting `llm_api_duration_ms`: {e!s}")
|
||||
verbose_logger.warning(f"Error setting `llm_api_duration_ms`: {e}")
|
||||
|
||||
|
||||
def track_llm_api_timing():
|
||||
|
|
@ -321,7 +321,7 @@ def track_llm_api_timing():
|
|||
)
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"Error in service logging: {e!s}")
|
||||
verbose_logger.debug(f"Error in service logging: {e}")
|
||||
|
||||
@functools.wraps(func)
|
||||
def sync_wrapper(*args, **kwargs):
|
||||
|
|
@ -366,7 +366,7 @@ def track_llm_api_timing():
|
|||
parent_otel_span=parent_otel_span,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"Error in service logging: {e!s}")
|
||||
verbose_logger.debug(f"Error in service logging: {e}")
|
||||
|
||||
# Check if the function is async or sync
|
||||
if inspect.iscoroutinefunction(func):
|
||||
|
|
|
|||
|
|
@ -1683,7 +1683,7 @@ def parse_tool_call_arguments(
|
|||
if context:
|
||||
error_parts.append(f"({context})")
|
||||
|
||||
error_message = " ".join(error_parts) + f". Error: {original_error!s}. Arguments: {arguments}"
|
||||
error_message = " ".join(error_parts) + f". Error: {original_error}. Arguments: {arguments}"
|
||||
|
||||
raise ValueError(error_message) from original_error
|
||||
|
||||
|
|
|
|||
|
|
@ -438,9 +438,7 @@ def _render_chat_template(env, chat_template: str, bos_token: str, eos_token: st
|
|||
|
||||
return rendered_text
|
||||
except Exception as e:
|
||||
raise Exception(
|
||||
f"Error rendering template - {e!s}"
|
||||
) # don't use verbose_logger.exception, if exception is raised
|
||||
raise Exception(f"Error rendering template - {e}") # don't use verbose_logger.exception, if exception is raised
|
||||
|
||||
|
||||
async def _afetch_and_extract_template(
|
||||
|
|
@ -858,7 +856,7 @@ def convert_to_anthropic_image_obj(openai_image_url: str, format: str | None) ->
|
|||
raise
|
||||
except Exception as e:
|
||||
raise Exception(
|
||||
f"""Image url not in expected format. Example Expected input - "image_url": "data:image/jpeg;base64,{{base64_image}}". Supported formats - ['image/jpeg', 'image/png', 'image/gif', 'image/webp']. Error: {e!s}"""
|
||||
f"""Image url not in expected format. Example Expected input - "image_url": "data:image/jpeg;base64,{{base64_image}}". Supported formats - ['image/jpeg', 'image/png', 'image/gif', 'image/webp']. Error: {e}"""
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -1361,7 +1359,7 @@ def convert_to_gemini_tool_call_invoke(
|
|||
)
|
||||
return _parts_list
|
||||
except Exception as e:
|
||||
raise Exception(f"Unable to convert openai tool calls={message} to gemini tool calls. Received error={e!s}")
|
||||
raise Exception(f"Unable to convert openai tool calls={message} to gemini tool calls. Received error={e}")
|
||||
|
||||
|
||||
def convert_to_gemini_tool_call_result(
|
||||
|
|
@ -3713,7 +3711,7 @@ def _convert_to_bedrock_tool_call_invoke(
|
|||
_parts_list.append(cache_point_block)
|
||||
return _parts_list
|
||||
except Exception as e:
|
||||
raise Exception(f"Unable to convert openai tool calls={tool_calls} to bedrock tool calls. Received error={e!s}")
|
||||
raise Exception(f"Unable to convert openai tool calls={tool_calls} to bedrock tool calls. Received error={e}")
|
||||
|
||||
|
||||
def _append_bedrock_tool_result_media_block(
|
||||
|
|
|
|||
|
|
@ -618,7 +618,7 @@ class CustomStreamWrapper:
|
|||
else:
|
||||
return ""
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"litellm.CustomStreamWrapper.handle_baseten_chunk(): Exception occured - {e!s}")
|
||||
verbose_logger.exception(f"litellm.CustomStreamWrapper.handle_baseten_chunk(): Exception occured - {e}")
|
||||
return ""
|
||||
|
||||
def handle_triton_stream(self, chunk):
|
||||
|
|
@ -1179,7 +1179,7 @@ class CustomStreamWrapper:
|
|||
content=None,
|
||||
tool_calls=[
|
||||
{
|
||||
"id": f"call_{uuid.uuid4()!s}",
|
||||
"id": f"call_{uuid.uuid4()}",
|
||||
"function": {
|
||||
"arguments": args_str,
|
||||
"name": function_call.name,
|
||||
|
|
@ -1204,7 +1204,7 @@ class CustomStreamWrapper:
|
|||
)
|
||||
except Exception:
|
||||
if chunk.candidates[0].finish_reason.name == "SAFETY": # type: ignore
|
||||
raise Exception(f"The response was blocked by VertexAI. {chunk!s}")
|
||||
raise Exception(f"The response was blocked by VertexAI. {chunk}")
|
||||
else:
|
||||
completion_obj["content"] = str(chunk)
|
||||
elif self.custom_llm_provider == "petals":
|
||||
|
|
@ -1430,7 +1430,7 @@ class CustomStreamWrapper:
|
|||
model_response.choices[0].delta = Delta(**_json_delta)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"litellm.CustomStreamWrapper.chunk_creator(): Exception occured - {e!s}"
|
||||
f"litellm.CustomStreamWrapper.chunk_creator(): Exception occured - {e}"
|
||||
)
|
||||
model_response.choices[0].delta = Delta()
|
||||
elif self._has_any_special_delta_attributes(delta):
|
||||
|
|
@ -1538,7 +1538,7 @@ class CustomStreamWrapper:
|
|||
except Exception as e:
|
||||
from litellm._logging import verbose_logger
|
||||
|
||||
verbose_logger.exception(f"Error in post-call streaming deployment hook: {e!s}")
|
||||
verbose_logger.exception(f"Error in post-call streaming deployment hook: {e}")
|
||||
return chunk
|
||||
|
||||
def _add_mcp_list_tools_to_first_chunk(self, chunk: ModelResponseStream) -> ModelResponseStream:
|
||||
|
|
@ -1578,7 +1578,7 @@ class CustomStreamWrapper:
|
|||
except Exception as e:
|
||||
from litellm._logging import verbose_logger
|
||||
|
||||
verbose_logger.exception(f"Error adding MCP list tools to first chunk: {e!s}")
|
||||
verbose_logger.exception(f"Error adding MCP list tools to first chunk: {e}")
|
||||
|
||||
return chunk
|
||||
|
||||
|
|
@ -1615,7 +1615,7 @@ class CustomStreamWrapper:
|
|||
except Exception as e:
|
||||
from litellm._logging import verbose_logger
|
||||
|
||||
verbose_logger.exception(f"Error adding MCP metadata to final chunk: {e!s}")
|
||||
verbose_logger.exception(f"Error adding MCP metadata to final chunk: {e}")
|
||||
|
||||
return chunk
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ def get_modified_max_tokens(
|
|||
return user_max_tokens
|
||||
except Exception as e:
|
||||
verbose_logger.debug(
|
||||
f"litellm.litellm_core_utils.token_counter.py::get_modified_max_tokens() - Error while checking max token limit: {e!s}\nmodel={model}, base_model={base_model}"
|
||||
f"litellm.litellm_core_utils.token_counter.py::get_modified_max_tokens() - Error while checking max token limit: {e}\nmodel={model}, base_model={base_model}"
|
||||
)
|
||||
return user_max_tokens
|
||||
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ class A2AConfig(BaseConfig):
|
|||
except Exception as e:
|
||||
raise A2AError(
|
||||
status_code=raw_response.status_code,
|
||||
message=f"Failed to parse A2A response: {e!s}",
|
||||
message=f"Failed to parse A2A response: {e}",
|
||||
headers=dict(raw_response.headers),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1875,7 +1875,7 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
|||
except Exception as e:
|
||||
raise AnthropicError(
|
||||
status_code=400,
|
||||
message=f"{e!s}\nReceived Messages={messages}",
|
||||
message=f"{e}\nReceived Messages={messages}",
|
||||
) # don't use verbose_logger.exception, if exception is raised
|
||||
|
||||
## Auto-strip advisor blocks from history if advisor tool is absent.
|
||||
|
|
@ -2454,7 +2454,7 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
|||
except Exception as e:
|
||||
response_headers = getattr(raw_response, "headers", None)
|
||||
raise AnthropicError(
|
||||
message=f"Unable to get json response - {e!s}, Original Response: {raw_response.text}",
|
||||
message=f"Unable to get json response - {e}, Original Response: {raw_response.text}",
|
||||
status_code=raw_response.status_code,
|
||||
headers=response_headers,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -109,14 +109,14 @@ class AnthropicCountTokensHandler(AnthropicCountTokensConfig):
|
|||
raise
|
||||
except httpx.HTTPStatusError as e:
|
||||
# HTTP errors - preserve the actual status code
|
||||
verbose_logger.error(f"HTTP error in CountTokens handler: {e!s}")
|
||||
verbose_logger.error(f"HTTP error in CountTokens handler: {e}")
|
||||
raise AnthropicError(
|
||||
status_code=e.response.status_code,
|
||||
message=e.response.text,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"Error in CountTokens handler: {e!s}")
|
||||
verbose_logger.error(f"Error in CountTokens handler: {e}")
|
||||
raise AnthropicError(
|
||||
status_code=500,
|
||||
message=f"CountTokens processing error: {e!s}",
|
||||
message=f"CountTokens processing error: {e}",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -684,7 +684,7 @@ class AzureChatCompletion(BaseAzureLLM, BaseLLM):
|
|||
except json.JSONDecodeError as json_error:
|
||||
raise AzureOpenAIError(
|
||||
status_code=raw_response.status_code or 500,
|
||||
message=f"Failed to parse raw Azure embedding response: {json_error!s}",
|
||||
message=f"Failed to parse raw Azure embedding response: {json_error}",
|
||||
) from json_error
|
||||
if isinstance(response, str):
|
||||
raise AzureOpenAIError(
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ def get_azure_ad_token(
|
|||
verbose_logger.debug("Azure AD Token Provider could not be used.")
|
||||
except Exception as e:
|
||||
verbose_logger.error(
|
||||
f"Error calling Azure AD token provider: {e!s}. Follow docs - https://docs.litellm.ai/docs/providers/azure/#azure-ad-token-refresh---defaultazurecredential"
|
||||
f"Error calling Azure AD token provider: {e}. Follow docs - https://docs.litellm.ai/docs/providers/azure/#azure-ad-token-refresh---defaultazurecredential"
|
||||
)
|
||||
raise e
|
||||
|
||||
|
|
@ -359,8 +359,8 @@ def get_azure_ad_token(
|
|||
# Re-raise TypeError directly
|
||||
raise
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"Error calling Azure AD token provider: {e!s}")
|
||||
raise RuntimeError(f"Failed to get Azure AD token: {e!s}") from e
|
||||
verbose_logger.error(f"Error calling Azure AD token provider: {e}")
|
||||
raise RuntimeError(f"Failed to get Azure AD token: {e}") from e
|
||||
|
||||
return azure_ad_token
|
||||
|
||||
|
|
@ -393,7 +393,7 @@ class BaseAzureLLM(BaseOpenAILLM):
|
|||
verbose_logger.debug("Successfully obtained Azure AD token provider using DefaultAzureCredential")
|
||||
return azure_ad_token_provider
|
||||
except Exception as e:
|
||||
verbose_logger.debug(f"DefaultAzureCredential failed: {e!s}")
|
||||
verbose_logger.debug(f"DefaultAzureCredential failed: {e}")
|
||||
return None
|
||||
|
||||
def get_azure_openai_client(
|
||||
|
|
@ -508,6 +508,8 @@ class BaseAzureLLM(BaseOpenAILLM):
|
|||
openai_client=openai_client,
|
||||
client_initialization_params=client_initialization_params,
|
||||
client_type="azure",
|
||||
litellm_owned_client=client is None
|
||||
and self.owns_wrapped_http_client(azure_client_params.get("http_client")),
|
||||
)
|
||||
return openai_client
|
||||
|
||||
|
|
@ -580,7 +582,7 @@ class BaseAzureLLM(BaseOpenAILLM):
|
|||
# only show first 5 chars of api_key
|
||||
_api_key = _api_key[:8] + "*" * 15
|
||||
verbose_logger.debug(
|
||||
f"Initializing Azure OpenAI Client for {model_name}, Api Base: {api_base!s}, Api Key:{_api_key}"
|
||||
f"Initializing Azure OpenAI Client for {model_name}, Api Base: {api_base}, Api Key:{_api_key}"
|
||||
)
|
||||
azure_client_params = {
|
||||
"api_key": api_key,
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ class AzureAIAgentsHandler:
|
|||
),
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.warning(f"Failed to calculate token usage: {e!s}")
|
||||
verbose_logger.warning(f"Failed to calculate token usage: {e}")
|
||||
|
||||
return model_response
|
||||
|
||||
|
|
|
|||
|
|
@ -114,14 +114,14 @@ class AzureAIAnthropicCountTokensHandler(AzureAIAnthropicCountTokensConfig):
|
|||
raise
|
||||
except httpx.HTTPStatusError as e:
|
||||
# HTTP errors - preserve the actual status code
|
||||
verbose_logger.error(f"HTTP error in CountTokens handler: {e!s}")
|
||||
verbose_logger.error(f"HTTP error in CountTokens handler: {e}")
|
||||
raise AnthropicError(
|
||||
status_code=e.response.status_code,
|
||||
message=e.response.text,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"Error in CountTokens handler: {e!s}")
|
||||
verbose_logger.error(f"Error in CountTokens handler: {e}")
|
||||
raise AnthropicError(
|
||||
status_code=500,
|
||||
message=f"CountTokens processing error: {e!s}",
|
||||
message=f"CountTokens processing error: {e}",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ class AzureAIVectorStoreConfig(BaseVectorStoreConfig, BaseAzureLLM):
|
|||
)
|
||||
query_vector = embedding_response.data[0]["embedding"]
|
||||
except Exception as e:
|
||||
raise Exception(f"Failed to generate embedding for query: {e!s}")
|
||||
raise Exception(f"Failed to generate embedding for query: {e}")
|
||||
|
||||
# Azure AI Search endpoint for search
|
||||
index_name = vector_store_id # vector_store_id is the index name
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ class AzureBlobStorageBackend(BaseFileStorageBackend, AzureBlobStorageLogger):
|
|||
return storage_url
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error uploading file to Azure Blob Storage: {e!s}")
|
||||
verbose_logger.exception(f"Error uploading file to Azure Blob Storage: {e}")
|
||||
raise
|
||||
|
||||
async def _upload_file_with_account_key(self, file_content: bytes, full_path: str) -> str:
|
||||
|
|
@ -247,7 +247,7 @@ class AzureBlobStorageBackend(BaseFileStorageBackend, AzureBlobStorageLogger):
|
|||
return await self._download_file_with_azure_ad(file_path)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error downloading file from Azure Blob Storage: {e!s}")
|
||||
verbose_logger.exception(f"Error downloading file from Azure Blob Storage: {e}")
|
||||
raise
|
||||
|
||||
async def _download_file_with_account_key(self, file_path: str) -> bytes:
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ class AmazonAgentCoreConfig(BaseConfig, BaseAWSLLM):
|
|||
return session_id
|
||||
|
||||
# Generate a session ID with 33+ characters
|
||||
generated_id = f"litellm-session-{uuid.uuid4()!s}"
|
||||
generated_id = f"litellm-session-{uuid.uuid4()}"
|
||||
verbose_logger.debug(f"Generated new session ID: {generated_id}")
|
||||
return generated_id
|
||||
|
||||
|
|
@ -370,7 +370,7 @@ class AmazonAgentCoreConfig(BaseConfig, BaseAWSLLM):
|
|||
total_tokens=total_tokens,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.warning(f"Failed to calculate token usage: {e!s}")
|
||||
verbose_logger.warning(f"Failed to calculate token usage: {e}")
|
||||
return None
|
||||
|
||||
def _parse_json_response(self, response_json: dict) -> AgentCoreParsedResponse:
|
||||
|
|
@ -1023,9 +1023,9 @@ class AmazonAgentCoreConfig(BaseConfig, BaseAWSLLM):
|
|||
return model_response
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"Error processing Bedrock AgentCore response: {e!s}")
|
||||
verbose_logger.error(f"Error processing Bedrock AgentCore response: {e}")
|
||||
raise BedrockError(
|
||||
message=f"Error processing response: {e!s}",
|
||||
message=f"Error processing response: {e}",
|
||||
status_code=raw_response.status_code,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -2073,7 +2073,7 @@ class AmazonConverseConfig(BaseConfig):
|
|||
completion_response = ConverseResponseBlock(**response.json()) # type: ignore
|
||||
except Exception as e:
|
||||
raise BedrockError(
|
||||
message=f"Error converting to valid response block={e!s}. File an issue if litellm error - https://github.com/BerriAI/litellm/issues",
|
||||
message=f"Error converting to valid response block={e}. File an issue if litellm error - https://github.com/BerriAI/litellm/issues",
|
||||
status_code=422,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -464,9 +464,9 @@ class AmazonInvokeAgentConfig(BaseConfig, BaseAWSLLM):
|
|||
)
|
||||
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"Error processing Bedrock Invoke Agent response: {e!s}")
|
||||
verbose_logger.error(f"Error processing Bedrock Invoke Agent response: {e}")
|
||||
raise BedrockError(
|
||||
message=f"Error processing response: {e!s}",
|
||||
message=f"Error processing response: {e}",
|
||||
status_code=raw_response.status_code,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -590,7 +590,7 @@ class AWSEventStreamDecoder:
|
|||
|
||||
return response
|
||||
except Exception as e:
|
||||
raise Exception(f"Received streaming error - {e!s}")
|
||||
raise Exception(f"Received streaming error - {e}")
|
||||
|
||||
def _chunk_parser(self, chunk_data: dict) -> Union[GChunk, ModelResponseStream, dict]:
|
||||
text = ""
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ class AmazonTwelveLabsPegasusConfig(AmazonInvokeConfig, BaseConfig):
|
|||
completion_response = raw_response.json()
|
||||
except Exception as e:
|
||||
raise BedrockError(
|
||||
message=f"Error parsing response: {raw_response.text}, error: {e!s}",
|
||||
message=f"Error parsing response: {raw_response.text}, error: {e}",
|
||||
status_code=raw_response.status_code,
|
||||
)
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ class AmazonTwelveLabsPegasusConfig(AmazonInvokeConfig, BaseConfig):
|
|||
raise Exception("Unable to set message content")
|
||||
except Exception as e:
|
||||
raise BedrockError(
|
||||
message=f"Error setting response content: {e!s}. Response: {completion_response}",
|
||||
message=f"Error setting response content: {e}. Response: {completion_response}",
|
||||
status_code=raw_response.status_code,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ class AmazonInvokeConfig(BaseConfig, BaseAWSLLM):
|
|||
outputText = completion_response.get("results")[0].get("outputText")
|
||||
except Exception as e:
|
||||
raise BedrockError(
|
||||
message=f"Error processing={raw_response.text}, Received error={e!s}",
|
||||
message=f"Error processing={raw_response.text}, Received error={e}",
|
||||
status_code=422,
|
||||
)
|
||||
|
||||
|
|
@ -379,7 +379,7 @@ class AmazonInvokeConfig(BaseConfig, BaseAWSLLM):
|
|||
raise Exception()
|
||||
except Exception as e:
|
||||
raise BedrockError(
|
||||
message=f"Error parsing received text={outputText}.\nError-{e!s}",
|
||||
message=f"Error parsing received text={outputText}.\nError-{e}",
|
||||
status_code=raw_response.status_code,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -120,14 +120,14 @@ class BedrockCountTokensHandler(BedrockCountTokensConfig):
|
|||
raise
|
||||
except httpx.HTTPStatusError as e:
|
||||
# HTTP errors - preserve the actual status code
|
||||
verbose_logger.error(f"HTTP error in CountTokens handler: {e!s}")
|
||||
verbose_logger.error(f"HTTP error in CountTokens handler: {e}")
|
||||
raise BedrockError(
|
||||
status_code=e.response.status_code,
|
||||
message=e.response.text,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"Error in CountTokens handler: {e!s}")
|
||||
verbose_logger.error(f"Error in CountTokens handler: {e}")
|
||||
raise BedrockError(
|
||||
status_code=500,
|
||||
message=f"CountTokens processing error: {e!s}",
|
||||
message=f"CountTokens processing error: {e}",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ class BedrockFilesHandler(BaseAWSLLM):
|
|||
response = s3_client.get_object(Bucket=bucket_name, Key=object_key)
|
||||
file_content = response["Body"].read()
|
||||
except Exception as e:
|
||||
raise ValueError(f"Failed to download file from S3: {s3_uri}. Error: {e!s}")
|
||||
raise ValueError(f"Failed to download file from S3: {s3_uri}. Error: {e}")
|
||||
|
||||
# Create mock HTTP response
|
||||
mock_response = httpx.Response(
|
||||
|
|
|
|||
|
|
@ -652,7 +652,7 @@ class BedrockFilesConfig(BaseAWSLLM, BaseFilesConfig):
|
|||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(
|
||||
f"litellm.llms.bedrock.files.transformation.py::_transform_openai_jsonl_content_to_bedrock_jsonl_content() - Error inferring custom_llm_provider - {e!s}"
|
||||
f"litellm.llms.bedrock.files.transformation.py::_transform_openai_jsonl_content_to_bedrock_jsonl_content() - Error inferring custom_llm_provider - {e}"
|
||||
)
|
||||
|
||||
# Determine provider from model name
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ class BedrockRealtime(BaseAWSLLM):
|
|||
except Exception as e:
|
||||
verbose_proxy_logger.exception(f"Error in BedrockRealtime.async_realtime: {e}")
|
||||
try:
|
||||
await websocket.close(code=1011, reason=_redact_string(f"Internal error: {e!s}"))
|
||||
await websocket.close(code=1011, reason=_redact_string(f"Internal error: {e}"))
|
||||
except Exception:
|
||||
pass
|
||||
raise
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ class BlackForestLabsImageEdit:
|
|||
except Exception as e:
|
||||
raise BlackForestLabsError(
|
||||
status_code=500,
|
||||
message=f"Request failed: {e!s}",
|
||||
message=f"Request failed: {e}",
|
||||
)
|
||||
|
||||
# Poll for result
|
||||
|
|
@ -262,7 +262,7 @@ class BlackForestLabsImageEdit:
|
|||
except Exception as e:
|
||||
raise BlackForestLabsError(
|
||||
status_code=500,
|
||||
message=f"Request failed: {e!s}",
|
||||
message=f"Request failed: {e}",
|
||||
)
|
||||
|
||||
# Poll for result
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ class BlackForestLabsImageGeneration:
|
|||
except Exception as e:
|
||||
raise BlackForestLabsError(
|
||||
status_code=500,
|
||||
message=f"Request failed: {e!s}",
|
||||
message=f"Request failed: {e}",
|
||||
)
|
||||
|
||||
# Poll for result
|
||||
|
|
@ -262,7 +262,7 @@ class BlackForestLabsImageGeneration:
|
|||
except Exception as e:
|
||||
raise BlackForestLabsError(
|
||||
status_code=500,
|
||||
message=f"Request failed: {e!s}",
|
||||
message=f"Request failed: {e}",
|
||||
)
|
||||
|
||||
# Poll for result
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ class ClarifaiConfig(OpenAIGPTConfig):
|
|||
except Exception as e:
|
||||
raise OpenAIError(
|
||||
status_code=raw_response.status_code,
|
||||
message=f"Failed to parse Clarifai response: {e!s}",
|
||||
message=f"Failed to parse Clarifai response: {e}",
|
||||
headers=raw_response.headers,
|
||||
) from e
|
||||
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ class CodestralTextCompletion:
|
|||
)
|
||||
except Exception as e:
|
||||
raise TextCompletionCodestralError(
|
||||
status_code=500, message=f"{e!s}"
|
||||
status_code=500, message=f"{e}"
|
||||
) # don't use verbose_logger.exception, if exception is raised
|
||||
return self.process_text_completion_response(
|
||||
model=model,
|
||||
|
|
|
|||
|
|
@ -1411,6 +1411,7 @@ def get_async_httpx_client(
|
|||
key=_cache_key_name,
|
||||
value=_new_client,
|
||||
ttl=_DEFAULT_TTL_FOR_HTTPX_CLIENTS,
|
||||
litellm_owned_client=True,
|
||||
)
|
||||
return _new_client
|
||||
|
||||
|
|
@ -1456,5 +1457,6 @@ def _get_httpx_client(params: dict | None = None) -> HTTPHandler:
|
|||
key=_cache_key_name,
|
||||
value=_new_client,
|
||||
ttl=_DEFAULT_TTL_FOR_HTTPX_CLIENTS,
|
||||
litellm_owned_client=True,
|
||||
)
|
||||
return _new_client
|
||||
|
|
|
|||
|
|
@ -5659,7 +5659,7 @@ class BaseLLMHTTPHandler:
|
|||
fingerprint=fingerprint,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"LiteLLM.AgenticHookError: Exception in chat completion agentic hooks: {e!s}")
|
||||
verbose_logger.exception(f"LiteLLM.AgenticHookError: Exception in chat completion agentic hooks: {e}")
|
||||
|
||||
# Check if we need to convert response to fake stream for chat completions
|
||||
# This happens when:
|
||||
|
|
@ -5906,7 +5906,7 @@ class BaseLLMHTTPHandler:
|
|||
except Exception as e:
|
||||
verbose_logger.exception(f"Error connecting to backend: {e}")
|
||||
try:
|
||||
await websocket.close(code=1011, reason=_redact_string(f"Internal server error: {e!s}"))
|
||||
await websocket.close(code=1011, reason=_redact_string(f"Internal server error: {e}"))
|
||||
except RuntimeError as close_error:
|
||||
if "already completed" in str(close_error) or "websocket.close" in str(close_error):
|
||||
# The WebSocket is already closed or the response is completed, so we can ignore this error
|
||||
|
|
@ -6303,7 +6303,7 @@ class BaseLLMHTTPHandler:
|
|||
except Exception as e:
|
||||
verbose_logger.exception(f"Error in responses WS: {e}")
|
||||
try:
|
||||
await websocket.close(code=1011, reason=_redact_string(f"Internal server error: {e!s}"))
|
||||
await websocket.close(code=1011, reason=_redact_string(f"Internal server error: {e}"))
|
||||
except RuntimeError as close_error:
|
||||
if "already completed" in str(close_error) or "websocket.close" in str(close_error):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ class DashScopeEmbeddingConfig(BaseEmbeddingConfig):
|
|||
except Exception as e:
|
||||
raise DashScopeError(
|
||||
status_code=raw_response.status_code,
|
||||
message=f"Failed to parse DashScope response as JSON: {e!s}",
|
||||
message=f"Failed to parse DashScope response as JSON: {e}",
|
||||
)
|
||||
|
||||
logging_obj.post_call(
|
||||
|
|
|
|||
|
|
@ -630,7 +630,7 @@ class DatabricksConfig(DatabricksBase, OpenAILikeChatConfig, AnthropicConfig):
|
|||
except Exception as e:
|
||||
response_headers = getattr(raw_response, "headers", None)
|
||||
raise DatabricksException(
|
||||
message=f"Unable to get json response - {e!s}, Original Response: {raw_response.text}",
|
||||
message=f"Unable to get json response - {e}, Original Response: {raw_response.text}",
|
||||
status_code=raw_response.status_code,
|
||||
headers=response_headers,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ class DatabricksBase:
|
|||
except requests.RequestException as e:
|
||||
raise DatabricksException(
|
||||
status_code=500,
|
||||
message=f"OAuth M2M token request failed: {e!s}",
|
||||
message=f"OAuth M2M token request failed: {e}",
|
||||
)
|
||||
|
||||
if response.status_code != 200:
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ class DeepgramAudioTranscriptionConfig(BaseAudioTranscriptionConfig):
|
|||
return response
|
||||
|
||||
except Exception as e:
|
||||
raise ValueError(f"Error transforming Deepgram response: {e!s}\nResponse: {raw_response.text}")
|
||||
raise ValueError(f"Error transforming Deepgram response: {e}\nResponse: {raw_response.text}")
|
||||
|
||||
def _reconstruct_diarized_transcript(self, words: list) -> str:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ class ElevenLabsAudioTranscriptionConfig(BaseAudioTranscriptionConfig):
|
|||
return response
|
||||
|
||||
except Exception as e:
|
||||
raise ValueError(f"Error transforming ElevenLabs response: {e!s}\nResponse: {raw_response.text}")
|
||||
raise ValueError(f"Error transforming ElevenLabs response: {e}\nResponse: {raw_response.text}")
|
||||
|
||||
def get_complete_url(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -542,7 +542,7 @@ class FireworksAIConfig(FireworksAIMixin, OpenAIGPTConfig):
|
|||
except Exception as e:
|
||||
response_headers = getattr(raw_response, "headers", None)
|
||||
raise FireworksAIException(
|
||||
message=f"Unable to get json response - {e!s}, Original Response: {raw_response.text}",
|
||||
message=f"Unable to get json response - {e}, Original Response: {raw_response.text}",
|
||||
status_code=raw_response.status_code,
|
||||
headers=response_headers,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ class FireworksAIRerankConfig(FireworksAIMixin, BaseRerankConfig):
|
|||
raw_response_json = raw_response.json()
|
||||
except Exception as e:
|
||||
raise self.get_error_class(
|
||||
error_message=f"Failed to parse response: {e!s}",
|
||||
error_message=f"Failed to parse response: {e}",
|
||||
status_code=raw_response.status_code,
|
||||
headers=raw_response.headers,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ class GDCGeminiConfig(OpenAILikeChatConfig):
|
|||
AttributeError,
|
||||
) as e:
|
||||
raise litellm.utils.AuthenticationError(
|
||||
message=f"Failed to load service account credentials from api_key: {e!s}",
|
||||
message=f"Failed to load service account credentials from api_key: {e}",
|
||||
llm_provider="gdc",
|
||||
model=model,
|
||||
) from e
|
||||
|
|
|
|||
|
|
@ -155,8 +155,8 @@ class GoogleAIStudioTokenCounter:
|
|||
status_code=e.response.status_code,
|
||||
) from e
|
||||
except httpx.RequestError as e:
|
||||
error_msg = f"Request to Google Gen AI Studio failed: {e!s}"
|
||||
error_msg = f"Request to Google Gen AI Studio failed: {e}"
|
||||
raise litellm.APIConnectionError(message=error_msg, llm_provider="gemini", model=model) from e
|
||||
except Exception as e:
|
||||
error_msg = f"Unexpected error during token counting: {e!s}"
|
||||
error_msg = f"Unexpected error during token counting: {e}"
|
||||
raise Exception(error_msg) from e
|
||||
|
|
|
|||
|
|
@ -190,8 +190,8 @@ class GoogleAIStudioFilesHandler(GeminiModelInfo, BaseFilesConfig):
|
|||
status_details=None,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error parsing file upload response: {e!s}")
|
||||
raise ValueError(f"Error parsing file upload response: {e!s}")
|
||||
verbose_logger.exception(f"Error parsing file upload response: {e}")
|
||||
raise ValueError(f"Error parsing file upload response: {e}")
|
||||
|
||||
def transform_retrieve_file_request(
|
||||
self,
|
||||
|
|
@ -294,8 +294,8 @@ class GoogleAIStudioFilesHandler(GeminiModelInfo, BaseFilesConfig):
|
|||
status_details=(str(response_json.get("error", "")) if gemini_state == "FAILED" else None),
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error parsing file retrieve response: {e!s}")
|
||||
raise ValueError(f"Error parsing file retrieve response: {e!s}")
|
||||
verbose_logger.exception(f"Error parsing file retrieve response: {e}")
|
||||
raise ValueError(f"Error parsing file retrieve response: {e}")
|
||||
|
||||
def transform_delete_file_request(
|
||||
self,
|
||||
|
|
@ -362,8 +362,8 @@ class GoogleAIStudioFilesHandler(GeminiModelInfo, BaseFilesConfig):
|
|||
else:
|
||||
raise ValueError(f"Failed to delete file: {raw_response.text}")
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error parsing file delete response: {e!s}")
|
||||
raise ValueError(f"Error parsing file delete response: {e!s}")
|
||||
verbose_logger.exception(f"Error parsing file delete response: {e}")
|
||||
raise ValueError(f"Error parsing file delete response: {e}")
|
||||
|
||||
def transform_list_files_request(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ class GeminiVectorStoreConfig(BaseVectorStoreConfig):
|
|||
|
||||
except Exception as e:
|
||||
raise self.get_error_class(
|
||||
error_message=f"Failed to parse Gemini response: {e!s}",
|
||||
error_message=f"Failed to parse Gemini response: {e}",
|
||||
status_code=response.status_code,
|
||||
headers=response.headers,
|
||||
)
|
||||
|
|
@ -327,7 +327,7 @@ class GeminiVectorStoreConfig(BaseVectorStoreConfig):
|
|||
|
||||
except Exception as e:
|
||||
raise self.get_error_class(
|
||||
error_message=f"Failed to parse Gemini create response: {e!s}",
|
||||
error_message=f"Failed to parse Gemini create response: {e}",
|
||||
status_code=response.status_code,
|
||||
headers=response.headers,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ def _request_token_sync(
|
|||
except httpx.RequestError as e:
|
||||
raise GigaChatAuthError(
|
||||
status_code=500,
|
||||
message=f"GigaChat authentication request failed: {e!s}",
|
||||
message=f"GigaChat authentication request failed: {e}",
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ async def _request_token_async(
|
|||
except httpx.RequestError as e:
|
||||
raise GigaChatAuthError(
|
||||
status_code=500,
|
||||
message=f"GigaChat authentication request failed: {e!s}",
|
||||
message=f"GigaChat authentication request failed: {e}",
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class Authenticator:
|
|||
verbose_logger.error("Error saving access token to file")
|
||||
return access_token
|
||||
except (GetDeviceCodeError, GetAccessTokenError, RefreshAPIKeyError) as e:
|
||||
verbose_logger.warning(f"Failed attempt {attempt + 1}: {e!s}")
|
||||
verbose_logger.warning(f"Failed attempt {attempt + 1}: {e}")
|
||||
continue
|
||||
|
||||
raise GetAccessTokenError(
|
||||
|
|
@ -100,7 +100,7 @@ class Authenticator:
|
|||
except OSError:
|
||||
verbose_logger.warning("No API key file found or error opening file")
|
||||
except (json.JSONDecodeError, KeyError) as e:
|
||||
verbose_logger.warning(f"Error reading API key from file: {e!s}")
|
||||
verbose_logger.warning(f"Error reading API key from file: {e}")
|
||||
except APIKeyExpiredError:
|
||||
pass # Already logged in the try block
|
||||
|
||||
|
|
@ -117,14 +117,14 @@ class Authenticator:
|
|||
status_code=401,
|
||||
)
|
||||
except OSError as e:
|
||||
verbose_logger.error(f"Error saving API key to file: {e!s}")
|
||||
verbose_logger.error(f"Error saving API key to file: {e}")
|
||||
raise GetAPIKeyError(
|
||||
message=f"Failed to save API key: {e!s}",
|
||||
message=f"Failed to save API key: {e}",
|
||||
status_code=500,
|
||||
)
|
||||
except RefreshAPIKeyError as e:
|
||||
raise GetAPIKeyError(
|
||||
message=f"Failed to refresh API key: {e!s}",
|
||||
message=f"Failed to refresh API key: {e}",
|
||||
status_code=401,
|
||||
)
|
||||
|
||||
|
|
@ -142,7 +142,7 @@ class Authenticator:
|
|||
api_endpoint = endpoints.get("api")
|
||||
return api_endpoint
|
||||
except (OSError, json.JSONDecodeError, KeyError) as e:
|
||||
verbose_logger.warning(f"Error reading API endpoint from file: {e!s}")
|
||||
verbose_logger.warning(f"Error reading API endpoint from file: {e}")
|
||||
return None
|
||||
|
||||
def _refresh_api_key(self) -> dict[str, Any]:
|
||||
|
|
@ -173,9 +173,9 @@ class Authenticator:
|
|||
else:
|
||||
verbose_logger.warning(f"API key response missing token: {response_json}")
|
||||
except httpx.HTTPStatusError as e:
|
||||
verbose_logger.error(f"HTTP error refreshing API key (attempt {attempt + 1}/{max_retries}): {e!s}")
|
||||
verbose_logger.error(f"HTTP error refreshing API key (attempt {attempt + 1}/{max_retries}): {e}")
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"Unexpected error refreshing API key: {e!s}")
|
||||
verbose_logger.error(f"Unexpected error refreshing API key: {e}")
|
||||
|
||||
raise RefreshAPIKeyError(
|
||||
message="Failed to refresh API key after maximum retries",
|
||||
|
|
@ -245,21 +245,21 @@ class Authenticator:
|
|||
|
||||
return resp_json
|
||||
except httpx.HTTPStatusError as e:
|
||||
verbose_logger.error(f"HTTP error getting device code: {e!s}")
|
||||
verbose_logger.error(f"HTTP error getting device code: {e}")
|
||||
raise GetDeviceCodeError(
|
||||
message=f"Failed to get device code: {e!s}",
|
||||
message=f"Failed to get device code: {e}",
|
||||
status_code=400,
|
||||
)
|
||||
except json.JSONDecodeError as e:
|
||||
verbose_logger.error(f"Error decoding JSON response: {e!s}")
|
||||
verbose_logger.error(f"Error decoding JSON response: {e}")
|
||||
raise GetDeviceCodeError(
|
||||
message=f"Failed to decode device code response: {e!s}",
|
||||
message=f"Failed to decode device code response: {e}",
|
||||
status_code=400,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"Unexpected error getting device code: {e!s}")
|
||||
verbose_logger.error(f"Unexpected error getting device code: {e}")
|
||||
raise GetDeviceCodeError(
|
||||
message=f"Failed to get device code: {e!s}",
|
||||
message=f"Failed to get device code: {e}",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
|
|
@ -304,21 +304,21 @@ class Authenticator:
|
|||
else:
|
||||
verbose_logger.warning(f"Unexpected response: {resp_json}")
|
||||
except httpx.HTTPStatusError as e:
|
||||
verbose_logger.error(f"HTTP error polling for access token: {e!s}")
|
||||
verbose_logger.error(f"HTTP error polling for access token: {e}")
|
||||
raise GetAccessTokenError(
|
||||
message=f"Failed to get access token: {e!s}",
|
||||
message=f"Failed to get access token: {e}",
|
||||
status_code=400,
|
||||
)
|
||||
except json.JSONDecodeError as e:
|
||||
verbose_logger.error(f"Error decoding JSON response: {e!s}")
|
||||
verbose_logger.error(f"Error decoding JSON response: {e}")
|
||||
raise GetAccessTokenError(
|
||||
message=f"Failed to decode access token response: {e!s}",
|
||||
message=f"Failed to decode access token response: {e}",
|
||||
status_code=400,
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_logger.error(f"Unexpected error polling for access token: {e!s}")
|
||||
verbose_logger.error(f"Unexpected error polling for access token: {e}")
|
||||
raise GetAccessTokenError(
|
||||
message=f"Failed to get access token: {e!s}",
|
||||
message=f"Failed to get access token: {e}",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue