From feb392d3854f259e7d98c90050bdf0c5989f5252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Wed, 19 Nov 2025 10:45:03 +0000 Subject: [PATCH 1/3] fix: upgrade boto3 and minor agentcore hardening --- .gitignore | 7 + docker/Dockerfile.dev | 5 +- .../bedrock/chat/agentcore/transformation.py | 8 +- pyproject.toml | 153 +++++++++--------- requirements.txt | 4 +- taplo.toml | 26 +++ 6 files changed, 117 insertions(+), 86 deletions(-) create mode 100644 taplo.toml diff --git a/.gitignore b/.gitignore index aa973201fd15..16ce2f0b08ed 100644 --- a/.gitignore +++ b/.gitignore @@ -100,3 +100,10 @@ update_model_cost_map.py tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server_manager.py litellm/proxy/_experimental/out/guardrails/index.html scripts/test_vertex_ai_search.py +.claude +*claude-flow +.hive-mind +.swarm +/memory +.mcp.json +prompt*.md diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev index f95f540a7a50..4e7f2d611369 100644 --- a/docker/Dockerfile.dev +++ b/docker/Dockerfile.dev @@ -45,8 +45,8 @@ RUN chmod +x docker/build_admin_ui.sh && ./docker/build_admin_ui.sh # Build the package RUN rm -rf dist/* && python -m build -# Install the built package -RUN pip install dist/*.whl +# Install the built package with proxy extras (includes boto3 1.40.73) +RUN pip install $(ls dist/*.whl)[proxy] # Runtime stage FROM $LITELLM_RUNTIME_IMAGE AS runtime @@ -74,6 +74,7 @@ COPY --from=builder /wheels/ /wheels/ COPY --from=builder /app/dist/*.whl . # Install all dependencies in one step with no-cache for smaller image +# Note: *.whl already has proxy extras installed from builder stage RUN pip install --no-cache-dir *.whl /wheels/* --no-index --find-links=/wheels/ && \ rm -f *.whl && \ rm -rf /wheels diff --git a/litellm/llms/bedrock/chat/agentcore/transformation.py b/litellm/llms/bedrock/chat/agentcore/transformation.py index 7c65cad94df0..f18fa4924422 100644 --- a/litellm/llms/bedrock/chat/agentcore/transformation.py +++ b/litellm/llms/bedrock/chat/agentcore/transformation.py @@ -116,8 +116,13 @@ def sign_request( fake_stream: Optional[bool] = None, ) -> Tuple[dict, Optional[bytes]]: # Check if api_key (bearer token) is provided for Cognito authentication - jwt_token = optional_params.get("api_key") + # Priority: api_key parameter first, then optional_params + print(f"[DEBUG sign_request] api_key parameter: {api_key[:50] if api_key else 'NONE'}...") + print(f"[DEBUG sign_request] optional_params.get('api_key'): {optional_params.get('api_key', 'NONE')[:50] if optional_params.get('api_key') else 'NONE'}...") + + jwt_token = api_key or optional_params.get("api_key") if jwt_token: + print(f"[DEBUG sign_request] ✅ USING JWT BEARER TOKEN (NOT AWS SigV4)") verbose_logger.debug( f"AgentCore: Using Bearer token authentication (Cognito/JWT) - token: {jwt_token[:50]}..." ) @@ -127,6 +132,7 @@ def sign_request( return headers, json.dumps(request_data).encode() # Otherwise, use AWS SigV4 authentication + print("[DEBUG sign_request] ❌ NO JWT TOKEN - Falling back to AWS SigV4") verbose_logger.debug("AgentCore: Using AWS SigV4 authentication (IAM)") return self._sign_request( service_name="bedrock-agentcore", diff --git a/pyproject.toml b/pyproject.toml index 4fbdff3328fe..0c9fe085cfc2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,14 +1,11 @@ [tool.poetry] name = "litellm" -version = "1.80.0" +version = "1.79.3" description = "Library to easily interface with LLM API providers" authors = ["BerriAI"] license = "MIT" readme = "README.md" -packages = [ - { include = "litellm" }, - { include = "litellm/py.typed"}, -] +packages = [{ include = "litellm" }, { include = "litellm/py.typed" }] [tool.poetry.urls] homepage = "https://litellm.ai" @@ -19,10 +16,10 @@ documentation = "https://docs.litellm.ai" Documentation = "https://docs.litellm.ai" [tool.poetry.dependencies] -python = ">=3.9,<4.0" +python = ">=3.8.1,<4.0, !=3.9.7" fastuuid = ">=0.13.0" httpx = ">=0.23.0" -openai = ">=2.8.0" +openai = ">=1.99.5" python-dotenv = ">=0.2.0" tiktoken = ">=0.7.0" importlib-metadata = ">=6.8.0" @@ -32,83 +29,81 @@ jinja2 = "^3.1.2" aiohttp = ">=3.10" pydantic = "^2.5.0" jsonschema = "^4.22.0" -numpydoc = {version = "*", optional = true} # used in utils.py - -uvicorn = {version = "^0.29.0", optional = true} -uvloop = {version = "^0.21.0", optional = true, markers="sys_platform != 'win32'"} -gunicorn = {version = "^23.0.0", optional = true} -fastapi = {version = ">=0.120.1", optional = true} -backoff = {version = "*", optional = true} -pyyaml = {version = "^6.0.1", optional = true} -rq = {version = "*", optional = true} -orjson = {version = "^3.9.7", optional = true} -apscheduler = {version = "^3.10.4", optional = true} +numpydoc = { version = "*", optional = true } # used in utils.py + +uvicorn = { version = "^0.29.0", optional = true } +uvloop = { version = "^0.21.0", optional = true, markers = "sys_platform != 'win32'" } +gunicorn = { version = "^23.0.0", optional = true } +fastapi = { version = ">=0.120.1", optional = true } +backoff = { version = "*", optional = true } +pyyaml = { version = "^6.0.1", optional = true } +rq = { version = "*", optional = true } +orjson = { version = "^3.9.7", optional = true } +apscheduler = { version = "^3.10.4", optional = true } fastapi-sso = { version = "^0.16.0", optional = true } PyJWT = { version = "^2.8.0", optional = true } -python-multipart = { version = "^0.0.18", optional = true} -cryptography = {version = "*", optional = true} -prisma = {version = "0.11.0", optional = true} -azure-identity = {version = "^1.15.0", optional = true} -azure-keyvault-secrets = {version = "^4.8.0", optional = true} -azure-storage-blob = {version="^12.25.1", optional=true} -google-cloud-kms = {version = "^2.21.3", optional = true} -google-cloud-iam = {version = "^2.19.1", optional = true} -resend = {version = ">=0.8.0", optional = true} -pynacl = {version = "^1.5.0", optional = true} -websockets = {version = "^13.1.0", optional = true} -boto3 = {version = "1.36.0", optional = true} -redisvl = {version = "^0.4.1", optional = true, markers = "python_version >= '3.9' and python_version < '3.14'"} -mcp = {version = "^1.10.0", optional = true, python = ">=3.10"} -litellm-proxy-extras = {version = "0.4.5", optional = true} -rich = {version = "13.7.1", optional = true} -litellm-enterprise = {version = "0.1.21", optional = true} -diskcache = {version = "^5.6.1", optional = true} -polars = {version = "^1.31.0", optional = true, python = ">=3.10"} -semantic-router = {version = ">=0.1.12", optional = true, python = ">=3.9,<3.14"} -mlflow = {version = ">3.1.4", optional = true, python = ">=3.10"} -soundfile = {version = "^0.12.1", optional = true} +python-multipart = { version = "^0.0.18", optional = true } +cryptography = { version = "*", optional = true } +prisma = { version = "0.11.0", optional = true } +azure-identity = { version = "^1.15.0", optional = true } +azure-keyvault-secrets = { version = "^4.8.0", optional = true } +azure-storage-blob = { version = "^12.25.1", optional = true } +google-cloud-kms = { version = "^2.21.3", optional = true } +google-cloud-iam = { version = "^2.19.1", optional = true } +resend = { version = "^0.8.0", optional = true } +pynacl = { version = "^1.5.0", optional = true } +websockets = { version = "^13.1.0", optional = true } +boto3 = { version = "1.40.76", optional = true } +redisvl = { version = "^0.4.1", optional = true, markers = "python_version >= '3.9' and python_version < '3.14'" } +mcp = { version = "^1.10.0", optional = true, python = ">=3.10" } +litellm-proxy-extras = { version = "0.4.3", optional = true } +rich = { version = "13.7.1", optional = true } +litellm-enterprise = { version = "0.1.20", optional = true } +diskcache = { version = "^5.6.1", optional = true } +polars = { version = "^1.31.0", optional = true, python = ">=3.10" } +semantic-router = { version = "*", optional = true, python = ">=3.9" } +mlflow = { version = ">3.1.4", optional = true, python = ">=3.10" } +soundfile = { version = "^0.12.1", optional = true } [tool.poetry.extras] proxy = [ - "gunicorn", - "uvicorn", - "uvloop", - "fastapi", - "backoff", - "pyyaml", - "rq", - "orjson", - "apscheduler", - "fastapi-sso", - "PyJWT", - "python-multipart", - "cryptography", - "pynacl", - "websockets", - "boto3", - "azure-identity", - "azure-storage-blob", - "mcp", - "litellm-proxy-extras", - "litellm-enterprise", - "rich", - "polars", - "soundfile", + "gunicorn", + "uvicorn", + "uvloop", + "fastapi", + "backoff", + "pyyaml", + "rq", + "orjson", + "apscheduler", + "fastapi-sso", + "PyJWT", + "python-multipart", + "cryptography", + "pynacl", + "websockets", + "boto3", + "azure-identity", + "azure-storage-blob", + "mcp", + "litellm-proxy-extras", + "litellm-enterprise", + "rich", + "polars", + "soundfile", ] extra_proxy = [ - "prisma", - "azure-identity", - "azure-keyvault-secrets", - "google-cloud-kms", - "google-cloud-iam", - "resend", - "redisvl" + "prisma", + "azure-identity", + "azure-keyvault-secrets", + "google-cloud-kms", + "google-cloud-iam", + "resend", + "redisvl", ] -utils = [ - "numpydoc", -] +utils = ["numpydoc"] caching = ["diskcache"] @@ -159,16 +154,12 @@ requires = ["poetry-core", "wheel"] build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "1.80.3" -version_files = [ - "pyproject.toml:^version" -] +version = "1.79.3" +version_files = ["pyproject.toml:^version"] [tool.mypy] plugins = "pydantic.mypy" [tool.pytest.ini_options] asyncio_mode = "auto" -markers = [ - "asyncio: mark test as an asyncio test", -] +markers = ["asyncio: mark test as an asyncio test"] diff --git a/requirements.txt b/requirements.txt index ef8c8b2ee0e2..2ef35c709538 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ uvicorn==0.29.0 # server dep gunicorn==23.0.0 # server dep fastuuid==0.13.5 # for uuid4 uvloop==0.21.0 # uvicorn dep, gives us much better performance under load -boto3==1.36.0 # aws bedrock/sagemaker calls +boto3==1.40.53 # aws bedrock/sagemaker calls (has bedrock-agentcore-control, compatible with aioboto3) redis==5.2.1 # redis caching prisma==0.11.0 # for db mangum==0.17.0 # for aws lambda functions @@ -53,7 +53,7 @@ click==8.1.7 # for proxy cli rich==13.7.1 # for litellm proxy cli jinja2==3.1.6 # for prompt templates aiohttp==3.12.14 # for network calls -aioboto3==13.4.0 # for async sagemaker calls +aioboto3==15.5.0 # for async sagemaker calls (updated to match boto3 1.40.73) tenacity==8.5.0 # for retrying requests, when litellm.num_retries set pydantic==2.10.2 # proxy + openai req. jsonschema==4.22.0 # validating json schema diff --git a/taplo.toml b/taplo.toml new file mode 100644 index 000000000000..720888bfc2f2 --- /dev/null +++ b/taplo.toml @@ -0,0 +1,26 @@ +"$schema" = "https://taplo.tamasfe.dev/schema/config.json" + +[format] +# 4-space indentation to match your existing pyproject.toml +indent_string = " " + +# Long enough to avoid wrapping Poetry dependency blocks +column_width = 120 + +# Keep keys exactly in the order you wrote them +reorder_keys = false + +# Do NOT rewrite arrays (your style mixes inline + multiline arrays) +array_auto_expand = false +array_auto_collapse = false + +# Keep existing style for inline tables (don’t collapse them) +compact_inline_tables = false +compact_arrays = false + +# Ensure newline at EOF +trailing_newline = true + +[format.keys] +# Do not align or normalize keys — keeps Homepage/homepage, Repository/repository as-is +align = false From e8f251f81df2db8cdba8c0f55e7e63a91fb63007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Wed, 19 Nov 2025 11:00:50 +0000 Subject: [PATCH 2/3] fix: revert dockerfile changes --- docker/Dockerfile.dev | 5 ++--- pyproject.toml | 16 ++++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev index 4e7f2d611369..f95f540a7a50 100644 --- a/docker/Dockerfile.dev +++ b/docker/Dockerfile.dev @@ -45,8 +45,8 @@ RUN chmod +x docker/build_admin_ui.sh && ./docker/build_admin_ui.sh # Build the package RUN rm -rf dist/* && python -m build -# Install the built package with proxy extras (includes boto3 1.40.73) -RUN pip install $(ls dist/*.whl)[proxy] +# Install the built package +RUN pip install dist/*.whl # Runtime stage FROM $LITELLM_RUNTIME_IMAGE AS runtime @@ -74,7 +74,6 @@ COPY --from=builder /wheels/ /wheels/ COPY --from=builder /app/dist/*.whl . # Install all dependencies in one step with no-cache for smaller image -# Note: *.whl already has proxy extras installed from builder stage RUN pip install --no-cache-dir *.whl /wheels/* --no-index --find-links=/wheels/ && \ rm -f *.whl && \ rm -rf /wheels diff --git a/pyproject.toml b/pyproject.toml index 0c9fe085cfc2..9cfe54ce7383 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "litellm" -version = "1.79.3" +version = "1.80.0" description = "Library to easily interface with LLM API providers" authors = ["BerriAI"] license = "MIT" @@ -16,10 +16,10 @@ documentation = "https://docs.litellm.ai" Documentation = "https://docs.litellm.ai" [tool.poetry.dependencies] -python = ">=3.8.1,<4.0, !=3.9.7" +python = ">=3.9,<4.0" fastuuid = ">=0.13.0" httpx = ">=0.23.0" -openai = ">=1.99.5" +openai = ">=2.8.0" python-dotenv = ">=0.2.0" tiktoken = ">=0.7.0" importlib-metadata = ">=6.8.0" @@ -50,18 +50,18 @@ azure-keyvault-secrets = { version = "^4.8.0", optional = true } azure-storage-blob = { version = "^12.25.1", optional = true } google-cloud-kms = { version = "^2.21.3", optional = true } google-cloud-iam = { version = "^2.19.1", optional = true } -resend = { version = "^0.8.0", optional = true } +resend = { version = ">=0.8.0", optional = true } pynacl = { version = "^1.5.0", optional = true } websockets = { version = "^13.1.0", optional = true } boto3 = { version = "1.40.76", optional = true } redisvl = { version = "^0.4.1", optional = true, markers = "python_version >= '3.9' and python_version < '3.14'" } mcp = { version = "^1.10.0", optional = true, python = ">=3.10" } -litellm-proxy-extras = { version = "0.4.3", optional = true } +litellm-proxy-extras = { version = "0.4.5", optional = true } rich = { version = "13.7.1", optional = true } -litellm-enterprise = { version = "0.1.20", optional = true } +litellm-enterprise = { version = "0.1.21", optional = true } diskcache = { version = "^5.6.1", optional = true } polars = { version = "^1.31.0", optional = true, python = ">=3.10" } -semantic-router = { version = "*", optional = true, python = ">=3.9" } +semantic-router = { version = ">=0.1.12", optional = true, python = ">=3.9,<3.14" } mlflow = { version = ">3.1.4", optional = true, python = ">=3.10" } soundfile = { version = "^0.12.1", optional = true } @@ -154,7 +154,7 @@ requires = ["poetry-core", "wheel"] build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "1.79.3" +version = "1.80.3" version_files = ["pyproject.toml:^version"] [tool.mypy] From 5b07ad0d2d99479577e02b4c9a62678226ce643e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Wed, 19 Nov 2025 12:02:59 +0000 Subject: [PATCH 3/3] chore: align requirements with pyproject.toml openai dep --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2ef35c709538..a1930492c4e0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ # LITELLM PROXY DEPENDENCIES # anyio==4.8.0 # openai + http req. httpx==0.28.1 -openai==1.99.5 # openai req. +openai==2.8.0 # openai req. fastapi==0.120.1 # server dep starlette==0.49.1 # starlette fastapi dep backoff==2.2.1 # server dep