mirror of
https://github.com/BerriAI/litellm.git
synced 2025-04-25 18:54:30 +00:00
This reverts commit e3729f9855
.
This commit is contained in:
parent
e3729f9855
commit
d3e7a137ad
3 changed files with 6 additions and 198 deletions
|
@ -165,18 +165,9 @@ def _check_text_in_content(parts: List[PartType]) -> bool:
|
||||||
return has_text_param
|
return has_text_param
|
||||||
|
|
||||||
|
|
||||||
def _build_vertex_schema(parameters: dict, add_property_ordering: bool = False):
|
def _build_vertex_schema(parameters: dict):
|
||||||
"""
|
"""
|
||||||
This is a modified version of https://github.com/google-gemini/generative-ai-python/blob/8f77cc6ac99937cd3a81299ecf79608b91b06bbb/google/generativeai/types/content_types.py#L419
|
This is a modified version of https://github.com/google-gemini/generative-ai-python/blob/8f77cc6ac99937cd3a81299ecf79608b91b06bbb/google/generativeai/types/content_types.py#L419
|
||||||
|
|
||||||
Updates the input parameters, removing extraneous fields, adjusting types, unwinding $defs, and adding propertyOrdering if specified, returning the updated parameters.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
parameters: dict - the json schema to build from
|
|
||||||
add_property_ordering: bool - whether to add propertyOrdering to the schema. This is only applicable to schemas for structured outputs. See
|
|
||||||
set_schema_property_ordering for more details.
|
|
||||||
Returns:
|
|
||||||
parameters: dict - the input parameters, modified in place
|
|
||||||
"""
|
"""
|
||||||
# Get valid fields from Schema TypedDict
|
# Get valid fields from Schema TypedDict
|
||||||
valid_schema_fields = set(get_type_hints(Schema).keys())
|
valid_schema_fields = set(get_type_hints(Schema).keys())
|
||||||
|
@ -195,31 +186,8 @@ def _build_vertex_schema(parameters: dict, add_property_ordering: bool = False):
|
||||||
add_object_type(parameters)
|
add_object_type(parameters)
|
||||||
# Postprocessing
|
# Postprocessing
|
||||||
# Filter out fields that don't exist in Schema
|
# Filter out fields that don't exist in Schema
|
||||||
parameters = filter_schema_fields(parameters, valid_schema_fields)
|
filtered_parameters = filter_schema_fields(parameters, valid_schema_fields)
|
||||||
|
return filtered_parameters
|
||||||
if add_property_ordering:
|
|
||||||
set_schema_property_ordering(parameters)
|
|
||||||
return parameters
|
|
||||||
|
|
||||||
|
|
||||||
def set_schema_property_ordering(schema: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""
|
|
||||||
vertex ai and generativeai apis order output of fields alphabetically, unless you specify the order.
|
|
||||||
python dicts retain order, so we just use that. Note that this field only applies to structured outputs, and not tools.
|
|
||||||
Function tools are not afflicted by the same alphabetical ordering issue, (the order of keys returned seems to be arbitrary, up to the model)
|
|
||||||
https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.cachedContents#Schema.FIELDS.property_ordering
|
|
||||||
"""
|
|
||||||
if "properties" in schema and isinstance(schema["properties"], dict):
|
|
||||||
# retain propertyOrdering as an escape hatch if user already specifies it
|
|
||||||
if "propertyOrdering" not in schema:
|
|
||||||
schema["propertyOrdering"] = [k for k, v in schema["properties"].items()]
|
|
||||||
for k, v in schema["properties"].items():
|
|
||||||
set_schema_property_ordering(v)
|
|
||||||
if "items" in schema:
|
|
||||||
set_schema_property_ordering(schema["items"])
|
|
||||||
return schema
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def filter_schema_fields(
|
def filter_schema_fields(
|
||||||
|
|
|
@ -207,7 +207,7 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
||||||
"extra_headers",
|
"extra_headers",
|
||||||
"seed",
|
"seed",
|
||||||
"logprobs",
|
"logprobs",
|
||||||
"top_logprobs",
|
"top_logprobs", # Added this to list of supported openAI params
|
||||||
"modalities",
|
"modalities",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -313,10 +313,9 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
||||||
if isinstance(old_schema, list):
|
if isinstance(old_schema, list):
|
||||||
for item in old_schema:
|
for item in old_schema:
|
||||||
if isinstance(item, dict):
|
if isinstance(item, dict):
|
||||||
item = _build_vertex_schema(parameters=item, add_property_ordering=True)
|
item = _build_vertex_schema(parameters=item)
|
||||||
|
|
||||||
elif isinstance(old_schema, dict):
|
elif isinstance(old_schema, dict):
|
||||||
old_schema = _build_vertex_schema(parameters=old_schema, add_property_ordering=True)
|
old_schema = _build_vertex_schema(parameters=old_schema)
|
||||||
return old_schema
|
return old_schema
|
||||||
|
|
||||||
def apply_response_schema_transformation(self, value: dict, optional_params: dict):
|
def apply_response_schema_transformation(self, value: dict, optional_params: dict):
|
||||||
|
|
|
@ -9,8 +9,6 @@ from litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import (
|
||||||
VertexGeminiConfig,
|
VertexGeminiConfig,
|
||||||
)
|
)
|
||||||
from litellm.types.utils import ChoiceLogprobs
|
from litellm.types.utils import ChoiceLogprobs
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, cast
|
|
||||||
|
|
||||||
|
|
||||||
def test_top_logprobs():
|
def test_top_logprobs():
|
||||||
|
@ -64,160 +62,3 @@ def test_get_model_name_from_gemini_spec_model():
|
||||||
model = "gemini/ft-uuid-123"
|
model = "gemini/ft-uuid-123"
|
||||||
result = VertexGeminiConfig._get_model_name_from_gemini_spec_model(model)
|
result = VertexGeminiConfig._get_model_name_from_gemini_spec_model(model)
|
||||||
assert result == "ft-uuid-123"
|
assert result == "ft-uuid-123"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_vertex_ai_response_schema_dict():
|
|
||||||
v = VertexGeminiConfig()
|
|
||||||
transformed_request = v.map_openai_params(
|
|
||||||
non_default_params={
|
|
||||||
"messages": [{"role": "user", "content": "Hello, world!"}],
|
|
||||||
"response_format": {
|
|
||||||
"type": "json_schema",
|
|
||||||
"json_schema": {
|
|
||||||
"name": "math_reasoning",
|
|
||||||
"schema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"steps": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"thought": {"type": "string"},
|
|
||||||
"output": {"type": "string"},
|
|
||||||
},
|
|
||||||
"required": ["thought", "output"],
|
|
||||||
"additionalProperties": False,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"final_answer": {"type": "string"},
|
|
||||||
},
|
|
||||||
"required": ["steps", "final_answer"],
|
|
||||||
"additionalProperties": False,
|
|
||||||
},
|
|
||||||
"strict": False,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
optional_params={},
|
|
||||||
model="gemini-2.0-flash-lite",
|
|
||||||
drop_params=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
schema = transformed_request["response_schema"]
|
|
||||||
# should add propertyOrdering
|
|
||||||
assert schema["propertyOrdering"] == ["steps", "final_answer"]
|
|
||||||
# should add propertyOrdering (recursively, including array items)
|
|
||||||
assert schema["properties"]["steps"]["items"]["propertyOrdering"] == [
|
|
||||||
"thought",
|
|
||||||
"output",
|
|
||||||
]
|
|
||||||
# should strip strict and additionalProperties
|
|
||||||
assert "strict" not in schema
|
|
||||||
assert "additionalProperties" not in schema
|
|
||||||
# validate the whole thing to catch regressions
|
|
||||||
assert transformed_request["response_schema"] == {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"steps": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"thought": {"type": "string"},
|
|
||||||
"output": {"type": "string"},
|
|
||||||
},
|
|
||||||
"required": ["thought", "output"],
|
|
||||||
"propertyOrdering": ["thought", "output"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"final_answer": {"type": "string"},
|
|
||||||
},
|
|
||||||
"required": ["steps", "final_answer"],
|
|
||||||
"propertyOrdering": ["steps", "final_answer"],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class MathReasoning(BaseModel):
|
|
||||||
steps: List["Step"]
|
|
||||||
final_answer: str
|
|
||||||
|
|
||||||
|
|
||||||
class Step(BaseModel):
|
|
||||||
thought: str
|
|
||||||
output: str
|
|
||||||
|
|
||||||
|
|
||||||
def test_vertex_ai_response_schema_defs():
|
|
||||||
v = VertexGeminiConfig()
|
|
||||||
|
|
||||||
schema = cast(dict, v.get_json_schema_from_pydantic_object(MathReasoning))
|
|
||||||
|
|
||||||
# pydantic conversion by default adds $defs to the schema, make sure this is still the case, otherwise this test isn't really testing anything
|
|
||||||
assert "$defs" in schema["json_schema"]["schema"]
|
|
||||||
|
|
||||||
transformed_request = v.map_openai_params(
|
|
||||||
non_default_params={
|
|
||||||
"messages": [{"role": "user", "content": "Hello, world!"}],
|
|
||||||
"response_format": schema,
|
|
||||||
},
|
|
||||||
optional_params={},
|
|
||||||
model="gemini-2.0-flash-lite",
|
|
||||||
drop_params=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert "$defs" not in transformed_request["response_schema"]
|
|
||||||
assert transformed_request["response_schema"] == {
|
|
||||||
"title": "MathReasoning",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"steps": {
|
|
||||||
"title": "Steps",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"title": "Step",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"thought": {"title": "Thought", "type": "string"},
|
|
||||||
"output": {"title": "Output", "type": "string"},
|
|
||||||
},
|
|
||||||
"required": ["thought", "output"],
|
|
||||||
"propertyOrdering": ["thought", "output"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"final_answer": {"title": "Final Answer", "type": "string"},
|
|
||||||
},
|
|
||||||
"required": ["steps", "final_answer"],
|
|
||||||
"propertyOrdering": ["steps", "final_answer"],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def test_vertex_ai_retain_property_ordering():
|
|
||||||
v = VertexGeminiConfig()
|
|
||||||
transformed_request = v.map_openai_params(
|
|
||||||
non_default_params={
|
|
||||||
"messages": [{"role": "user", "content": "Hello, world!"}],
|
|
||||||
"response_format": {
|
|
||||||
"type": "json_schema",
|
|
||||||
"json_schema": {
|
|
||||||
"name": "math_reasoning",
|
|
||||||
"schema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"output": {"type": "string"},
|
|
||||||
"thought": {"type": "string"},
|
|
||||||
},
|
|
||||||
"propertyOrdering": ["thought", "output"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
optional_params={},
|
|
||||||
model="gemini-2.0-flash-lite",
|
|
||||||
drop_params=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
schema = transformed_request["response_schema"]
|
|
||||||
# should leave existing value alone, despite dictionary ordering
|
|
||||||
assert schema["propertyOrdering"] == ["thought", "output"]
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue