22
22
23
23
logger = logging .getLogger (__name__ )
24
24
25
+ ERROR_MESSAGE_ON_JSON_ADAPTER_FAILURE = (
26
+ "Both structured output format and JSON mode failed. Please choose a model that supports "
27
+ "`response_format` argument. Original error: {}"
28
+ )
29
+
25
30
26
31
def _has_open_ended_mapping (signature : SignatureMeta ) -> bool :
27
32
"""
@@ -37,6 +42,18 @@ def _has_open_ended_mapping(signature: SignatureMeta) -> bool:
37
42
38
43
39
44
class JSONAdapter (ChatAdapter ):
45
+ def _json_adapter_call_common (self , lm , lm_kwargs , signature , demos , inputs , call_fn ):
46
+ """Common call logic to be used for both sync and async calls."""
47
+ provider = lm .model .split ("/" , 1 )[0 ] or "openai"
48
+ params = litellm .get_supported_openai_params (model = lm .model , custom_llm_provider = provider )
49
+
50
+ if not params or "response_format" not in params :
51
+ return call_fn (lm , lm_kwargs , signature , demos , inputs )
52
+
53
+ if _has_open_ended_mapping (signature ):
54
+ lm_kwargs ["response_format" ] = {"type" : "json_object" }
55
+ return call_fn (lm , lm_kwargs , signature , demos , inputs )
56
+
40
57
def __call__ (
41
58
self ,
42
59
lm : LM ,
@@ -45,37 +62,49 @@ def __call__(
45
62
demos : list [dict [str , Any ]],
46
63
inputs : dict [str , Any ],
47
64
) -> list [dict [str , Any ]]:
48
- provider = lm .model .split ("/" , 1 )[0 ] or "openai"
49
- params = litellm .get_supported_openai_params (model = lm .model , custom_llm_provider = provider )
65
+ result = self ._json_adapter_call_common (lm , lm_kwargs , signature , demos , inputs , super ().__call__ )
66
+ if result :
67
+ return result
50
68
51
- # If response_format is not supported, use basic call
52
- if not params or "response_format" not in params :
69
+ try :
70
+ structured_output_model = _get_structured_outputs_response_format (signature )
71
+ lm_kwargs ["response_format" ] = structured_output_model
53
72
return super ().__call__ (lm , lm_kwargs , signature , demos , inputs )
73
+ except Exception :
74
+ logger .warning ("Failed to use structured output format, falling back to JSON mode." )
75
+ try :
76
+ lm_kwargs ["response_format" ] = {"type" : "json_object" }
77
+ return super ().__call__ (lm , lm_kwargs , signature , demos , inputs )
78
+ except AdapterParseError as e :
79
+ raise e
80
+ except Exception as e :
81
+ raise RuntimeError (ERROR_MESSAGE_ON_JSON_ADAPTER_FAILURE .format (e )) from e
54
82
55
- # Check early for open-ended mapping types before trying structured outputs.
56
- if _has_open_ended_mapping (signature ):
57
- lm_kwargs ["response_format" ] = {"type" : "json_object" }
58
- return super ().__call__ (lm , lm_kwargs , signature , demos , inputs )
83
+ async def acall (
84
+ self ,
85
+ lm : LM ,
86
+ lm_kwargs : dict [str , Any ],
87
+ signature : Type [Signature ],
88
+ demos : list [dict [str , Any ]],
89
+ inputs : dict [str , Any ],
90
+ ) -> list [dict [str , Any ]]:
91
+ result = self ._json_adapter_call_common (lm , lm_kwargs , signature , demos , inputs , super ().acall )
92
+ if result :
93
+ return await result
59
94
60
- # Try structured output first, fall back to basic JSON if it fails.
61
95
try :
62
96
structured_output_model = _get_structured_outputs_response_format (signature )
63
97
lm_kwargs ["response_format" ] = structured_output_model
64
- return super ().__call__ (lm , lm_kwargs , signature , demos , inputs )
98
+ return await super ().acall (lm , lm_kwargs , signature , demos , inputs )
65
99
except Exception :
66
100
logger .warning ("Failed to use structured output format, falling back to JSON mode." )
67
101
try :
68
102
lm_kwargs ["response_format" ] = {"type" : "json_object" }
69
- return super ().__call__ (lm , lm_kwargs , signature , demos , inputs )
103
+ return await super ().acall (lm , lm_kwargs , signature , demos , inputs )
70
104
except AdapterParseError as e :
71
- # On AdapterParseError, we raise the original error.
72
105
raise e
73
106
except Exception as e :
74
- # On any other error, we raise a RuntimeError with the original error message.
75
- raise RuntimeError (
76
- "Both structured output format and JSON mode failed. Please choose a model that supports "
77
- f"`response_format` argument. Original error: { e } "
78
- ) from e
107
+ raise RuntimeError (ERROR_MESSAGE_ON_JSON_ADAPTER_FAILURE .format (e )) from e
79
108
80
109
def _call_preprocess (
81
110
self ,
0 commit comments