mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-12 03:48:56 +00:00
Merge pull request #44437 from BerriAI/litellm_chore_bba82d
test(e2e): backport Together structured-output and text-completion fixes to stable/1.103.x
This commit is contained in:
commit
ecae261b10
3 changed files with 28 additions and 17 deletions
|
|
@ -97,6 +97,7 @@ class CompletionsRequest(BaseModel):
|
|||
model: str
|
||||
prompt: str
|
||||
max_tokens: int = 32
|
||||
reasoning_effort: str | None = None
|
||||
cache: dict[str, bool] | None = {"no-cache": True}
|
||||
|
||||
|
||||
|
|
@ -378,12 +379,20 @@ class EndpointsClient:
|
|||
)
|
||||
|
||||
def text_completions(
|
||||
self, key: str, model: str, prompt: str, *, max_tokens: int = 32
|
||||
self,
|
||||
key: str,
|
||||
model: str,
|
||||
prompt: str,
|
||||
*,
|
||||
max_tokens: int = 32,
|
||||
reasoning_effort: str | None = None,
|
||||
) -> StreamingResponse:
|
||||
return self._send(
|
||||
"/v1/completions",
|
||||
key,
|
||||
CompletionsRequest(model=model, prompt=prompt, max_tokens=max_tokens),
|
||||
CompletionsRequest(
|
||||
model=model, prompt=prompt, max_tokens=max_tokens, reasoning_effort=reasoning_effort
|
||||
),
|
||||
)
|
||||
|
||||
def embeddings(self, key: str, model: str, text: str) -> StreamingResponse:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
The legacy text-completion endpoint (prompt-style, non-chat) is the second-busiest
|
||||
route in production yet was previously uncovered; the rest of the "completions"
|
||||
surface is chat only. Registers an OpenAI instruct deployment at runtime (deleted
|
||||
surface is chat only. Registers an OpenAI chat deployment at runtime (deleted
|
||||
on teardown), drives /v1/completions through the gateway, and asserts real
|
||||
generated text came back so a regression that empties the completion fails here.
|
||||
"""
|
||||
|
|
@ -29,7 +29,7 @@ class TestCompletionsEndpoint:
|
|||
model_id = endpoints_client.create_model(
|
||||
model,
|
||||
LiteLLMParamsBody(
|
||||
model="text-completion-openai/gpt-3.5-turbo-instruct",
|
||||
model="openai/gpt-5.4-nano",
|
||||
api_key="os.environ/OPENAI_API_KEY",
|
||||
),
|
||||
)
|
||||
|
|
@ -37,7 +37,10 @@ class TestCompletionsEndpoint:
|
|||
key = resources.key()
|
||||
|
||||
result = endpoints_client.text_completions(
|
||||
key, model, "Finish this sentence in a few words: the capital of France is"
|
||||
key,
|
||||
model,
|
||||
"Finish this sentence in a few words: the capital of France is",
|
||||
reasoning_effort="none",
|
||||
)
|
||||
require_successful_call(result)
|
||||
parsed = CompletionsResult.model_validate_json(result.body)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
"""Live e2e: Together AI through the gateway on /chat/completions and /v1/messages.
|
||||
|
||||
The reasoning and tool-calling backend is the cheapest live ``together_ai/`` chat row
|
||||
in the proxy's own cost map that carries both capability flags; the structured-output
|
||||
and cache-pricing backends are likewise the cheapest rows carrying
|
||||
``supports_response_schema`` and a ``cache_read_input_token_cost``. Two backends are
|
||||
pinned because the registry has no flag for what they prove: ``enable_thinking`` and
|
||||
the ``{"reasoning": {"enabled": false}}`` toggle that ``reasoning_effort="none"`` maps
|
||||
to are Qwen hybrid-model contracts, and MiniMax-M3 is the serverless model whose
|
||||
in the proxy's own cost map that carries both capability flags; the cache-pricing
|
||||
backend is likewise the cheapest row carrying a ``cache_read_input_token_cost``. Two
|
||||
backends are pinned because the registry has no flag for what they prove: ``enable_thinking``
|
||||
and the ``{"reasoning": {"enabled": false}}`` toggle that ``reasoning_effort="none"`` maps
|
||||
to are Qwen hybrid-model contracts, and the structured-output case runs on that hybrid
|
||||
model with reasoning off, since a reasoning-only model can spend the whole token budget
|
||||
thinking and return no content. MiniMax-M3 is the serverless model whose
|
||||
template renders a replayed ``reasoning_content`` back into the prompt (Qwen and
|
||||
DeepSeek silently drop it). MiniMax-M3 honors that replayed field on nearly every call, not
|
||||
every call (one miss in dozens of otherwise identical calls), so the replay case asks
|
||||
|
|
@ -109,7 +110,6 @@ MESSAGES_WEATHER_TOOL = AnthropicCustomTool(
|
|||
class _Needs:
|
||||
function_calling: bool = False
|
||||
reasoning: bool = False
|
||||
response_schema: bool = False
|
||||
cache_read_pricing: bool = False
|
||||
|
||||
|
||||
|
|
@ -172,7 +172,6 @@ def _cheapest_together_chat_model(registry: Mapping[str, CostMapEntry], needs: _
|
|||
and (entry.output_cost_per_token or 0.0) > 0
|
||||
and (not needs.function_calling or bool(entry.supports_function_calling))
|
||||
and (not needs.reasoning or bool(entry.supports_reasoning))
|
||||
and (not needs.response_schema or bool(entry.supports_response_schema))
|
||||
and (not needs.cache_read_pricing or (entry.cache_read_input_token_cost or 0.0) > 0)
|
||||
)
|
||||
|
||||
|
|
@ -586,10 +585,9 @@ class TestTogetherChatCompletions:
|
|||
|
||||
@pytest.mark.covers("llm.chat_completions.together_ai.structured_output.nonstream.works")
|
||||
def test_response_format_json_schema_shapes_the_reply(
|
||||
self, client: PassthroughClient, resources: ResourceManager, registry: dict[str, CostMapEntry]
|
||||
self, client: PassthroughClient, resources: ResourceManager
|
||||
) -> None:
|
||||
backend = _cheapest_together_chat_model(registry, _Needs(response_schema=True))
|
||||
model, key = _register(client, resources, backend)
|
||||
model, key = _register(client, resources, HYBRID_REASONING_BACKEND)
|
||||
|
||||
message = _message(
|
||||
unwrap(
|
||||
|
|
@ -599,12 +597,13 @@ class TestTogetherChatCompletions:
|
|||
model=model,
|
||||
messages=[ChatMessage(role="user", content=PERSON_PROMPT)],
|
||||
max_tokens=1024,
|
||||
reasoning_effort="none",
|
||||
response_format=PERSON_RESPONSE_FORMAT,
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
assert message.content, f"{backend} returned no content: {message}"
|
||||
assert message.content, f"{HYBRID_REASONING_BACKEND} returned no content: {message}"
|
||||
person = _Person.model_validate_json(message.content)
|
||||
assert person.name, f"schema-shaped reply carries an empty name: {message.content!r}"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue