mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
fix(cloudflare): guard missing account id and migrate legacy /ai/run base
Centralize the OpenAI-compatible api_base default in get_complete_url so it is built in one place instead of being duplicated in main.py. When neither api_base nor CLOUDFLARE_ACCOUNT_ID is set the call now fails fast with a clear error rather than sending a request to a URL containing the literal 'None'. An api_base still pinned to the legacy Workers AI '/ai/run' path is rewritten to the '/ai/v1' OpenAI-compatible endpoint with a deprecation warning, so users who hardcoded the previous default migrate gracefully instead of hitting a silently broken '/ai/run/chat/completions' URL.
This commit is contained in:
parent
1815cc9bee
commit
93add6a43b
3 changed files with 52 additions and 13 deletions
|
|
@ -2,6 +2,7 @@ from typing import List, Optional, Union
|
|||
|
||||
import httpx
|
||||
|
||||
from litellm._logging import verbose_logger
|
||||
from litellm.llms.base_llm.chat.transformation import BaseLLMException
|
||||
from litellm.llms.openai.chat.gpt_transformation import OpenAIGPTConfig
|
||||
from litellm.secret_managers.main import get_secret_str
|
||||
|
|
@ -32,13 +33,8 @@ class CloudflareChatConfig(OpenAIGPTConfig):
|
|||
litellm_params: dict,
|
||||
stream: Optional[bool] = None,
|
||||
) -> str:
|
||||
if api_base is None:
|
||||
account_id = get_secret_str("CLOUDFLARE_ACCOUNT_ID")
|
||||
api_base = (
|
||||
f"https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1"
|
||||
)
|
||||
return super().get_complete_url(
|
||||
api_base=api_base,
|
||||
api_base=self._resolve_api_base(api_base),
|
||||
api_key=api_key,
|
||||
model=model,
|
||||
optional_params=optional_params,
|
||||
|
|
@ -46,6 +42,23 @@ class CloudflareChatConfig(OpenAIGPTConfig):
|
|||
stream=stream,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _resolve_api_base(api_base: Optional[str]) -> str:
|
||||
if api_base is None:
|
||||
account_id = get_secret_str("CLOUDFLARE_ACCOUNT_ID")
|
||||
if account_id is None:
|
||||
raise ValueError(
|
||||
"Missing CLOUDFLARE_ACCOUNT_ID - set CLOUDFLARE_ACCOUNT_ID in the environment or pass api_base explicitly"
|
||||
)
|
||||
return f"https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1"
|
||||
trimmed = api_base.rstrip("/")
|
||||
if trimmed.endswith("/ai/run"):
|
||||
verbose_logger.warning(
|
||||
"Cloudflare api_base ending in '/ai/run' is the legacy Workers AI path and no longer serves OpenAI-compatible requests; rewriting to the '/ai/v1' endpoint"
|
||||
)
|
||||
return f"{trimmed[: -len('/ai/run')]}/ai/v1"
|
||||
return api_base
|
||||
|
||||
def validate_environment(
|
||||
self,
|
||||
headers: dict,
|
||||
|
|
|
|||
|
|
@ -4236,13 +4236,7 @@ def completion( # type: ignore
|
|||
or litellm.api_key
|
||||
or get_secret("CLOUDFLARE_API_KEY")
|
||||
)
|
||||
account_id = get_secret("CLOUDFLARE_ACCOUNT_ID")
|
||||
api_base = (
|
||||
api_base
|
||||
or litellm.api_base
|
||||
or get_secret("CLOUDFLARE_API_BASE")
|
||||
or f"https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1"
|
||||
)
|
||||
api_base = api_base or litellm.api_base or get_secret("CLOUDFLARE_API_BASE")
|
||||
|
||||
custom_prompt_dict = custom_prompt_dict or litellm.custom_prompt_dict
|
||||
response = base_llm_http_handler.completion(
|
||||
|
|
|
|||
|
|
@ -68,6 +68,38 @@ def test_get_complete_url_is_idempotent_for_full_base():
|
|||
)
|
||||
|
||||
|
||||
def test_get_complete_url_raises_when_account_id_and_base_missing(monkeypatch):
|
||||
monkeypatch.delenv("CLOUDFLARE_ACCOUNT_ID", raising=False)
|
||||
config = CloudflareChatConfig()
|
||||
|
||||
with pytest.raises(ValueError, match="Missing CLOUDFLARE_ACCOUNT_ID"):
|
||||
config.get_complete_url(
|
||||
api_base=None,
|
||||
api_key="cf-key",
|
||||
model="@cf/meta/llama-2-7b-chat-int8",
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
)
|
||||
|
||||
|
||||
def test_get_complete_url_migrates_legacy_ai_run_base():
|
||||
config = CloudflareChatConfig()
|
||||
|
||||
url = config.get_complete_url(
|
||||
api_base="https://api.cloudflare.com/client/v4/accounts/acct/ai/run/",
|
||||
api_key="cf-key",
|
||||
model="@cf/meta/llama-2-7b-chat-int8",
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
)
|
||||
|
||||
assert (
|
||||
url
|
||||
== "https://api.cloudflare.com/client/v4/accounts/acct/ai/v1/chat/completions"
|
||||
)
|
||||
assert "/ai/run" not in url
|
||||
|
||||
|
||||
def test_transform_request_passes_tools_through_in_openai_format():
|
||||
config = CloudflareChatConfig()
|
||||
tools = [
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue