synth-ai 0.1.0.dev31__py3-none-any.whl → 0.1.0.dev33__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- public_tests/test_tools.py +19 -0
- synth_ai/zyk/lms/structured_outputs/handler.py +10 -10
- synth_ai/zyk/lms/vendors/core/anthropic_api.py +12 -2
- synth_ai/zyk/lms/vendors/openai_standard.py +24 -4
- {synth_ai-0.1.0.dev31.dist-info → synth_ai-0.1.0.dev33.dist-info}/METADATA +1 -1
- {synth_ai-0.1.0.dev31.dist-info → synth_ai-0.1.0.dev33.dist-info}/RECORD +9 -9
- {synth_ai-0.1.0.dev31.dist-info → synth_ai-0.1.0.dev33.dist-info}/WHEEL +0 -0
- {synth_ai-0.1.0.dev31.dist-info → synth_ai-0.1.0.dev33.dist-info}/licenses/LICENSE +0 -0
- {synth_ai-0.1.0.dev31.dist-info → synth_ai-0.1.0.dev33.dist-info}/top_level.txt +0 -0
public_tests/test_tools.py
CHANGED
@@ -147,6 +147,25 @@ def test_weather_tool_anthropic_lm():
|
|
147
147
|
assert "location" in arguments
|
148
148
|
assert "Paris" in arguments
|
149
149
|
|
150
|
+
def test_weather_tool_anthropic_35():
|
151
|
+
lm = LM(
|
152
|
+
model_name="claude-3-5-sonnet-latest",
|
153
|
+
formatting_model_name="claude-3-5-sonnet-20241022",
|
154
|
+
temperature=0,
|
155
|
+
)
|
156
|
+
|
157
|
+
response = lm.respond_sync(
|
158
|
+
system_message="You are a helpful assistant that uses tools when appropriate.",
|
159
|
+
user_message="What's the weather in Paris? Use the tools and explain your reasoning. Units local to the country, please!",
|
160
|
+
tools=[weather_tool],
|
161
|
+
)
|
162
|
+
|
163
|
+
assert response.tool_calls is not None
|
164
|
+
assert len(response.tool_calls) > 0
|
165
|
+
assert response.tool_calls[0]["function"]["name"] == "get_weather"
|
166
|
+
assert "arguments" in response.tool_calls[0]["function"]
|
167
|
+
arguments = response.tool_calls[0]["function"]["arguments"]
|
168
|
+
assert isinstance(arguments, str)
|
150
169
|
|
151
170
|
# Gemini Tests
|
152
171
|
def test_weather_tool_gemini_direct():
|
@@ -174,24 +174,24 @@ class StringifiedJSONHandler(StructuredHandlerBase):
|
|
174
174
|
type(raw_text_response_or_cached_hit) in [str, BaseLMResponse]
|
175
175
|
), f"Expected str or BaseLMResponse, got {type(raw_text_response_or_cached_hit)}"
|
176
176
|
if type(raw_text_response_or_cached_hit) == BaseLMResponse:
|
177
|
-
print("Got cached hit, returning directly")
|
177
|
+
#print("Got cached hit, returning directly")
|
178
178
|
raw_text_response = raw_text_response_or_cached_hit.raw_response
|
179
179
|
else:
|
180
180
|
raw_text_response = raw_text_response_or_cached_hit
|
181
181
|
logger.debug(f"Raw response from model:\n{raw_text_response}")
|
182
182
|
|
183
|
-
print("Trying to parse structured output")
|
183
|
+
#print("Trying to parse structured output")
|
184
184
|
try:
|
185
185
|
structured_output = pull_out_structured_output(
|
186
186
|
raw_text_response, response_model
|
187
187
|
)
|
188
188
|
|
189
|
-
print("Successfully parsed structured output on first attempt")
|
189
|
+
#print("Successfully parsed structured output on first attempt")
|
190
190
|
break
|
191
191
|
except Exception as e:
|
192
192
|
logger.warning(f"Failed to parse structured output: {str(e)}")
|
193
193
|
try:
|
194
|
-
print("Attempting to fix with forced JSON parser")
|
194
|
+
#print("Attempting to fix with forced JSON parser")
|
195
195
|
structured_output = await fix_errant_forced_async(
|
196
196
|
messages_with_json_formatting_instructions,
|
197
197
|
raw_text_response,
|
@@ -200,7 +200,7 @@ class StringifiedJSONHandler(StructuredHandlerBase):
|
|
200
200
|
)
|
201
201
|
assert isinstance(structured_output, BaseModel), "Structured output must be a Pydantic model"
|
202
202
|
assert not isinstance(structured_output, BaseLMResponse), "Got BaseLMResponse instead of Pydantic model"
|
203
|
-
print("Successfully fixed and parsed structured output")
|
203
|
+
#print("Successfully fixed and parsed structured output")
|
204
204
|
break
|
205
205
|
except Exception as e:
|
206
206
|
logger.error(f"Failed to fix structured output: {str(e)}")
|
@@ -215,8 +215,8 @@ class StringifiedJSONHandler(StructuredHandlerBase):
|
|
215
215
|
raise StructuredOutputCoercionFailureException(
|
216
216
|
"Failed to get structured output"
|
217
217
|
)
|
218
|
-
print("Successfully parsed structured output")
|
219
|
-
print(structured_output)
|
218
|
+
#print("Successfully parsed structured output")
|
219
|
+
#print(structured_output)
|
220
220
|
assert isinstance(structured_output, BaseModel), "Structured output must be a Pydantic model"
|
221
221
|
assert not isinstance(structured_output, BaseLMResponse),"Got BaseLMResponse instead of Pydantic model"
|
222
222
|
return BaseLMResponse(
|
@@ -277,16 +277,16 @@ class StringifiedJSONHandler(StructuredHandlerBase):
|
|
277
277
|
structured_output = pull_out_structured_output(
|
278
278
|
raw_text_response, response_model
|
279
279
|
)
|
280
|
-
print("Successfully parsed structured output on first attempt")
|
280
|
+
#print("Successfully parsed structured output on first attempt")
|
281
281
|
break
|
282
282
|
except Exception as e:
|
283
283
|
logger.warning(f"Failed to parse structured output: {str(e)}")
|
284
284
|
try:
|
285
|
-
print("Attempting to fix with forced JSON parser")
|
285
|
+
#print("Attempting to fix with forced JSON parser")
|
286
286
|
structured_output = fix_errant_forced_sync(
|
287
287
|
raw_text_response, response_model, "gpt-4o-mini"
|
288
288
|
)
|
289
|
-
print("Successfully fixed and parsed structured output")
|
289
|
+
#print("Successfully fixed and parsed structured output")
|
290
290
|
break
|
291
291
|
except Exception as e:
|
292
292
|
logger.error(f"Failed to fix structured output: {str(e)}")
|
@@ -82,7 +82,12 @@ class AnthropicAPI(VendorBase):
|
|
82
82
|
|
83
83
|
# Add tools if provided
|
84
84
|
if tools:
|
85
|
-
api_params["tools"] = [
|
85
|
+
api_params["tools"] = []
|
86
|
+
for tool in tools:
|
87
|
+
if isinstance(tool, BaseTool):
|
88
|
+
api_params["tools"].append(tool.to_anthropic_tool())
|
89
|
+
else:
|
90
|
+
api_params["tools"].append(tool)
|
86
91
|
|
87
92
|
# Only try to add thinking if supported by the SDK
|
88
93
|
try:
|
@@ -175,7 +180,12 @@ class AnthropicAPI(VendorBase):
|
|
175
180
|
|
176
181
|
# Add tools if provided
|
177
182
|
if tools:
|
178
|
-
api_params["tools"] = [
|
183
|
+
api_params["tools"] = []
|
184
|
+
for tool in tools:
|
185
|
+
if isinstance(tool, BaseTool):
|
186
|
+
api_params["tools"].append(tool.to_anthropic_tool())
|
187
|
+
else:
|
188
|
+
api_params["tools"].append(tool)
|
179
189
|
|
180
190
|
# Only try to add thinking if supported by the SDK
|
181
191
|
try:
|
@@ -100,7 +100,12 @@ class OpenAIStandard(VendorBase):
|
|
100
100
|
|
101
101
|
# Add tools if provided
|
102
102
|
if tools:
|
103
|
-
api_params["tools"] = [
|
103
|
+
api_params["tools"] = []
|
104
|
+
for tool in tools:
|
105
|
+
if isinstance(tool, BaseTool):
|
106
|
+
api_params["tools"].append(tool.to_openai_tool())
|
107
|
+
else:
|
108
|
+
api_params["tools"].append(tool)
|
104
109
|
|
105
110
|
# Only add temperature for non o1/o3 models
|
106
111
|
if not any(prefix in model for prefix in ["o1-", "o3-"]):
|
@@ -178,7 +183,12 @@ class OpenAIStandard(VendorBase):
|
|
178
183
|
|
179
184
|
# Add tools if provided
|
180
185
|
if tools:
|
181
|
-
api_params["tools"] = [
|
186
|
+
api_params["tools"] = []
|
187
|
+
for tool in tools:
|
188
|
+
if isinstance(tool, BaseTool):
|
189
|
+
api_params["tools"].append(tool.to_openai_tool())
|
190
|
+
else:
|
191
|
+
api_params["tools"].append(tool)
|
182
192
|
|
183
193
|
# Only add temperature for non o1/o3 models
|
184
194
|
if not any(prefix in model for prefix in ["o1-", "o3-"]):
|
@@ -246,7 +256,12 @@ class OpenAIStandard(VendorBase):
|
|
246
256
|
|
247
257
|
# Add tools if provided
|
248
258
|
if tools:
|
249
|
-
api_params["tools"] = [
|
259
|
+
api_params["tools"] = []
|
260
|
+
for tool in tools:
|
261
|
+
if isinstance(tool, BaseTool):
|
262
|
+
api_params["tools"].append(tool.to_openai_tool())
|
263
|
+
else:
|
264
|
+
api_params["tools"].append(tool)
|
250
265
|
|
251
266
|
# Only add temperature for non o1/o3 models
|
252
267
|
if not any(prefix in model for prefix in ["o1-", "o3-"]):
|
@@ -302,7 +317,12 @@ class OpenAIStandard(VendorBase):
|
|
302
317
|
|
303
318
|
# Add tools if provided
|
304
319
|
if tools:
|
305
|
-
api_params["tools"] = [
|
320
|
+
api_params["tools"] = []
|
321
|
+
for tool in tools:
|
322
|
+
if isinstance(tool, BaseTool):
|
323
|
+
api_params["tools"].append(tool.to_openai_tool())
|
324
|
+
else:
|
325
|
+
api_params["tools"].append(tool)
|
306
326
|
|
307
327
|
# Only add temperature for non o1/o3 models
|
308
328
|
if not any(prefix in model for prefix in ["o1-", "o3-"]):
|
@@ -14,7 +14,7 @@ public_tests/test_structured.py,sha256=rftVwvYgMSHkRZM1WUJzga5Uvl9hmc5OpXzBshEXN
|
|
14
14
|
public_tests/test_structured_outputs.py,sha256=9SFpH4RQ6nRcphBVmELRNSvhRjYaJBu_z-r6xqKAYpg,4213
|
15
15
|
public_tests/test_synth_sdk.py,sha256=jqJHKpvBn9qj21P76z9onXfPg88jyUmBTKmdvCsQMk8,14885
|
16
16
|
public_tests/test_text.py,sha256=UyPZ0ci-XBjK35tAeV0kN1X8Njf-0pHfEPZhsWDZ0-c,4072
|
17
|
-
public_tests/test_tools.py,sha256=
|
17
|
+
public_tests/test_tools.py,sha256=QBwJ70dmPCm27BEwbNaZXXAf8DJxObsfwFX1rlBcYME,10904
|
18
18
|
synth_ai/__init__.py,sha256=tX_fcK8u64BoPEboRa3dIKK_WpLy5KAxL2Ucl-l0xVg,147
|
19
19
|
synth_ai/zyk/__init__.py,sha256=kGMD-drlBVdsyT-QFODMwaZUtxPCJ9mg58GKQUvFqo0,134
|
20
20
|
synth_ai/zyk/lms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -35,17 +35,17 @@ synth_ai/zyk/lms/cost/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
35
35
|
synth_ai/zyk/lms/cost/monitor.py,sha256=cSKIvw6WdPZIRubADWxQoh1MdB40T8-jjgfNUeUHIn0,5
|
36
36
|
synth_ai/zyk/lms/cost/statefulness.py,sha256=TOsuXL8IjtKOYJ2aJQF8TwJVqn_wQ7AIwJJmdhMye7U,36
|
37
37
|
synth_ai/zyk/lms/structured_outputs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
|
-
synth_ai/zyk/lms/structured_outputs/handler.py,sha256=
|
38
|
+
synth_ai/zyk/lms/structured_outputs/handler.py,sha256=BQ0T4HBFXC9qesF8v0lG8MuiOecWm2YEF75nUt1mB_s,16925
|
39
39
|
synth_ai/zyk/lms/structured_outputs/inject.py,sha256=Fy-zDeleRxOZ8ZRM6IuZ6CP2XZnMe4K2PEn4Q9c_KPY,11777
|
40
40
|
synth_ai/zyk/lms/structured_outputs/rehabilitate.py,sha256=GuIhzsb7rTvwgn7f9I9omNnXBz5Me_qrtNYcTWzw5_U,7909
|
41
41
|
synth_ai/zyk/lms/tools/base.py,sha256=j7wYb1xAvaAm3qVrINphgUhGS-UjZmRpbouseQYgh7A,3228
|
42
42
|
synth_ai/zyk/lms/vendors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
43
43
|
synth_ai/zyk/lms/vendors/base.py,sha256=aK4PEtkMLt_o3qD22kW-x3HJUEKdIk06zlH4kX0VkAE,760
|
44
44
|
synth_ai/zyk/lms/vendors/constants.py,sha256=zqCOyXZqo297wboR9EKVSkvpq6JCMSJyeso8HdZPKa4,102
|
45
|
-
synth_ai/zyk/lms/vendors/openai_standard.py,sha256=
|
45
|
+
synth_ai/zyk/lms/vendors/openai_standard.py,sha256=BoLfzd2d6TqFw1CyukJfbUzrqIxQT1A-F0otb1ybNVU,12149
|
46
46
|
synth_ai/zyk/lms/vendors/retries.py,sha256=m-WvAiPix9ovnO2S-m53Td5VZDWBVBFuHuSK9--OVxw,38
|
47
47
|
synth_ai/zyk/lms/vendors/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
48
|
-
synth_ai/zyk/lms/vendors/core/anthropic_api.py,sha256=
|
48
|
+
synth_ai/zyk/lms/vendors/core/anthropic_api.py,sha256=vxANYEcU46n6flRJ4y5j4VrSA1ky4EXo8nWgYPLi3HU,13829
|
49
49
|
synth_ai/zyk/lms/vendors/core/gemini_api.py,sha256=I1goLy5R8eBLrun2jpnD4o87NlmzWgPrfYaeu9RZN8M,11008
|
50
50
|
synth_ai/zyk/lms/vendors/core/mistral_api.py,sha256=-EMPBEIoYxxDMxukmcmKL8AGAHPNYe4w-76gsPtmrhk,11860
|
51
51
|
synth_ai/zyk/lms/vendors/core/openai_api.py,sha256=QkQqba851EEGf9n5H31-pJ6WexhTZkdPWQap0oGy2Ho,6713
|
@@ -56,11 +56,11 @@ synth_ai/zyk/lms/vendors/supported/deepseek.py,sha256=BElW0NGpkSA62wOqzzMtDw8XR3
|
|
56
56
|
synth_ai/zyk/lms/vendors/supported/groq.py,sha256=Fbi7QvhdLx0F-VHO5PY-uIQlPR0bo3C9h1MvIOx8nz0,388
|
57
57
|
synth_ai/zyk/lms/vendors/supported/ollama.py,sha256=K30VBFRTd7NYyPmyBVRZS2sm0UB651AHp9i3wd55W64,469
|
58
58
|
synth_ai/zyk/lms/vendors/supported/together.py,sha256=Ni_jBqqGPN0PkkY-Ew64s3gNKk51k3FCpLSwlNhKbf0,342
|
59
|
-
synth_ai-0.1.0.
|
59
|
+
synth_ai-0.1.0.dev33.dist-info/licenses/LICENSE,sha256=ynhjRQUfqA_RdGRATApfFA_fBAy9cno04sLtLUqxVFM,1069
|
60
60
|
tests/test_agent.py,sha256=CjPPWuMWC_TzX1DkDald-bbAxgjXE-HPQvFhq2B--5k,22363
|
61
61
|
tests/test_recursive_structured_outputs.py,sha256=Ne-9XwnOxN7eSpGbNHOpegR-sRj589I84T6y8Z_4QnA,5781
|
62
62
|
tests/test_structured_outputs.py,sha256=J7sfbGZ7OeB5ONIKpcCTymyayNyAdFfGokC1bcUrSx0,3651
|
63
|
-
synth_ai-0.1.0.
|
64
|
-
synth_ai-0.1.0.
|
65
|
-
synth_ai-0.1.0.
|
66
|
-
synth_ai-0.1.0.
|
63
|
+
synth_ai-0.1.0.dev33.dist-info/METADATA,sha256=dft68cr1vKV74EF4tB03XmXxX7WMmmTuCinGG_5Cmxk,2702
|
64
|
+
synth_ai-0.1.0.dev33.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
65
|
+
synth_ai-0.1.0.dev33.dist-info/top_level.txt,sha256=5GzJO9j-KbJ_4ppxhmCUa_qdhHM4-9cHHNU76yAI8do,42
|
66
|
+
synth_ai-0.1.0.dev33.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|