synth-ai 0.2.0__py3-none-any.whl → 0.2.1.dev0__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.
- synth_ai/__init__.py +28 -2
- synth_ai/core/system.py +4 -0
- synth_ai/environments/__init__.py +35 -0
- synth_ai/environments/environment/__init__.py +1 -0
- synth_ai/environments/environment/artifacts/__init__.py +1 -0
- synth_ai/environments/environment/artifacts/base.py +50 -0
- synth_ai/environments/environment/core.py +22 -0
- synth_ai/environments/environment/db/__init__.py +1 -0
- synth_ai/environments/environment/db/sqlite.py +45 -0
- synth_ai/environments/environment/registry.py +24 -0
- synth_ai/environments/environment/resources/sqlite.py +46 -0
- synth_ai/environments/environment/results.py +1 -0
- synth_ai/environments/environment/rewards/__init__.py +1 -0
- synth_ai/environments/environment/rewards/core.py +28 -0
- synth_ai/environments/environment/shared_engine.py +26 -0
- synth_ai/environments/environment/tools/__init__.py +34 -0
- synth_ai/environments/examples/__init__.py +1 -0
- synth_ai/environments/examples/crafter_classic/__init__.py +8 -0
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_comprehensive_evaluation.py +58 -0
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_evaluation_browser.py +152 -0
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_evaluation_framework.py +1194 -0
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_quick_evaluation.py +51 -0
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_react_agent.py +872 -0
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_trace_evaluation.py +1412 -0
- synth_ai/environments/examples/crafter_classic/agent_demos/test_crafter_react_agent.py +1110 -0
- synth_ai/environments/examples/crafter_classic/config_logging.py +111 -0
- synth_ai/environments/examples/crafter_classic/engine.py +502 -0
- synth_ai/environments/examples/crafter_classic/engine_deterministic_patch.py +63 -0
- synth_ai/environments/examples/crafter_classic/engine_helpers/action_map.py +5 -0
- synth_ai/environments/examples/crafter_classic/engine_helpers/serialization.py +74 -0
- synth_ai/environments/examples/crafter_classic/environment.py +255 -0
- synth_ai/environments/examples/crafter_classic/taskset.py +228 -0
- synth_ai/environments/examples/enron/agent_demos/test_synth_react.py +535 -0
- synth_ai/environments/examples/enron/art_helpers/email_search_tools.py +156 -0
- synth_ai/environments/examples/enron/art_helpers/local_email_db.py +280 -0
- synth_ai/environments/examples/enron/art_helpers/types_enron.py +24 -0
- synth_ai/environments/examples/enron/engine.py +291 -0
- synth_ai/environments/examples/enron/environment.py +165 -0
- synth_ai/environments/examples/enron/taskset.py +112 -0
- synth_ai/environments/examples/enron/units/keyword_stats.py +111 -0
- synth_ai/environments/examples/enron/units/test_email_index.py +8 -0
- synth_ai/environments/examples/minigrid/__init__.py +48 -0
- synth_ai/environments/examples/minigrid/agent_demos/minigrid_evaluation_framework.py +1188 -0
- synth_ai/environments/examples/minigrid/agent_demos/minigrid_quick_evaluation.py +47 -0
- synth_ai/environments/examples/minigrid/agent_demos/minigrid_react_agent.py +562 -0
- synth_ai/environments/examples/minigrid/agent_demos/minigrid_trace_evaluation.py +220 -0
- synth_ai/environments/examples/minigrid/agent_demos/test_minigrid_react_agent.py +393 -0
- synth_ai/environments/examples/minigrid/engine.py +589 -0
- synth_ai/environments/examples/minigrid/environment.py +274 -0
- synth_ai/environments/examples/minigrid/environment_mapping.py +242 -0
- synth_ai/environments/examples/minigrid/puzzle_loader.py +416 -0
- synth_ai/environments/examples/minigrid/taskset.py +583 -0
- synth_ai/environments/examples/minigrid/units/test_action_behavior.py +226 -0
- synth_ai/environments/examples/minigrid/units/test_debug_messages.py +83 -0
- synth_ai/environments/examples/minigrid/units/test_exploration.py +120 -0
- synth_ai/environments/examples/minigrid/units/test_minigrid_engine.py +214 -0
- synth_ai/environments/examples/minigrid/units/test_minigrid_environment.py +238 -0
- synth_ai/environments/examples/minigrid/units/test_minigrid_environment_mapping.py +301 -0
- synth_ai/environments/examples/minigrid/units/test_minigrid_taskset.py +210 -0
- synth_ai/environments/examples/nethack/__init__.py +7 -0
- synth_ai/environments/examples/nethack/achievements.py +337 -0
- synth_ai/environments/examples/nethack/agent_demos/nethack_evaluation_framework.py +981 -0
- synth_ai/environments/examples/nethack/agent_demos/nethack_quick_evaluation.py +74 -0
- synth_ai/environments/examples/nethack/agent_demos/nethack_react_agent.py +832 -0
- synth_ai/environments/examples/nethack/agent_demos/test_nethack_react_agent.py +1112 -0
- synth_ai/environments/examples/nethack/engine.py +738 -0
- synth_ai/environments/examples/nethack/environment.py +255 -0
- synth_ai/environments/examples/nethack/helpers/__init__.py +42 -0
- synth_ai/environments/examples/nethack/helpers/action_mapping.py +301 -0
- synth_ai/environments/examples/nethack/helpers/nle_wrapper.py +401 -0
- synth_ai/environments/examples/nethack/helpers/observation_utils.py +433 -0
- synth_ai/environments/examples/nethack/helpers/recording_wrapper.py +201 -0
- synth_ai/environments/examples/nethack/helpers/trajectory_recorder.py +268 -0
- synth_ai/environments/examples/nethack/helpers/visualization/replay_viewer.py +308 -0
- synth_ai/environments/examples/nethack/helpers/visualization/visualizer.py +430 -0
- synth_ai/environments/examples/nethack/taskset.py +323 -0
- synth_ai/environments/examples/nethack/units/test_nethack_engine.py +277 -0
- synth_ai/environments/examples/nethack/units/test_nethack_environment.py +281 -0
- synth_ai/environments/examples/nethack/units/test_nethack_taskset.py +213 -0
- synth_ai/environments/examples/nethack/units/test_recording.py +307 -0
- synth_ai/environments/examples/red/__init__.py +7 -0
- synth_ai/environments/examples/red/agent_demos/__init__.py +1 -0
- synth_ai/environments/examples/red/agent_demos/test_synth_react.py +1471 -0
- synth_ai/environments/examples/red/config_logging.py +110 -0
- synth_ai/environments/examples/red/engine.py +693 -0
- synth_ai/environments/examples/red/engine_helpers/__init__.py +1 -0
- synth_ai/environments/examples/red/engine_helpers/memory_map.py +28 -0
- synth_ai/environments/examples/red/engine_helpers/reward_components.py +275 -0
- synth_ai/environments/examples/red/engine_helpers/reward_library/__init__.py +142 -0
- synth_ai/environments/examples/red/engine_helpers/reward_library/adaptive_rewards.py +56 -0
- synth_ai/environments/examples/red/engine_helpers/reward_library/battle_rewards.py +283 -0
- synth_ai/environments/examples/red/engine_helpers/reward_library/composite_rewards.py +149 -0
- synth_ai/environments/examples/red/engine_helpers/reward_library/economy_rewards.py +137 -0
- synth_ai/environments/examples/red/engine_helpers/reward_library/efficiency_rewards.py +56 -0
- synth_ai/environments/examples/red/engine_helpers/reward_library/exploration_rewards.py +330 -0
- synth_ai/environments/examples/red/engine_helpers/reward_library/novelty_rewards.py +120 -0
- synth_ai/environments/examples/red/engine_helpers/reward_library/pallet_town_rewards.py +558 -0
- synth_ai/environments/examples/red/engine_helpers/reward_library/pokemon_rewards.py +312 -0
- synth_ai/environments/examples/red/engine_helpers/reward_library/social_rewards.py +147 -0
- synth_ai/environments/examples/red/engine_helpers/reward_library/story_rewards.py +246 -0
- synth_ai/environments/examples/red/engine_helpers/screen_analysis.py +367 -0
- synth_ai/environments/examples/red/engine_helpers/state_extraction.py +139 -0
- synth_ai/environments/examples/red/environment.py +235 -0
- synth_ai/environments/examples/red/taskset.py +77 -0
- synth_ai/environments/examples/red/test_fixes.py +125 -0
- synth_ai/environments/examples/red/test_fixes_mock.py +148 -0
- synth_ai/environments/examples/red/units/__init__.py +1 -0
- synth_ai/environments/examples/red/units/test_basic_functionality.py +97 -0
- synth_ai/environments/examples/red/units/test_button_press_requirements.py +217 -0
- synth_ai/environments/examples/red/units/test_engine.py +192 -0
- synth_ai/environments/examples/red/units/test_environment.py +455 -0
- synth_ai/environments/examples/red/units/test_exploration_strategy.py +227 -0
- synth_ai/environments/examples/red/units/test_integration.py +217 -0
- synth_ai/environments/examples/red/units/test_memory_extraction.py +111 -0
- synth_ai/environments/examples/red/units/test_menu_bug_reproduction.py +1100 -0
- synth_ai/environments/examples/red/units/test_movement_debug.py +255 -0
- synth_ai/environments/examples/red/units/test_pokemon_mcts_debug.py +163 -0
- synth_ai/environments/examples/red/units/test_pokemon_mcts_verbose.py +117 -0
- synth_ai/environments/examples/red/units/test_red_basic.py +145 -0
- synth_ai/environments/examples/red/units/test_red_comprehensive.py +323 -0
- synth_ai/environments/examples/red/units/test_retry_movement.py +195 -0
- synth_ai/environments/examples/red/units/test_reward_components.py +186 -0
- synth_ai/environments/examples/red/units/test_rom_integration.py +260 -0
- synth_ai/environments/examples/red/units/test_taskset.py +116 -0
- synth_ai/environments/examples/red/units/test_tree.py +448 -0
- synth_ai/environments/examples/sokoban/__init__.py +1 -0
- synth_ai/environments/examples/sokoban/agent_demos/sokoban_full_eval.py +900 -0
- synth_ai/environments/examples/sokoban/agent_demos/test_dspy_react.py +1 -0
- synth_ai/environments/examples/sokoban/agent_demos/test_sokoban_react_agent.py +498 -0
- synth_ai/environments/examples/sokoban/agent_demos/test_synth_lats.py +1 -0
- synth_ai/environments/examples/sokoban/agent_demos/test_synth_react_locally.py +748 -0
- synth_ai/environments/examples/sokoban/agent_demos/test_synth_react_service.py +296 -0
- synth_ai/environments/examples/sokoban/engine.py +675 -0
- synth_ai/environments/examples/sokoban/engine_helpers/__init__.py +1 -0
- synth_ai/environments/examples/sokoban/engine_helpers/room_utils.py +656 -0
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/__init__.py +17 -0
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/__init__.py +3 -0
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/boxoban_env.py +129 -0
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/render_utils.py +370 -0
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/room_utils.py +331 -0
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env.py +305 -0
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_fixed_targets.py +66 -0
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_pull.py +114 -0
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_two_player.py +122 -0
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_variations.py +394 -0
- synth_ai/environments/examples/sokoban/environment.py +228 -0
- synth_ai/environments/examples/sokoban/generate_verified_puzzles.py +438 -0
- synth_ai/environments/examples/sokoban/puzzle_loader.py +311 -0
- synth_ai/environments/examples/sokoban/taskset.py +425 -0
- synth_ai/environments/examples/sokoban/units/astar_common.py +94 -0
- synth_ai/environments/examples/sokoban/units/test_building_task_set.py +49 -0
- synth_ai/environments/examples/sokoban/units/test_false_positive.py +120 -0
- synth_ai/environments/examples/sokoban/units/test_simple_run_through_environment.py +119 -0
- synth_ai/environments/examples/sokoban/units/test_sokoban_environment.py +98 -0
- synth_ai/environments/examples/sokoban/units/test_tree.py +364 -0
- synth_ai/environments/examples/tictactoe/__init__.py +1 -0
- synth_ai/environments/examples/tictactoe/agent_demos/test_synth_react.py +266 -0
- synth_ai/environments/examples/tictactoe/agent_demos/test_tictactoe_react_agent.py +470 -0
- synth_ai/environments/examples/tictactoe/engine.py +368 -0
- synth_ai/environments/examples/tictactoe/environment.py +239 -0
- synth_ai/environments/examples/tictactoe/taskset.py +214 -0
- synth_ai/environments/examples/tictactoe/units/test_tictactoe_engine.py +393 -0
- synth_ai/environments/examples/tictactoe/units/test_tictactoe_environment.py +493 -0
- synth_ai/environments/examples/tictactoe/units/test_tictactoe_taskset.py +191 -0
- synth_ai/environments/examples/verilog/__init__.py +10 -0
- synth_ai/environments/examples/verilog/agent_demos/test_synth_react.py +520 -0
- synth_ai/environments/examples/verilog/engine.py +328 -0
- synth_ai/environments/examples/verilog/environment.py +349 -0
- synth_ai/environments/examples/verilog/taskset.py +418 -0
- synth_ai/environments/examples/verilog/units/test_verilog_engine.py +466 -0
- synth_ai/environments/examples/verilog/units/test_verilog_environment.py +585 -0
- synth_ai/environments/examples/verilog/units/test_verilog_integration.py +383 -0
- synth_ai/environments/examples/verilog/units/test_verilog_taskset.py +457 -0
- synth_ai/environments/reproducibility/core.py +42 -0
- synth_ai/environments/reproducibility/tree.py +364 -0
- synth_ai/environments/service/app.py +78 -0
- synth_ai/environments/service/core_routes.py +775 -0
- synth_ai/environments/service/external_registry.py +57 -0
- synth_ai/environments/service/registry.py +9 -0
- synth_ai/environments/stateful/__init__.py +1 -0
- synth_ai/environments/stateful/core.py +28 -0
- synth_ai/environments/stateful/engine.py +21 -0
- synth_ai/environments/stateful/state.py +7 -0
- synth_ai/environments/tasks/api.py +19 -0
- synth_ai/environments/tasks/core.py +78 -0
- synth_ai/environments/tasks/filters.py +39 -0
- synth_ai/environments/tasks/utils.py +89 -0
- synth_ai/environments/v0_observability/history.py +3 -0
- synth_ai/environments/v0_observability/log.py +2 -0
- synth_ai/lm/caching/constants.py +1 -0
- synth_ai/{zyk/lms → lm}/caching/ephemeral.py +4 -8
- synth_ai/{zyk/lms → lm}/caching/handler.py +15 -15
- synth_ai/{zyk/lms → lm}/caching/initialize.py +2 -4
- synth_ai/{zyk/lms → lm}/caching/persistent.py +4 -10
- synth_ai/{zyk/lms → lm}/config.py +2 -1
- synth_ai/{zyk/lms → lm}/constants.py +2 -2
- synth_ai/{zyk/lms → lm}/core/all.py +10 -10
- synth_ai/{zyk/lms → lm}/core/main.py +57 -33
- synth_ai/{zyk/lms → lm}/core/vendor_clients.py +12 -10
- synth_ai/lm/cost/monitor.py +1 -0
- synth_ai/lm/cost/statefulness.py +1 -0
- synth_ai/lm/provider_support/__init__.py +8 -0
- synth_ai/lm/provider_support/anthropic.py +945 -0
- synth_ai/lm/provider_support/openai.py +1115 -0
- synth_ai/lm/provider_support/suppress_logging.py +31 -0
- synth_ai/{zyk/lms → lm}/structured_outputs/handler.py +58 -80
- synth_ai/{zyk/lms → lm}/structured_outputs/inject.py +6 -20
- synth_ai/{zyk/lms → lm}/structured_outputs/rehabilitate.py +6 -12
- synth_ai/{zyk/lms → lm}/vendors/core/anthropic_api.py +21 -30
- synth_ai/{zyk/lms → lm}/vendors/core/gemini_api.py +35 -32
- synth_ai/{zyk/lms → lm}/vendors/core/mistral_api.py +19 -28
- synth_ai/{zyk/lms → lm}/vendors/core/openai_api.py +26 -36
- synth_ai/{zyk/lms → lm}/vendors/openai_standard.py +29 -33
- synth_ai/{zyk/lms → lm}/vendors/retries.py +1 -1
- synth_ai/lm/vendors/supported/__init__.py +0 -0
- synth_ai/{zyk/lms → lm}/vendors/supported/custom_endpoint.py +131 -118
- synth_ai/{zyk/lms → lm}/vendors/supported/deepseek.py +4 -8
- synth_ai/{zyk/lms → lm}/vendors/supported/grok.py +6 -8
- synth_ai/{zyk/lms → lm}/vendors/supported/groq.py +1 -1
- synth_ai/{zyk/lms → lm}/vendors/supported/ollama.py +2 -2
- synth_ai/{zyk/lms → lm}/vendors/supported/openrouter.py +18 -16
- synth_ai/{zyk/lms → lm}/vendors/supported/together.py +1 -1
- synth_ai/tracing/__init__.py +0 -0
- synth_ai/tracing/abstractions.py +224 -0
- synth_ai/tracing/base_client.py +91 -0
- synth_ai/tracing/client_manager.py +131 -0
- synth_ai/tracing/config.py +140 -0
- synth_ai/tracing/context.py +146 -0
- synth_ai/tracing/decorators.py +679 -0
- synth_ai/tracing/events/__init__.py +0 -0
- synth_ai/tracing/events/manage.py +147 -0
- synth_ai/tracing/events/scope.py +86 -0
- synth_ai/tracing/events/store.py +227 -0
- synth_ai/tracing/immediate_client.py +152 -0
- synth_ai/tracing/local.py +18 -0
- synth_ai/tracing/log_client_base.py +74 -0
- synth_ai/tracing/retry_queue.py +187 -0
- synth_ai/tracing/trackers.py +515 -0
- synth_ai/tracing/upload.py +504 -0
- synth_ai/tracing/utils.py +9 -0
- synth_ai/zyk/__init__.py +28 -2
- synth_ai-0.2.1.dev0.dist-info/METADATA +349 -0
- synth_ai-0.2.1.dev0.dist-info/RECORD +261 -0
- {synth_ai-0.2.0.dist-info → synth_ai-0.2.1.dev0.dist-info}/WHEEL +1 -1
- synth_ai/zyk/lms/caching/constants.py +0 -1
- synth_ai/zyk/lms/cost/monitor.py +0 -1
- synth_ai/zyk/lms/cost/statefulness.py +0 -1
- synth_ai-0.2.0.dist-info/METADATA +0 -36
- synth_ai-0.2.0.dist-info/RECORD +0 -50
- /synth_ai/{zyk/lms/__init__.py → environments/reproducibility/helpers.py} +0 -0
- /synth_ai/{zyk/lms/caching → lm}/__init__.py +0 -0
- /synth_ai/{zyk/lms/core → lm/caching}/__init__.py +0 -0
- /synth_ai/{zyk/lms → lm}/caching/dbs.py +0 -0
- /synth_ai/{zyk/lms/cost → lm/core}/__init__.py +0 -0
- /synth_ai/{zyk/lms → lm}/core/exceptions.py +0 -0
- /synth_ai/{zyk/lms/structured_outputs → lm/cost}/__init__.py +0 -0
- /synth_ai/{zyk/lms/vendors → lm/structured_outputs}/__init__.py +0 -0
- /synth_ai/{zyk/lms → lm}/tools/__init__.py +0 -0
- /synth_ai/{zyk/lms → lm}/tools/base.py +0 -0
- /synth_ai/{zyk/lms/vendors/core → lm/vendors}/__init__.py +0 -0
- /synth_ai/{zyk/lms → lm}/vendors/base.py +0 -0
- /synth_ai/{zyk/lms/vendors/local → lm/vendors/core}/__init__.py +0 -0
- /synth_ai/{zyk/lms/vendors/supported → lm/vendors/local}/__init__.py +0 -0
- /synth_ai/{zyk/lms → lm}/vendors/local/ollama.py +0 -0
- {synth_ai-0.2.0.dist-info → synth_ai-0.2.1.dev0.dist-info/licenses}/LICENSE +0 -0
- {synth_ai-0.2.0.dist-info → synth_ai-0.2.1.dev0.dist-info}/top_level.txt +0 -0
@@ -3,16 +3,17 @@ import os
|
|
3
3
|
|
4
4
|
from pydantic import BaseModel, Field
|
5
5
|
|
6
|
-
from synth_ai.
|
7
|
-
from synth_ai.
|
6
|
+
from synth_ai.lm.core.exceptions import StructuredOutputCoercionFailureException
|
7
|
+
from synth_ai.lm.core.vendor_clients import (
|
8
8
|
anthropic_naming_regexes,
|
9
9
|
get_client,
|
10
10
|
openai_naming_regexes,
|
11
11
|
)
|
12
|
-
from synth_ai.
|
13
|
-
from synth_ai.
|
14
|
-
from synth_ai.
|
15
|
-
from synth_ai.
|
12
|
+
from synth_ai.lm.structured_outputs.handler import StructuredOutputHandler
|
13
|
+
from synth_ai.lm.vendors.base import VendorBase
|
14
|
+
from synth_ai.lm.tools.base import BaseTool
|
15
|
+
from synth_ai.lm.config import reasoning_models
|
16
|
+
|
16
17
|
|
17
18
|
def build_messages(
|
18
19
|
sys_msg: str,
|
@@ -20,9 +21,7 @@ def build_messages(
|
|
20
21
|
images_bytes: List = [],
|
21
22
|
model_name: Optional[str] = None,
|
22
23
|
) -> List[Dict]:
|
23
|
-
if len(images_bytes) > 0 and any(
|
24
|
-
regex.match(model_name) for regex in openai_naming_regexes
|
25
|
-
):
|
24
|
+
if len(images_bytes) > 0 and any(regex.match(model_name) for regex in openai_naming_regexes):
|
26
25
|
return [
|
27
26
|
{"role": "system", "content": sys_msg},
|
28
27
|
{
|
@@ -69,7 +68,7 @@ def build_messages(
|
|
69
68
|
class LM:
|
70
69
|
"""
|
71
70
|
Language Model interface for interacting with various AI providers.
|
72
|
-
|
71
|
+
|
73
72
|
Args:
|
74
73
|
model_name: The name of the model to use.
|
75
74
|
formatting_model_name: The model to use for formatting structured outputs.
|
@@ -82,6 +81,7 @@ class LM:
|
|
82
81
|
environment variable. Supported values: "openai", "anthropic", "groq", "gemini",
|
83
82
|
"deepseek", "grok", "mistral", "openrouter", "together", or a custom string.
|
84
83
|
"""
|
84
|
+
|
85
85
|
# if str
|
86
86
|
model_name: str
|
87
87
|
client: VendorBase
|
@@ -94,16 +94,29 @@ class LM:
|
|
94
94
|
formatting_model_name: str,
|
95
95
|
temperature: float,
|
96
96
|
max_retries: Literal["None", "Few", "Many"] = "Few",
|
97
|
-
structured_output_mode: Literal[
|
98
|
-
"stringified_json", "forced_json"
|
99
|
-
] = "stringified_json",
|
97
|
+
structured_output_mode: Literal["stringified_json", "forced_json"] = "stringified_json",
|
100
98
|
synth_logging: bool = True,
|
101
|
-
provider: Optional[
|
99
|
+
provider: Optional[
|
100
|
+
Union[
|
101
|
+
Literal[
|
102
|
+
"openai",
|
103
|
+
"anthropic",
|
104
|
+
"groq",
|
105
|
+
"gemini",
|
106
|
+
"deepseek",
|
107
|
+
"grok",
|
108
|
+
"mistral",
|
109
|
+
"openrouter",
|
110
|
+
"together",
|
111
|
+
],
|
112
|
+
str,
|
113
|
+
]
|
114
|
+
] = None,
|
102
115
|
):
|
103
116
|
# print("Structured output mode", structured_output_mode)
|
104
117
|
# Check for environment variable if provider is not specified
|
105
118
|
effective_provider = provider or os.environ.get("SYNTH_AI_DEFAULT_PROVIDER")
|
106
|
-
|
119
|
+
|
107
120
|
self.client = get_client(
|
108
121
|
model_name,
|
109
122
|
with_formatting=structured_output_mode == "forced_json",
|
@@ -112,7 +125,9 @@ class LM:
|
|
112
125
|
)
|
113
126
|
# print(self.client.__class__)
|
114
127
|
|
115
|
-
formatting_client = get_client(
|
128
|
+
formatting_client = get_client(
|
129
|
+
formatting_model_name, with_formatting=True, synth_logging=synth_logging, provider=None
|
130
|
+
)
|
116
131
|
|
117
132
|
max_retries_dict = {"None": 0, "Few": 2, "Many": 5}
|
118
133
|
self.structured_output_handler = StructuredOutputHandler(
|
@@ -143,12 +158,12 @@ class LM:
|
|
143
158
|
tools: Optional[List[BaseTool]] = None,
|
144
159
|
reasoning_effort: str = "low",
|
145
160
|
):
|
146
|
-
assert (system_message is None) == (
|
147
|
-
user_message
|
148
|
-
)
|
149
|
-
assert (
|
150
|
-
|
151
|
-
)
|
161
|
+
assert (system_message is None) == (user_message is None), (
|
162
|
+
"Must provide both system_message and user_message or neither"
|
163
|
+
)
|
164
|
+
assert (messages is None) != (system_message is None), (
|
165
|
+
"Must provide either messages or system_message/user_message pair, but not both"
|
166
|
+
)
|
152
167
|
assert not (response_model and tools), "Cannot provide both response_model and tools"
|
153
168
|
if messages is None:
|
154
169
|
messages = build_messages(
|
@@ -185,8 +200,12 @@ class LM:
|
|
185
200
|
reasoning_effort=reasoning_effort,
|
186
201
|
)
|
187
202
|
assert isinstance(result.raw_response, str), "Raw response must be a string"
|
188
|
-
assert (
|
189
|
-
|
203
|
+
assert (
|
204
|
+
isinstance(result.structured_output, BaseModel) or result.structured_output is None
|
205
|
+
), "Structured output must be a Pydantic model or None"
|
206
|
+
assert isinstance(result.tool_calls, list) or result.tool_calls is None, (
|
207
|
+
"Tool calls must be a list or None"
|
208
|
+
)
|
190
209
|
return result
|
191
210
|
|
192
211
|
async def respond_async(
|
@@ -201,12 +220,12 @@ class LM:
|
|
201
220
|
reasoning_effort: str = "low",
|
202
221
|
):
|
203
222
|
# "In respond_async")
|
204
|
-
assert (system_message is None) == (
|
205
|
-
user_message
|
206
|
-
)
|
207
|
-
assert (
|
208
|
-
|
209
|
-
)
|
223
|
+
assert (system_message is None) == (user_message is None), (
|
224
|
+
"Must provide both system_message and user_message or neither"
|
225
|
+
)
|
226
|
+
assert (messages is None) != (system_message is None), (
|
227
|
+
"Must provide either messages or system_message/user_message pair, but not both"
|
228
|
+
)
|
210
229
|
|
211
230
|
assert not (response_model and tools), "Cannot provide both response_model and tools"
|
212
231
|
if messages is None:
|
@@ -236,7 +255,7 @@ class LM:
|
|
236
255
|
reasoning_effort=reasoning_effort,
|
237
256
|
)
|
238
257
|
else:
|
239
|
-
#print("Calling API no response model")
|
258
|
+
# print("Calling API no response model")
|
240
259
|
result = await self.client._hit_api_async(
|
241
260
|
messages=messages,
|
242
261
|
model=self.model_name,
|
@@ -246,10 +265,15 @@ class LM:
|
|
246
265
|
reasoning_effort=reasoning_effort,
|
247
266
|
)
|
248
267
|
assert isinstance(result.raw_response, str), "Raw response must be a string"
|
249
|
-
assert (
|
250
|
-
|
268
|
+
assert (
|
269
|
+
isinstance(result.structured_output, BaseModel) or result.structured_output is None
|
270
|
+
), "Structured output must be a Pydantic model or None"
|
271
|
+
assert isinstance(result.tool_calls, list) or result.tool_calls is None, (
|
272
|
+
"Tool calls must be a list or None"
|
273
|
+
)
|
251
274
|
return result
|
252
275
|
|
276
|
+
|
253
277
|
if __name__ == "__main__":
|
254
278
|
import asyncio
|
255
279
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import re
|
2
2
|
from typing import Any, List, Pattern, Optional, Dict
|
3
3
|
|
4
|
-
from synth_ai.
|
4
|
+
from synth_ai.lm.core.all import (
|
5
5
|
AnthropicClient,
|
6
6
|
DeepSeekClient,
|
7
7
|
GeminiClient,
|
@@ -99,33 +99,35 @@ def get_client(
|
|
99
99
|
) -> Any:
|
100
100
|
"""
|
101
101
|
Get a vendor client for the specified model.
|
102
|
-
|
102
|
+
|
103
103
|
Args:
|
104
104
|
model_name: The name of the model to use.
|
105
105
|
with_formatting: Whether to use formatting capabilities.
|
106
106
|
synth_logging: Whether to enable Synth logging.
|
107
107
|
provider: Optional provider override. If specified, forces the use of a specific vendor
|
108
108
|
implementation regardless of model name.
|
109
|
-
|
109
|
+
|
110
110
|
Returns:
|
111
111
|
A vendor client instance.
|
112
|
-
|
112
|
+
|
113
113
|
Raises:
|
114
114
|
ValueError: If the provider is unsupported or model name is invalid.
|
115
115
|
"""
|
116
116
|
# print("With formatting", with_formatting)
|
117
|
-
|
117
|
+
|
118
118
|
# If provider is explicitly specified, use it
|
119
119
|
if provider:
|
120
120
|
if provider not in PROVIDER_MAP:
|
121
|
-
raise ValueError(
|
122
|
-
|
121
|
+
raise ValueError(
|
122
|
+
f"Unsupported provider: '{provider}'. Supported providers are: {', '.join(PROVIDER_MAP.keys())}"
|
123
|
+
)
|
124
|
+
|
123
125
|
# Log the provider override
|
124
126
|
if synth_logging:
|
125
127
|
print(f"Provider override: using '{provider}' for model '{model_name}'")
|
126
|
-
|
128
|
+
|
127
129
|
client_class = PROVIDER_MAP[provider]
|
128
|
-
|
130
|
+
|
129
131
|
# Special handling for OpenAI with formatting
|
130
132
|
if provider == "openai":
|
131
133
|
return client_class(synth_logging=synth_logging)
|
@@ -141,7 +143,7 @@ def get_client(
|
|
141
143
|
return CustomEndpointClient(endpoint_url=model_name)
|
142
144
|
else:
|
143
145
|
return client_class()
|
144
|
-
|
146
|
+
|
145
147
|
# Original regex-based detection
|
146
148
|
if any(regex.match(model_name) for regex in openai_naming_regexes):
|
147
149
|
# print("Returning OpenAIStructuredOutputClient")
|
@@ -0,0 +1 @@
|
|
1
|
+
# TODO
|
@@ -0,0 +1 @@
|
|
1
|
+
# Maybe some kind of ephemeral cache
|