mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-16 23:41:43 +00:00
Merge 076c710c51 into c2c2a623c0
This commit is contained in:
commit
050c7bf955
3 changed files with 72 additions and 1 deletions
|
|
@ -22,6 +22,18 @@ from litellm.types.router import GenericLiteLLMParams
|
|||
from litellm.types.utils import LlmProviders
|
||||
|
||||
|
||||
def perplexity_uses_agent_api(model: str) -> bool:
|
||||
"""Whether a Perplexity model id names the Agent API rather than the chat endpoint.
|
||||
|
||||
Agent API ids keep their own vendor namespace once litellm's ``perplexity/`` prefix is
|
||||
stripped (``perplexity/sonar``, ``openai/gpt-5.2``, ``preset/pro-search``), while chat,
|
||||
embedding and search ids are a single segment (``sonar``, ``sonar-pro``). Reading the id
|
||||
keeps routing independent of the cost map, which does not carry every model Perplexity
|
||||
serves and whose flat ``perplexity/sonar`` chat entry otherwise shadows the Agent API one.
|
||||
"""
|
||||
return "/" in model
|
||||
|
||||
|
||||
class PerplexityResponsesConfig(OpenAIResponsesAPIConfig):
|
||||
def get_supported_openai_params(self, model: str) -> list:
|
||||
"""Ref: https://docs.perplexity.ai/api-reference/responses-post"""
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ from litellm.llms.cohere.common_utils import CohereModelInfo
|
|||
from litellm.llms.custom_httpx.http_handler import AsyncHTTPHandler, HTTPHandler
|
||||
from litellm.llms.openai.chat.gpt_5_transformation import OpenAIGPT5Config
|
||||
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
|
||||
from litellm.llms.perplexity.responses.transformation import perplexity_uses_agent_api
|
||||
from litellm.llms.vertex_ai.common_utils import (
|
||||
VertexAIModelRoute,
|
||||
get_vertex_ai_model_route,
|
||||
|
|
@ -1084,6 +1085,9 @@ def responses_api_bridge_check(
|
|||
mode = "responses"
|
||||
model_info["mode"] = mode
|
||||
|
||||
if custom_llm_provider == "perplexity" and perplexity_uses_agent_api(model):
|
||||
model_info["mode"] = "responses"
|
||||
|
||||
# OpenAI/Azure GPT-5 chat-completions that need Responses-only fields (e.g.
|
||||
# ``reasoningSummary`` in ``extra_body``) must be bridged; Chat Completions rejects
|
||||
# those keys.
|
||||
|
|
|
|||
|
|
@ -15,7 +15,10 @@ import pytest
|
|||
|
||||
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj
|
||||
from litellm.llms.base_llm.chat.transformation import BaseLLMException
|
||||
from litellm.llms.perplexity.responses.transformation import PerplexityResponsesConfig
|
||||
from litellm.llms.perplexity.responses.transformation import (
|
||||
PerplexityResponsesConfig,
|
||||
perplexity_uses_agent_api,
|
||||
)
|
||||
from litellm.types.llms.openai import ResponsesAPIOptionalRequestParams
|
||||
from litellm.types.utils import LlmProviders
|
||||
from litellm.utils import ProviderConfigManager
|
||||
|
|
@ -587,3 +590,55 @@ class TestPerplexityResponsesTransformation:
|
|||
assert result.type == "response.completed"
|
||||
assert result.response.usage.cost == 0.0003
|
||||
assert isinstance(result.response.usage.cost, float)
|
||||
|
||||
|
||||
class TestPerplexityAgentApiRouting:
|
||||
"""Routing an Agent API deployment to /v1/responses must not depend on the cost map.
|
||||
|
||||
``completion()`` picks the responses bridge off ``mode`` in the cost map, so an Agent API
|
||||
model litellm ships no pricing for was unroutable on /v1/chat/completions, and
|
||||
``perplexity/perplexity/sonar`` resolved to the older flat ``perplexity/sonar`` chat entry
|
||||
several steps before the doubled-prefix key. Both went out on Perplexity's chat endpoint
|
||||
and came back 400 naming a model id nobody wrote.
|
||||
"""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"model",
|
||||
[
|
||||
"perplexity/sonar",
|
||||
"perplexity/glm-5.2",
|
||||
"perplexity/nemotron-3-ultra-550b-a55b",
|
||||
"openai/gpt-5.2",
|
||||
"anthropic/claude-opus-4-7",
|
||||
"preset/pro-search",
|
||||
],
|
||||
)
|
||||
def test_agent_api_models_bridge_to_responses(self, model):
|
||||
from litellm.main import responses_api_bridge_check
|
||||
|
||||
model_info, _ = responses_api_bridge_check(model=model, custom_llm_provider="perplexity")
|
||||
|
||||
assert model_info.get("mode") == "responses"
|
||||
|
||||
@pytest.mark.parametrize("model", ["sonar", "sonar-pro", "sonar-reasoning", "llama-3.1-70b-instruct"])
|
||||
def test_chat_models_stay_on_chat_completions(self, model):
|
||||
from litellm.main import responses_api_bridge_check
|
||||
|
||||
model_info, _ = responses_api_bridge_check(model=model, custom_llm_provider="perplexity")
|
||||
|
||||
assert model_info.get("mode") != "responses"
|
||||
|
||||
def test_other_providers_keep_a_slash_in_the_model_name_on_chat(self):
|
||||
from litellm.main import responses_api_bridge_check
|
||||
|
||||
model_info, _ = responses_api_bridge_check(
|
||||
model="meta-llama/Llama-3.3-70B-Instruct", custom_llm_provider="together_ai"
|
||||
)
|
||||
|
||||
assert model_info.get("mode") != "responses"
|
||||
|
||||
def test_agent_api_ids_are_told_apart_by_their_vendor_namespace(self):
|
||||
assert perplexity_uses_agent_api("perplexity/sonar") is True
|
||||
assert perplexity_uses_agent_api("preset/pro-search") is True
|
||||
assert perplexity_uses_agent_api("sonar") is False
|
||||
assert perplexity_uses_agent_api("sonar-pro") is False
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue