synth-ai 0.1.0.dev28__py3-none-any.whl → 0.1.0.dev29__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.
Files changed (38) hide show
  1. public_tests/test_agent.py +11 -11
  2. public_tests/test_all_structured_outputs.py +32 -37
  3. public_tests/test_anthropic_structured_outputs.py +0 -0
  4. public_tests/test_deepseek_structured_outputs.py +0 -0
  5. public_tests/test_deepseek_tools.py +64 -0
  6. public_tests/test_gemini_structured_outputs.py +106 -0
  7. public_tests/test_models.py +27 -27
  8. public_tests/test_openai_structured_outputs.py +106 -0
  9. public_tests/test_reasoning_models.py +9 -7
  10. public_tests/test_recursive_structured_outputs.py +30 -30
  11. public_tests/test_structured.py +137 -0
  12. public_tests/test_structured_outputs.py +22 -13
  13. public_tests/test_text.py +160 -0
  14. public_tests/test_tools.py +300 -0
  15. synth_ai/__init__.py +1 -4
  16. synth_ai/zyk/__init__.py +2 -2
  17. synth_ai/zyk/lms/caching/ephemeral.py +54 -32
  18. synth_ai/zyk/lms/caching/handler.py +43 -15
  19. synth_ai/zyk/lms/caching/persistent.py +55 -27
  20. synth_ai/zyk/lms/core/main.py +26 -14
  21. synth_ai/zyk/lms/core/vendor_clients.py +1 -1
  22. synth_ai/zyk/lms/structured_outputs/handler.py +79 -45
  23. synth_ai/zyk/lms/structured_outputs/rehabilitate.py +3 -2
  24. synth_ai/zyk/lms/tools/base.py +104 -0
  25. synth_ai/zyk/lms/vendors/base.py +22 -6
  26. synth_ai/zyk/lms/vendors/core/anthropic_api.py +130 -95
  27. synth_ai/zyk/lms/vendors/core/gemini_api.py +153 -34
  28. synth_ai/zyk/lms/vendors/core/mistral_api.py +160 -54
  29. synth_ai/zyk/lms/vendors/core/openai_api.py +64 -53
  30. synth_ai/zyk/lms/vendors/openai_standard.py +197 -41
  31. synth_ai/zyk/lms/vendors/supported/deepseek.py +55 -0
  32. {synth_ai-0.1.0.dev28.dist-info → synth_ai-0.1.0.dev29.dist-info}/METADATA +2 -5
  33. synth_ai-0.1.0.dev29.dist-info/RECORD +65 -0
  34. public_tests/test_sonnet_thinking.py +0 -217
  35. synth_ai-0.1.0.dev28.dist-info/RECORD +0 -57
  36. {synth_ai-0.1.0.dev28.dist-info → synth_ai-0.1.0.dev29.dist-info}/WHEEL +0 -0
  37. {synth_ai-0.1.0.dev28.dist-info → synth_ai-0.1.0.dev29.dist-info}/licenses/LICENSE +0 -0
  38. {synth_ai-0.1.0.dev28.dist-info → synth_ai-0.1.0.dev29.dist-info}/top_level.txt +0 -0
