3232 Literal ,
3333 Optional ,
3434 Sequence ,
35+ Type ,
36+ TypeVar ,
3537 Union ,
3638 overload ,
3739 TYPE_CHECKING ,
6668except ImportError :
6769 PIL_Image = None
6870
71+
72+ T = TypeVar ("T" )
73+
74+
6975# Re-exporting some GAPIC types
7076
7177# GAPIC types used in request
@@ -1627,8 +1633,9 @@ def __init__(
16271633 if response_schema is None :
16281634 raw_schema = None
16291635 else :
1630- gapic_schema_dict = _convert_schema_dict_to_gapic (response_schema )
1631- raw_schema = aiplatform_types .Schema (gapic_schema_dict )
1636+ raw_schema = FunctionDeclaration (
1637+ name = "tmp" , parameters = response_schema
1638+ )._raw_function_declaration .parameters
16321639 self ._raw_generation_config = gapic_content_types .GenerationConfig (
16331640 temperature = temperature ,
16341641 top_p = top_p ,
@@ -1660,8 +1667,12 @@ def _from_gapic(
16601667
16611668 @classmethod
16621669 def from_dict (cls , generation_config_dict : Dict [str , Any ]) -> "GenerationConfig" :
1663- raw_generation_config = gapic_content_types .GenerationConfig (
1664- generation_config_dict
1670+ generation_config_dict = copy .deepcopy (generation_config_dict )
1671+ response_schema = generation_config_dict .get ("response_schema" )
1672+ if response_schema :
1673+ _fix_schema_dict_for_gapic_in_place (response_schema )
1674+ raw_generation_config = _dict_to_proto (
1675+ gapic_content_types .GenerationConfig , generation_config_dict
16651676 )
16661677 return cls ._from_gapic (raw_generation_config = raw_generation_config )
16671678
@@ -1872,12 +1883,11 @@ def _from_gapic(
18721883 @classmethod
18731884 def from_dict (cls , tool_dict : Dict [str , Any ]) -> "Tool" :
18741885 tool_dict = copy .deepcopy (tool_dict )
1875- function_declarations = tool_dict ["function_declarations" ]
1876- for function_declaration in function_declarations :
1877- function_declaration ["parameters" ] = _convert_schema_dict_to_gapic (
1878- function_declaration ["parameters" ]
1879- )
1880- raw_tool = gapic_tool_types .Tool (tool_dict )
1886+ for function_declaration in tool_dict .get ("function_declarations" ) or []:
1887+ parameters = function_declaration .get ("parameters" )
1888+ if parameters :
1889+ _fix_schema_dict_for_gapic_in_place (parameters )
1890+ raw_tool = _dict_to_proto (aiplatform_types .Tool , tool_dict )
18811891 return cls ._from_gapic (raw_tool = raw_tool )
18821892
18831893 def to_dict (self ) -> Dict [str , Any ]:
@@ -2035,8 +2045,9 @@ def __init__(
20352045 description: Description and purpose of the function.
20362046 Model uses it to decide how and whether to call the function.
20372047 """
2038- gapic_schema_dict = _convert_schema_dict_to_gapic (parameters )
2039- raw_schema = aiplatform_types .Schema (gapic_schema_dict )
2048+ parameters = copy .deepcopy (parameters )
2049+ _fix_schema_dict_for_gapic_in_place (parameters )
2050+ raw_schema = _dict_to_proto (aiplatform_types .Schema , parameters )
20402051 self ._raw_function_declaration = gapic_tool_types .FunctionDeclaration (
20412052 name = name , description = description , parameters = raw_schema
20422053 )
@@ -2052,6 +2063,7 @@ def __repr__(self) -> str:
20522063 return self ._raw_function_declaration .__repr__ ()
20532064
20542065
2066+ # TODO: Remove this function once Reasoning Engines moves away from it.
20552067def _convert_schema_dict_to_gapic (schema_dict : Dict [str , Any ]) -> Dict [str , Any ]:
20562068 """Converts a JsonSchema to a dict that the GAPIC Schema class accepts."""
20572069 gapic_schema_dict = copy .copy (schema_dict )
@@ -2070,6 +2082,20 @@ def _convert_schema_dict_to_gapic(schema_dict: Dict[str, Any]) -> Dict[str, Any]
20702082 return gapic_schema_dict
20712083
20722084
2085+ def _fix_schema_dict_for_gapic_in_place (schema_dict : Dict [str , Any ]) -> None :
2086+ """Converts a JsonSchema to a dict that the Schema proto class accepts."""
2087+ schema_dict ["type" ] = schema_dict ["type" ].upper ()
2088+
2089+ items_schema = schema_dict .get ("items" )
2090+ if items_schema :
2091+ _fix_schema_dict_for_gapic_in_place (items_schema )
2092+
2093+ properties = schema_dict .get ("properties" )
2094+ if properties :
2095+ for property_schema in properties .values ():
2096+ _fix_schema_dict_for_gapic_in_place (property_schema )
2097+
2098+
20732099class CallableFunctionDeclaration (FunctionDeclaration ):
20742100 """A function declaration plus a function."""
20752101
@@ -2139,8 +2165,9 @@ def _from_gapic(
21392165
21402166 @classmethod
21412167 def from_dict (cls , response_dict : Dict [str , Any ]) -> "GenerationResponse" :
2142- raw_response = gapic_prediction_service_types .GenerateContentResponse ()
2143- json_format .ParseDict (response_dict , raw_response ._pb )
2168+ raw_response = _dict_to_proto (
2169+ gapic_prediction_service_types .GenerateContentResponse , response_dict
2170+ )
21442171 return cls ._from_gapic (raw_response = raw_response )
21452172
21462173 def to_dict (self ) -> Dict [str , Any ]:
@@ -2209,8 +2236,7 @@ def _from_gapic(cls, raw_candidate: gapic_content_types.Candidate) -> "Candidate
22092236
22102237 @classmethod
22112238 def from_dict (cls , candidate_dict : Dict [str , Any ]) -> "Candidate" :
2212- raw_candidate = gapic_content_types .Candidate ()
2213- json_format .ParseDict (candidate_dict , raw_candidate ._pb )
2239+ raw_candidate = _dict_to_proto (gapic_content_types .Candidate , candidate_dict )
22142240 return cls ._from_gapic (raw_candidate = raw_candidate )
22152241
22162242 def to_dict (self ) -> Dict [str , Any ]:
@@ -2310,8 +2336,7 @@ def _from_gapic(cls, raw_content: gapic_content_types.Content) -> "Content":
23102336
23112337 @classmethod
23122338 def from_dict (cls , content_dict : Dict [str , Any ]) -> "Content" :
2313- raw_content = gapic_content_types .Content ()
2314- json_format .ParseDict (content_dict , raw_content ._pb )
2339+ raw_content = _dict_to_proto (gapic_content_types .Content , content_dict )
23152340 return cls ._from_gapic (raw_content = raw_content )
23162341
23172342 def to_dict (self ) -> Dict [str , Any ]:
@@ -2381,8 +2406,7 @@ def _from_gapic(cls, raw_part: gapic_content_types.Part) -> "Part":
23812406
23822407 @classmethod
23832408 def from_dict (cls , part_dict : Dict [str , Any ]) -> "Part" :
2384- raw_part = gapic_content_types .Part ()
2385- json_format .ParseDict (part_dict , raw_part ._pb )
2409+ raw_part = _dict_to_proto (gapic_content_types .Part , part_dict )
23862410 return cls ._from_gapic (raw_part = raw_part )
23872411
23882412 def __repr__ (self ) -> str :
@@ -2510,7 +2534,9 @@ def _from_gapic(
25102534
25112535 @classmethod
25122536 def from_dict (cls , safety_setting_dict : Dict [str , Any ]) -> "SafetySetting" :
2513- raw_safety_setting = gapic_content_types .SafetySetting (safety_setting_dict )
2537+ raw_safety_setting = _dict_to_proto (
2538+ aiplatform_types .SafetySetting , safety_setting_dict
2539+ )
25142540 return cls ._from_gapic (raw_safety_setting = raw_safety_setting )
25152541
25162542 def to_dict (self ) -> Dict [str , Any ]:
@@ -2760,6 +2786,15 @@ def _proto_to_dict(message) -> Dict[str, Any]:
27602786 )
27612787
27622788
2789+ def _dict_to_proto (message_type : Type [T ], message_dict : Dict [str , Any ]) -> T :
2790+ """Converts a dictionary to a proto-plus protobuf message."""
2791+ # We cannot just use `message = message_type(message_dict)` because
2792+ # it fails for classes where GAPIC has renamed proto fields.
2793+ message = message_type ()
2794+ json_format .ParseDict (message_dict , message ._pb )
2795+ return message
2796+
2797+
27632798def _dict_to_pretty_string (d : dict ) -> str :
27642799 """Format dict as a pretty-printed JSON string."""
27652800 return json .dumps (d , indent = 2 )
0 commit comments