@@ -1,217 +0,0 @@
1
- import asyncio
2
- import unittest
3
-
4
- from synth_ai.zyk import LM
5
-
6
-
7
- class TestSonnetThinking(unittest.TestCase):
8
- @classmethod
9
- def setUpClass(cls):
10
- cls.lm = LM(
11
- model_name="claude-3-7-sonnet-latest",
12
- formatting_model_name="gpt-4o-mini",
13
- temperature=0,
14
- )
15
- # Set reasoning_effort in lm_config
16
- cls.lm.lm_config["reasoning_effort"] = "high"
17
-
18
- async def test_thinking_response(self):
19
- messages = [
20
- {"role": "system", "content": "You are a helpful AI assistant."},
21
- {
22
- "role": "user",
23
- "content": "Please solve this math problem step by step: If a train travels at 60 mph for 2.5 hours, how far does it travel?",
24
- },
25
- ]
26
-
27
- response = await self.lm.respond_async(messages=messages)
28
- print("\n=== Math Problem Test ===")
29
- print(f"Response:\n{response}\n")
30
- self.assertIsInstance(response, str)
31
- self.assertGreater(len(response), 0)
32
-
33
- # Test that the response includes numerical calculation
34
- self.assertTrue(any(char.isdigit() for char in response))
35
-
36
- async def test_thinking_structured_output(self):
37
- from pydantic import BaseModel
38
-
39
- class MathSolution(BaseModel):
40
- steps: list[str]
41
- final_answer: float
42
- units: str
43
-
44
- messages = [
45
- {"role": "system", "content": "You are a math problem solver."},
46
- {
47
- "role": "user",
48
- "content": "If a car travels at 30 mph for 45 minutes, how far does it travel? Provide steps.",
49
- },
50
- ]
51
-
52
- response = await self.lm.respond_async(
53
- messages=messages, response_model=MathSolution
54
- )
55
-
56
- print("\n=== Structured Math Problem Test ===")
57
- print(f"Steps:")
58
- for i, step in enumerate(response.steps, 1):
59
- print(f"{i}. {step}")
60
- print(f"Final Answer: {response.final_answer} {response.units}\n")
61
-
62
- self.assertIsInstance(response, MathSolution)
63
- self.assertGreater(len(response.steps), 0)
64
- self.assertIsInstance(response.final_answer, float)
65
- self.assertIsInstance(response.units, str)
66
-
67
- async def test_thinking_with_high_effort(self):
68
- messages = [
69
- {
70
- "role": "system",
71
- "content": "You are a problem-solving AI. Break down complex problems into detailed steps.",
72
- },
73
- {
74
- "role": "user",
75
- "content": "Design a system to automate a coffee shop's inventory management. Consider all aspects.",
76
- },
77
- ]
78
-
79
- print("\n=== High Effort Thinking Test ===")
80
- response = await self.lm.respond_async(messages=messages)
81
- print(f"High Effort Response:\n{response}\n")
82
- self.assertIsInstance(response, str)
83
- self.assertGreater(len(response), 100) # Expecting detailed response
84
-
85
- # Test with medium effort
86
- lm_medium = LM(
87
- model_name="claude-3-7-sonnet-latest",
88
- formatting_model_name="gpt-4o-mini",
89
- temperature=0,
90
- )
91
- lm_medium.lm_config["reasoning_effort"] = "medium"
92
- print("\n=== Medium Effort Thinking Test ===")
93
- response_medium = await lm_medium.respond_async(messages=messages)
94
- print(f"Medium Effort Response:\n{response_medium}\n")
95
- self.assertIsInstance(response_medium, str)
96
-
97
- async def test_thinking_blocks_attributes(self):
98
- """Test to verify thinking blocks have the correct attributes and structure"""
99
- messages = [
100
- {"role": "system", "content": "You are a helpful AI assistant."},
101
- {
102
- "role": "user",
103
- "content": "Please solve this math problem step by step: If a train travels at 60 mph for 2.5 hours, how far does it travel?",
104
- },
105
- ]
106
-
107
- print("\n=== Testing Thinking Blocks Structure ===")
108
- try:
109
- response = await self.lm.respond_async(messages=messages)
110
- print(f"Response received successfully: {response[:100]}...")
111
- self.assertIsInstance(response, str)
112
- self.assertGreater(len(response), 0)
113
- except AttributeError as e:
114
- if "'TextBlock' object has no attribute 'value'" in str(e):
115
- self.fail(
116
- "TextBlock missing 'value' attribute - API response structure may have changed"
117
- )
118
- raise
119
-
120
- async def test_thinking_blocks_with_structured_output(self):
121
- """Test thinking blocks with structured output to verify attribute handling"""
122
- from pydantic import BaseModel
123
-
124
- class SimpleResponse(BaseModel):
125
- answer: str
126
- explanation: str
127
-
128
- messages = [
129
- {"role": "system", "content": "You are a helpful AI assistant."},
130
- {"role": "user", "content": "What is 2+2? Provide answer and explanation."},
131
- ]
132
-
133
- print("\n=== Testing Thinking Blocks with Structured Output ===")
134
- try:
135
- response = await self.lm.respond_async(
136
- messages=messages, response_model=SimpleResponse
137
- )
138
- print(f"Structured response received: {response}")
139
- self.assertIsInstance(response, SimpleResponse)
140
- self.assertTrue(hasattr(response, "answer"))
141
- self.assertTrue(hasattr(response, "explanation"))
142
- except AttributeError as e:
143
- if "'TextBlock' object has no attribute 'value'" in str(e):
144
- self.fail("TextBlock missing 'value' attribute in structured output")
145
- raise
146
-
147
- async def test_thinking_blocks_raw_response(self):
148
- """Test to examine the raw response structure from the API"""
149
- messages = [
150
- {"role": "system", "content": "You are a helpful AI assistant."},
151
- {"role": "user", "content": "Count from 1 to 3."},
152
- ]
153
-
154
- print("\n=== Testing Raw Response Structure ===")
155
- try:
156
- # Access the raw response if possible
157
- response = await self.lm.respond_async(messages=messages)
158
- print(f"Raw response type: {type(response)}")
159
- print(f"Raw response content: {response}")
160
-
161
- # Add detailed response structure inspection
162
- print("\nResponse Structure Details:")
163
- print(f"Is string: {isinstance(response, str)}")
164
- if hasattr(response, "content"):
165
- for i, block in enumerate(response.content):
166
- print(f"\nBlock {i}:")
167
- print(f"Type: {block.type}")
168
- print(f"Available attributes: {dir(block)}")
169
- if hasattr(block, "text"):
170
- print(f"Has .text: {block.text}")
171
- if hasattr(block, "value"):
172
- print(f"Has .value: {block.value}")
173
-
174
- self.assertIsInstance(response, str)
175
- except Exception as e:
176
- print(f"Exception type: {type(e)}")
177
- print(f"Exception message: {str(e)}")
178
- print(f"Full exception details: {dir(e)}")
179
- raise
180
-
181
- async def test_thinking_blocks_structure(self):
182
- """Test specifically for thinking blocks structure"""
183
- messages = [
184
- {"role": "system", "content": "You are a helpful AI assistant."},
185
- {"role": "user", "content": "What is 2+2?"},
186
- ]
187
-
188
- print("\n=== Testing Thinking Blocks Structure ===")
189
- try:
190
- # Set high reasoning effort to trigger thinking
191
- self.lm.lm_config["reasoning_effort"] = "high"
192
- response = await self.lm.respond_async(messages=messages)
193
- print(f"Response with thinking:\n{response}")
194
- self.assertIsInstance(response, str)
195
- self.assertGreater(len(response), 0)
196
- except AttributeError as e:
197
- print(f"Attribute Error Details:")
198
- print(f"Error message: {str(e)}")
199
- print(f"Error type: {type(e)}")
200
- if hasattr(e, "__context__"):
201
- print(f"Context: {e.__context__}")
202
- raise
203
-
204
- def test_all(self):
205
- print("\nStarting Claude 3.7 Sonnet Thinking Tests...")
206
- asyncio.run(self.test_thinking_response())
207
- asyncio.run(self.test_thinking_structured_output())
208
- asyncio.run(self.test_thinking_with_high_effort())
209
- asyncio.run(self.test_thinking_blocks_attributes())
210
- asyncio.run(self.test_thinking_blocks_with_structured_output())
211
- asyncio.run(self.test_thinking_blocks_raw_response())
212
- asyncio.run(self.test_thinking_blocks_structure())
213
- print("\nAll tests completed successfully!")
214
-
215
-
216
- if __name__ == "__main__":
217
- unittest.main()
@@ -1,57 +0,0 @@
1
- private_tests/try_synth_sdk.py,sha256=vk4lUEfpQfLACFl6Qw468t_lsuYxuoIIr05WRgWKGKY,24
2
- public_tests/test_agent.py,sha256=CjPPWuMWC_TzX1DkDald-bbAxgjXE-HPQvFhq2B--5k,22363
3
- public_tests/test_all_structured_outputs.py,sha256=x7Gj5Ykpw8Ut_XlSOEBHRLJSagYSHDsO1unrMSlv_Vw,6534
4
- public_tests/test_models.py,sha256=7ZJ2HPDZWhcIeZDDu8Iyt5lOy1xpKpYHM8FzsyEKQmc,5703
5
- public_tests/test_reasoning_models.py,sha256=twKNTrWyeTgtqSC2A4V0g79Uq_SjZiBeWp6ntJIAGNM,2779
6
- public_tests/test_recursive_structured_outputs.py,sha256=Ne-9XwnOxN7eSpGbNHOpegR-sRj589I84T6y8Z_4QnA,5781
7
- public_tests/test_sonnet_thinking.py,sha256=jZREMZ4JMDkBflqwJbzd-OQ4PUEjn5m4VgwjSCX04MQ,8749
8
- public_tests/test_structured_outputs.py,sha256=MZitgGedFlvxeaVFzuDQb2xXs8apwvDLTINpGBfsTdM,3653
9
- public_tests/test_synth_sdk.py,sha256=jqJHKpvBn9qj21P76z9onXfPg88jyUmBTKmdvCsQMk8,14885
10
- synth_ai/__init__.py,sha256=2siivzLbT2r-EA7m91dcJB-6Vsurc5_sX3WiKf4_o8Y,198
11
- synth_ai/zyk/__init__.py,sha256=zoPor1PI2OrgpCu-MBLZXcX1jAbSgD9q0kqZpTghTcQ,60
12
- synth_ai/zyk/lms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- synth_ai/zyk/lms/config.py,sha256=CcN5NL99j0UZubyGo-MUfbPD3pWosAMju_sqgfvqLVY,201
14
- synth_ai/zyk/lms/caching/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- synth_ai/zyk/lms/caching/constants.py,sha256=fPi3x9p-yRdvixMSIyclvmwmwCRliXLXQjEm6dRnG8s,52
16
- synth_ai/zyk/lms/caching/dbs.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- synth_ai/zyk/lms/caching/ephemeral.py,sha256=OduhhWc8TdEohli0HJkbtTxVM0egSxmOHDVfErTXTPw,1725
18
- synth_ai/zyk/lms/caching/handler.py,sha256=sewq5rRfqXHzCEiXvdckbuxYp9ze_EjVSndnUTsOAJY,2962
19
- synth_ai/zyk/lms/caching/initialize.py,sha256=zZls6RKAax6Z-8oJInGaSg_RPN_fEZ6e_RCX64lMLJw,416
20
- synth_ai/zyk/lms/caching/persistent.py,sha256=mQmP1z0rWVYjxwso5zIwd51Df2dWZvdHonuqsOY6SFI,2075
21
- synth_ai/zyk/lms/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- synth_ai/zyk/lms/core/all.py,sha256=wakK0HhvYRuaQZmxClURyNf3vUkTbm3OABw3TgpMjOQ,1185
23
- synth_ai/zyk/lms/core/exceptions.py,sha256=K0BVdAzxVIchsvYZAaHEH1GAWBZvpxhFi-SPcJOjyPQ,205
24
- synth_ai/zyk/lms/core/main.py,sha256=fdAPBjnyOfLBPtcD0D79tn0f7SrKv49zCP6IhiAeH9Y,9019
25
- synth_ai/zyk/lms/core/vendor_clients.py,sha256=s14XHkiswIpNG8UfkYRbkdpuPi3UlzWhQN3pM2-r8PU,2781
26
- synth_ai/zyk/lms/cost/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- synth_ai/zyk/lms/cost/monitor.py,sha256=cSKIvw6WdPZIRubADWxQoh1MdB40T8-jjgfNUeUHIn0,5
28
- synth_ai/zyk/lms/cost/statefulness.py,sha256=TOsuXL8IjtKOYJ2aJQF8TwJVqn_wQ7AIwJJmdhMye7U,36
29
- synth_ai/zyk/lms/structured_outputs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
- synth_ai/zyk/lms/structured_outputs/handler.py,sha256=DJ9-S4l5jGUaLjx2yulmS_0AiLGty3YRZrOaWiOI0nQ,14680
31
- synth_ai/zyk/lms/structured_outputs/inject.py,sha256=Fy-zDeleRxOZ8ZRM6IuZ6CP2XZnMe4K2PEn4Q9c_KPY,11777
32
- synth_ai/zyk/lms/structured_outputs/rehabilitate.py,sha256=_QOfnI1rJxIE9-zUMhC0PedCOr6y5m6WuGScDb5gcUo,7787
33
- synth_ai/zyk/lms/vendors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- synth_ai/zyk/lms/vendors/base.py,sha256=bs27mNfrCjQ5NsmxWnKfxZmpoAa9mTNAFr9AnGVwqLk,552
35
- synth_ai/zyk/lms/vendors/constants.py,sha256=zqCOyXZqo297wboR9EKVSkvpq6JCMSJyeso8HdZPKa4,102
36
- synth_ai/zyk/lms/vendors/openai_standard.py,sha256=TJz1u6IcJ1KHjbofyHs0rlFa13smVXFTtqBSVqEYJqo,5818
37
- synth_ai/zyk/lms/vendors/retries.py,sha256=m-WvAiPix9ovnO2S-m53Td5VZDWBVBFuHuSK9--OVxw,38
38
- synth_ai/zyk/lms/vendors/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- synth_ai/zyk/lms/vendors/core/anthropic_api.py,sha256=l75WSqR7pS0gNRI-x0GyTkz8UL40o9Q2xwK-Rq5pddk,12592
40
- synth_ai/zyk/lms/vendors/core/gemini_api.py,sha256=Cp8BpSk1yCC3SYrEK1pFOnCdUc65XIPonFEirZ6W2rA,5395
41
- synth_ai/zyk/lms/vendors/core/mistral_api.py,sha256=m11ItQ46VyyCUy6hv6mw5OmiqwHr07wV_NJVNnPHgiA,8080
42
- synth_ai/zyk/lms/vendors/core/openai_api.py,sha256=700M0QfAxDZXAURnlY--ReEwIEPJPMCwY0JIpu4vptM,5881
43
- synth_ai/zyk/lms/vendors/local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
- synth_ai/zyk/lms/vendors/local/ollama.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
- synth_ai/zyk/lms/vendors/supported/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
- synth_ai/zyk/lms/vendors/supported/deepseek.py,sha256=diFfdhPMO5bLFZxnYj7VT0v6jKTlOYESBkspUuVa2eY,529
47
- synth_ai/zyk/lms/vendors/supported/groq.py,sha256=Fbi7QvhdLx0F-VHO5PY-uIQlPR0bo3C9h1MvIOx8nz0,388
48
- synth_ai/zyk/lms/vendors/supported/ollama.py,sha256=K30VBFRTd7NYyPmyBVRZS2sm0UB651AHp9i3wd55W64,469
49
- synth_ai/zyk/lms/vendors/supported/together.py,sha256=Ni_jBqqGPN0PkkY-Ew64s3gNKk51k3FCpLSwlNhKbf0,342
50
- synth_ai-0.1.0.dev28.dist-info/licenses/LICENSE,sha256=ynhjRQUfqA_RdGRATApfFA_fBAy9cno04sLtLUqxVFM,1069
51
- tests/test_agent.py,sha256=CjPPWuMWC_TzX1DkDald-bbAxgjXE-HPQvFhq2B--5k,22363
52
- tests/test_recursive_structured_outputs.py,sha256=Ne-9XwnOxN7eSpGbNHOpegR-sRj589I84T6y8Z_4QnA,5781
53
- tests/test_structured_outputs.py,sha256=J7sfbGZ7OeB5ONIKpcCTymyayNyAdFfGokC1bcUrSx0,3651
54
- synth_ai-0.1.0.dev28.dist-info/METADATA,sha256=HLddXeCXyIpgrBJSD8sQ4iKH7MmArT_-XhGhlVwv7tE,2795
55
- synth_ai-0.1.0.dev28.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
56
- synth_ai-0.1.0.dev28.dist-info/top_level.txt,sha256=5GzJO9j-KbJ_4ppxhmCUa_qdhHM4-9cHHNU76yAI8do,42
57
- synth_ai-0.1.0.dev28.dist-info/RECORD,,