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
synth_ai/__init__.py
CHANGED
@@ -2,7 +2,33 @@
|
|
2
2
|
Synth AI - Software for aiding the best and multiplying the will.
|
3
3
|
"""
|
4
4
|
|
5
|
-
from synth_ai.
|
5
|
+
from synth_ai.lm.core.main import LM # Moved from zyk to lm for better organization
|
6
|
+
|
7
|
+
# Tracing exports - moved from synth-sdk
|
8
|
+
from synth_ai.tracing import * # noqa
|
9
|
+
from synth_ai.tracing.abstractions import (
|
10
|
+
EventPartitionElement,
|
11
|
+
SystemTrace,
|
12
|
+
TrainingQuestion,
|
13
|
+
RewardSignal,
|
14
|
+
)
|
15
|
+
from synth_ai.tracing.decorators import trace_event_async, trace_event_sync
|
16
|
+
from synth_ai.tracing.upload import upload
|
17
|
+
|
18
|
+
# Provider support exports - moved from synth-sdk to synth_ai/lm
|
19
|
+
from synth_ai.lm.provider_support.openai import OpenAI, AsyncOpenAI
|
20
|
+
from synth_ai.lm.provider_support.anthropic import Anthropic, AsyncAnthropic
|
21
|
+
|
22
|
+
# Environment exports - moved from synth-env
|
23
|
+
from synth_ai.environments import * # noqa
|
6
24
|
|
7
25
|
__version__ = "0.1.9"
|
8
|
-
__all__ = [
|
26
|
+
__all__ = [
|
27
|
+
"LM",
|
28
|
+
"tracing",
|
29
|
+
"OpenAI",
|
30
|
+
"AsyncOpenAI",
|
31
|
+
"Anthropic",
|
32
|
+
"AsyncAnthropic",
|
33
|
+
"environments",
|
34
|
+
] # Explicitly define public API
|
synth_ai/core/system.py
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
"""Synth Environment Package - A framework for reinforcement learning environments."""
|
2
|
+
|
3
|
+
__version__ = "0.1.5"
|
4
|
+
|
5
|
+
# Import key modules for easier access
|
6
|
+
from . import environment
|
7
|
+
from . import service
|
8
|
+
from . import stateful
|
9
|
+
from . import tasks
|
10
|
+
from . import examples
|
11
|
+
|
12
|
+
__all__ = [
|
13
|
+
"environment",
|
14
|
+
"service",
|
15
|
+
"stateful",
|
16
|
+
"tasks",
|
17
|
+
"examples",
|
18
|
+
]
|
19
|
+
|
20
|
+
import sys
|
21
|
+
import types
|
22
|
+
|
23
|
+
# ---------------------------------------------------------------------------
|
24
|
+
# Compatibility Shim
|
25
|
+
# Some older code imports synth_env via the namespace prefix 'src.synth_env'.
|
26
|
+
# Rather than requiring consumers to update import paths (or adding try/except
|
27
|
+
# imports which violates project style rules), we register an alias module so
|
28
|
+
# that both import styles resolve to the same package instance.
|
29
|
+
# ---------------------------------------------------------------------------
|
30
|
+
if "src" not in sys.modules:
|
31
|
+
sys.modules["src"] = types.ModuleType("src")
|
32
|
+
|
33
|
+
# Expose this package as src.synth_env
|
34
|
+
sys.modules["src.synth_env"] = sys.modules[__name__]
|
35
|
+
setattr(sys.modules["src"], "synth_env", sys.modules[__name__])
|
@@ -0,0 +1 @@
|
|
1
|
+
"""Environment core module."""
|
@@ -0,0 +1 @@
|
|
1
|
+
# artifacts package
|
@@ -0,0 +1,50 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from abc import ABC, abstractmethod
|
3
|
+
from pathlib import Path
|
4
|
+
from pydantic import BaseModel
|
5
|
+
import shutil
|
6
|
+
|
7
|
+
|
8
|
+
class Artifact(BaseModel, ABC):
|
9
|
+
"""Generic artifact representation."""
|
10
|
+
|
11
|
+
artifact_type: str
|
12
|
+
filename: str
|
13
|
+
|
14
|
+
@abstractmethod
|
15
|
+
def bytes(self) -> bytes:
|
16
|
+
"""Return raw bytes of the artifact."""
|
17
|
+
...
|
18
|
+
|
19
|
+
def save(self, root: Path) -> None:
|
20
|
+
"""Save artifact bytes to `root/filename`."""
|
21
|
+
p = root / self.filename
|
22
|
+
p.write_bytes(self.bytes())
|
23
|
+
|
24
|
+
|
25
|
+
class FileArtifact(Artifact):
|
26
|
+
"""Artifact representing a file's contents."""
|
27
|
+
|
28
|
+
artifact_type: str = "file"
|
29
|
+
content: bytes
|
30
|
+
|
31
|
+
def bytes(self) -> bytes:
|
32
|
+
return self.content
|
33
|
+
|
34
|
+
|
35
|
+
class ArtifactStore:
|
36
|
+
"""Filesystem-based store for artifacts."""
|
37
|
+
|
38
|
+
def __init__(self, root: Path):
|
39
|
+
self.root = root
|
40
|
+
self.root.mkdir(parents=True, exist_ok=True)
|
41
|
+
|
42
|
+
def add(self, art: Artifact) -> None:
|
43
|
+
art.save(self.root)
|
44
|
+
|
45
|
+
def list(self) -> list[Path]:
|
46
|
+
return list(self.root.iterdir())
|
47
|
+
|
48
|
+
def export_tar(self, out: Path) -> None:
|
49
|
+
"""Generate `out.tar.gz` from artifact directory."""
|
50
|
+
shutil.make_archive(out.with_suffix(""), "gztar", self.root)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
from synth_ai.core.system import System
|
2
|
+
|
3
|
+
class Environment(System):
|
4
|
+
"""
|
5
|
+
Base class for all environments, providing a name attribute.
|
6
|
+
"""
|
7
|
+
|
8
|
+
_default_name: str
|
9
|
+
|
10
|
+
def __init_subclass__(cls, **kwargs):
|
11
|
+
super().__init_subclass__(**kwargs)
|
12
|
+
# Set a default name for the subclass based on its class name
|
13
|
+
cls._default_name = cls.__name__
|
14
|
+
|
15
|
+
@property
|
16
|
+
def name(self) -> str:
|
17
|
+
"""Return the environment name, defaulting to the subclass name."""
|
18
|
+
return getattr(self, "_name", self._default_name)
|
19
|
+
|
20
|
+
@name.setter
|
21
|
+
def name(self, value: str):
|
22
|
+
self._name = value
|
@@ -0,0 +1 @@
|
|
1
|
+
# db package
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import sqlite3
|
2
|
+
import threading
|
3
|
+
import contextlib
|
4
|
+
from pathlib import Path
|
5
|
+
|
6
|
+
|
7
|
+
class SQLiteManager:
|
8
|
+
def __init__(self, db_path: Path, read_only: bool = True, ephemeral: bool = False):
|
9
|
+
"""Initializes SQLiteManager with optional read-only or ephemeral mode."""
|
10
|
+
self.db_path = db_path
|
11
|
+
self.read_only = read_only
|
12
|
+
self.ephemeral = ephemeral
|
13
|
+
self._lock = threading.RLock()
|
14
|
+
self._conn: sqlite3.Connection | None = None
|
15
|
+
|
16
|
+
@contextlib.contextmanager
|
17
|
+
def connection(self):
|
18
|
+
with self._lock:
|
19
|
+
if self._conn is None:
|
20
|
+
uri = f"file:{self.db_path}?mode=ro" if self.read_only else str(self.db_path)
|
21
|
+
self._conn = sqlite3.connect(uri, uri=self.read_only, isolation_level="DEFERRED")
|
22
|
+
self._conn.execute("PRAGMA foreign_keys=ON;")
|
23
|
+
self._conn.execute("PRAGMA journal_mode=WAL;")
|
24
|
+
try:
|
25
|
+
yield self._conn
|
26
|
+
self._conn.commit()
|
27
|
+
except:
|
28
|
+
self._conn.rollback()
|
29
|
+
raise
|
30
|
+
|
31
|
+
def close(self):
|
32
|
+
"""Closes the underlying connection for cleanup at environment teardown."""
|
33
|
+
with self._lock:
|
34
|
+
if self._conn:
|
35
|
+
self._conn.close()
|
36
|
+
self._conn = None
|
37
|
+
|
38
|
+
def reset(self, new_db_path: Path | None = None):
|
39
|
+
"""Resets the connection, optionally switching to a new database path for a fresh session."""
|
40
|
+
with self._lock:
|
41
|
+
if self._conn:
|
42
|
+
self._conn.close()
|
43
|
+
if new_db_path:
|
44
|
+
self.db_path = new_db_path
|
45
|
+
self._conn = None
|
@@ -0,0 +1,24 @@
|
|
1
|
+
from typing import Type, Dict, List
|
2
|
+
|
3
|
+
from synth_ai.environments.stateful.core import StatefulEnvironment
|
4
|
+
|
5
|
+
# Global registry for environment types
|
6
|
+
ENV_REGISTRY: Dict[str, Type[StatefulEnvironment]] = {}
|
7
|
+
|
8
|
+
|
9
|
+
def register_environment(name: str, cls: Type[StatefulEnvironment]) -> None:
|
10
|
+
"""Register an environment class under a unique name."""
|
11
|
+
ENV_REGISTRY[name] = cls
|
12
|
+
|
13
|
+
|
14
|
+
def get_environment_cls(env_type: str) -> Type[StatefulEnvironment]:
|
15
|
+
"""Retrieve a registered environment class or raise an error."""
|
16
|
+
try:
|
17
|
+
return ENV_REGISTRY[env_type]
|
18
|
+
except KeyError:
|
19
|
+
raise ValueError(f"Unsupported environment type: {env_type}")
|
20
|
+
|
21
|
+
|
22
|
+
def list_supported_env_types() -> List[str]:
|
23
|
+
"""List all registered environment type names."""
|
24
|
+
return list(ENV_REGISTRY.keys())
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import sqlite3
|
2
|
+
import threading
|
3
|
+
import contextlib
|
4
|
+
from pathlib import Path
|
5
|
+
from typing import Optional
|
6
|
+
|
7
|
+
|
8
|
+
class SQLiteManager:
|
9
|
+
def __init__(self, db_path: Path, read_only: bool = True, ephemeral: bool = False):
|
10
|
+
"""Initializes SQLiteManager with optional read-only or ephemeral mode."""
|
11
|
+
self.db_path = db_path
|
12
|
+
self.read_only = read_only
|
13
|
+
self.ephemeral = ephemeral
|
14
|
+
self._lock = threading.RLock()
|
15
|
+
self._conn: sqlite3.Connection | None = None
|
16
|
+
|
17
|
+
@contextlib.contextmanager
|
18
|
+
def connection(self):
|
19
|
+
with self._lock:
|
20
|
+
if self._conn is None:
|
21
|
+
uri = f"file:{self.db_path}?mode=ro" if self.read_only else str(self.db_path)
|
22
|
+
self._conn = sqlite3.connect(uri, uri=self.read_only, isolation_level="DEFERRED")
|
23
|
+
self._conn.execute("PRAGMA foreign_keys=ON;")
|
24
|
+
self._conn.execute("PRAGMA journal_mode=WAL;")
|
25
|
+
try:
|
26
|
+
yield self._conn
|
27
|
+
self._conn.commit()
|
28
|
+
except:
|
29
|
+
self._conn.rollback()
|
30
|
+
raise
|
31
|
+
|
32
|
+
def close(self):
|
33
|
+
"""Closes the underlying connection for cleanup at environment teardown."""
|
34
|
+
with self._lock:
|
35
|
+
if self._conn:
|
36
|
+
self._conn.close()
|
37
|
+
self._conn = None
|
38
|
+
|
39
|
+
def reset(self, new_db_path: Optional[Path] = None):
|
40
|
+
"""Resets the connection, optionally switching to a new database path for a fresh session."""
|
41
|
+
with self._lock:
|
42
|
+
if self._conn:
|
43
|
+
self._conn.close()
|
44
|
+
if new_db_path:
|
45
|
+
self.db_path = new_db_path
|
46
|
+
self._conn = None
|
@@ -0,0 +1 @@
|
|
1
|
+
# EnvHistory, EnvRecord, EnvironmentCheckpointObservation (customer supplied, not for agent but only designer)
|
@@ -0,0 +1 @@
|
|
1
|
+
# rewards package
|
@@ -0,0 +1,28 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from abc import ABC, abstractmethod
|
3
|
+
from typing import List, Any
|
4
|
+
|
5
|
+
|
6
|
+
class RewardComponent(ABC):
|
7
|
+
"""Interface for a component contributing to stepwise reward."""
|
8
|
+
|
9
|
+
weight: float = 1.0
|
10
|
+
|
11
|
+
@abstractmethod
|
12
|
+
async def score(self, state: Any, action: Any) -> float:
|
13
|
+
"""Compute the component's reward given current state and action."""
|
14
|
+
...
|
15
|
+
|
16
|
+
|
17
|
+
class RewardStack:
|
18
|
+
"""Aggregates multiple RewardComponent instances to compute a total reward."""
|
19
|
+
|
20
|
+
def __init__(self, components: List[RewardComponent]):
|
21
|
+
self.components = components
|
22
|
+
|
23
|
+
async def step_reward(self, state: Any, action: Any) -> float:
|
24
|
+
"""Compute the sum of weighted component rewards for a single step."""
|
25
|
+
total = 0.0
|
26
|
+
for comp in self.components:
|
27
|
+
total += comp.weight * await comp.score(state, action)
|
28
|
+
return total
|
@@ -0,0 +1,26 @@
|
|
1
|
+
from abc import abstractmethod
|
2
|
+
from typing import Any
|
3
|
+
|
4
|
+
|
5
|
+
class InternalObservation:
|
6
|
+
public_observation: Any
|
7
|
+
private_observation: Any
|
8
|
+
|
9
|
+
|
10
|
+
class GetObservationCallable:
|
11
|
+
@abstractmethod
|
12
|
+
async def get_observation(self) -> InternalObservation:
|
13
|
+
pass
|
14
|
+
|
15
|
+
pass
|
16
|
+
|
17
|
+
|
18
|
+
class Engine:
|
19
|
+
async def initialize(self):
|
20
|
+
pass
|
21
|
+
|
22
|
+
async def terminate(self):
|
23
|
+
pass
|
24
|
+
|
25
|
+
async def _step_engine(self):
|
26
|
+
pass
|
@@ -0,0 +1,34 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from abc import ABC, abstractmethod
|
3
|
+
from pydantic import BaseModel, Field
|
4
|
+
from typing import Any, Dict, Type
|
5
|
+
|
6
|
+
|
7
|
+
class EnvToolCall(BaseModel):
|
8
|
+
"""Agent-requested call into an environment tool."""
|
9
|
+
|
10
|
+
tool: str
|
11
|
+
args: Dict[str, Any] = Field(default_factory=dict)
|
12
|
+
|
13
|
+
|
14
|
+
class ToolResult(BaseModel):
|
15
|
+
ok: bool
|
16
|
+
payload: Any | None = None
|
17
|
+
error: str | None = None
|
18
|
+
|
19
|
+
|
20
|
+
class AbstractTool(ABC):
|
21
|
+
name: str
|
22
|
+
call_schema: Type[BaseModel]
|
23
|
+
result_schema: Type[BaseModel] = ToolResult
|
24
|
+
|
25
|
+
@abstractmethod
|
26
|
+
async def __call__(self, call: EnvToolCall) -> ToolResult: ...
|
27
|
+
|
28
|
+
|
29
|
+
TOOL_REGISTRY: dict[str, AbstractTool] = {}
|
30
|
+
|
31
|
+
|
32
|
+
def register_tool(tool: AbstractTool) -> None:
|
33
|
+
"""Register a tool instance under its `name` for dispatch."""
|
34
|
+
TOOL_REGISTRY[tool.name] = tool
|
@@ -0,0 +1 @@
|
|
1
|
+
"""Environment examples and demos."""
|
@@ -0,0 +1,8 @@
|
|
1
|
+
from .config_logging import configure_logging
|
2
|
+
from .environment import CrafterClassicEnvironment
|
3
|
+
from .engine import CrafterEngine
|
4
|
+
|
5
|
+
# Configure logging when crafter_classic module is imported
|
6
|
+
configure_logging()
|
7
|
+
|
8
|
+
__all__ = ["CrafterClassicEnvironment", "CrafterEngine"]
|
synth_ai/environments/examples/crafter_classic/agent_demos/crafter_comprehensive_evaluation.py
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Run script for Full Enchilada Crafter Evaluation
|
4
|
+
"""
|
5
|
+
|
6
|
+
import asyncio
|
7
|
+
import argparse
|
8
|
+
from src.synth_env.examples.crafter_classic.agent_demos.full_enchilada import (
|
9
|
+
run_full_enchilada_eval,
|
10
|
+
)
|
11
|
+
|
12
|
+
|
13
|
+
async def main():
|
14
|
+
parser = argparse.ArgumentParser(description="Run Full Enchilada Crafter Evaluation")
|
15
|
+
parser.add_argument(
|
16
|
+
"--models", nargs="+", default=["gpt-4o-mini"], help="Model names to evaluate"
|
17
|
+
)
|
18
|
+
parser.add_argument(
|
19
|
+
"--difficulties",
|
20
|
+
nargs="+",
|
21
|
+
default=["easy", "hard"],
|
22
|
+
help="Difficulty levels to test",
|
23
|
+
)
|
24
|
+
parser.add_argument(
|
25
|
+
"--num-trajectories",
|
26
|
+
type=int,
|
27
|
+
default=3,
|
28
|
+
help="Number of trajectories per condition",
|
29
|
+
)
|
30
|
+
parser.add_argument("--max-turns", type=int, default=30, help="Maximum turns per trajectory")
|
31
|
+
parser.add_argument("--no-images", action="store_true", help="Disable image capture")
|
32
|
+
parser.add_argument(
|
33
|
+
"--no-viewer",
|
34
|
+
action="store_true",
|
35
|
+
help="Don't launch the viewer after evaluation",
|
36
|
+
)
|
37
|
+
parser.add_argument(
|
38
|
+
"--output-dir",
|
39
|
+
type=str,
|
40
|
+
default=None,
|
41
|
+
help="Output directory (default: src/evals/crafter/run_TIMESTAMP)",
|
42
|
+
)
|
43
|
+
|
44
|
+
args = parser.parse_args()
|
45
|
+
|
46
|
+
await run_full_enchilada_eval(
|
47
|
+
model_names=args.models,
|
48
|
+
difficulties=args.difficulties,
|
49
|
+
num_trajectories=args.num_trajectories,
|
50
|
+
max_turns=args.max_turns,
|
51
|
+
capture_images=not args.no_images,
|
52
|
+
launch_viewer=not args.no_viewer,
|
53
|
+
output_dir=args.output_dir,
|
54
|
+
)
|
55
|
+
|
56
|
+
|
57
|
+
if __name__ == "__main__":
|
58
|
+
asyncio.run(main())
|
@@ -0,0 +1,152 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Browse existing Crafter evaluations and launch viewer for a selected run.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import argparse
|
7
|
+
import json
|
8
|
+
from pathlib import Path
|
9
|
+
from datetime import datetime
|
10
|
+
import asyncio
|
11
|
+
from tabulate import tabulate
|
12
|
+
|
13
|
+
from src.synth_env.examples.crafter_classic.agent_demos.full_enchilada import (
|
14
|
+
set_current_eval_dir,
|
15
|
+
app,
|
16
|
+
)
|
17
|
+
from fastapi.staticfiles import StaticFiles
|
18
|
+
import uvicorn
|
19
|
+
|
20
|
+
|
21
|
+
def list_evaluations(evals_dir: Path = Path("src/evals/crafter")):
|
22
|
+
"""List all available evaluations with summary info."""
|
23
|
+
if not evals_dir.exists():
|
24
|
+
print(f"No evaluations found at {evals_dir}")
|
25
|
+
return []
|
26
|
+
|
27
|
+
evaluations = []
|
28
|
+
for run_dir in sorted(evals_dir.glob("run_*"), reverse=True):
|
29
|
+
if run_dir.is_dir():
|
30
|
+
summary_file = run_dir / "evaluation_summary.json"
|
31
|
+
if summary_file.exists():
|
32
|
+
with open(summary_file, "r") as f:
|
33
|
+
summary = json.load(f)
|
34
|
+
|
35
|
+
eval_info = {
|
36
|
+
"run_id": run_dir.name,
|
37
|
+
"timestamp": summary["evaluation_metadata"]["timestamp"],
|
38
|
+
"models": ", ".join(summary["models_evaluated"]),
|
39
|
+
"difficulties": ", ".join(summary["difficulties_evaluated"]),
|
40
|
+
"num_trajectories": summary["evaluation_metadata"]["num_trajectories"],
|
41
|
+
"path": run_dir,
|
42
|
+
}
|
43
|
+
evaluations.append(eval_info)
|
44
|
+
|
45
|
+
return evaluations
|
46
|
+
|
47
|
+
|
48
|
+
async def view_evaluation(eval_dir: Path):
|
49
|
+
"""Launch viewer for a specific evaluation."""
|
50
|
+
if not eval_dir.exists():
|
51
|
+
print(f"Evaluation directory not found: {eval_dir}")
|
52
|
+
return
|
53
|
+
|
54
|
+
viewer_dir = eval_dir / "viewer"
|
55
|
+
if not viewer_dir.exists():
|
56
|
+
print(f"Viewer files not found in {eval_dir}")
|
57
|
+
return
|
58
|
+
|
59
|
+
print(f"\nš Viewing evaluation: {eval_dir}")
|
60
|
+
print("š Launching viewer at http://localhost:8000")
|
61
|
+
print(" Press Ctrl+C to stop the viewer")
|
62
|
+
|
63
|
+
# Set the current eval directory for the viewer
|
64
|
+
set_current_eval_dir(eval_dir)
|
65
|
+
|
66
|
+
# Mount static files from the viewer directory
|
67
|
+
app.mount("/", StaticFiles(directory=str(viewer_dir), html=True), name="viewer")
|
68
|
+
|
69
|
+
# Run viewer
|
70
|
+
config = uvicorn.Config(app, host="0.0.0.0", port=8000, log_level="error")
|
71
|
+
server = uvicorn.Server(config)
|
72
|
+
await server.serve()
|
73
|
+
|
74
|
+
|
75
|
+
async def main():
|
76
|
+
parser = argparse.ArgumentParser(description="Browse Crafter evaluations")
|
77
|
+
parser.add_argument(
|
78
|
+
"--eval-dir",
|
79
|
+
type=str,
|
80
|
+
default="src/evals/crafter",
|
81
|
+
help="Base directory for evaluations",
|
82
|
+
)
|
83
|
+
parser.add_argument(
|
84
|
+
"--run-id", type=str, help="Specific run ID to view (e.g., run_20240115_143022)"
|
85
|
+
)
|
86
|
+
parser.add_argument("--latest", action="store_true", help="View the latest evaluation")
|
87
|
+
|
88
|
+
args = parser.parse_args()
|
89
|
+
evals_dir = Path(args.eval_dir)
|
90
|
+
|
91
|
+
# List evaluations
|
92
|
+
evaluations = list_evaluations(evals_dir)
|
93
|
+
|
94
|
+
if not evaluations:
|
95
|
+
return
|
96
|
+
|
97
|
+
# Display table of evaluations
|
98
|
+
if not args.run_id and not args.latest:
|
99
|
+
print("\nš Available Crafter Evaluations:")
|
100
|
+
table_data = []
|
101
|
+
for i, eval_info in enumerate(evaluations):
|
102
|
+
# Parse timestamp for cleaner display
|
103
|
+
try:
|
104
|
+
ts = datetime.fromisoformat(eval_info["timestamp"])
|
105
|
+
ts_str = ts.strftime("%Y-%m-%d %H:%M:%S")
|
106
|
+
except:
|
107
|
+
ts_str = eval_info["timestamp"]
|
108
|
+
|
109
|
+
table_data.append(
|
110
|
+
[
|
111
|
+
i + 1,
|
112
|
+
eval_info["run_id"],
|
113
|
+
ts_str,
|
114
|
+
eval_info["models"],
|
115
|
+
eval_info["difficulties"],
|
116
|
+
eval_info["num_trajectories"],
|
117
|
+
]
|
118
|
+
)
|
119
|
+
|
120
|
+
headers = ["#", "Run ID", "Timestamp", "Models", "Difficulties", "Trajectories"]
|
121
|
+
print(tabulate(table_data, headers=headers, tablefmt="grid"))
|
122
|
+
|
123
|
+
# Ask user to select
|
124
|
+
print("\nEnter the number of the evaluation to view (or 'q' to quit): ", end="")
|
125
|
+
choice = input().strip()
|
126
|
+
|
127
|
+
if choice.lower() == "q":
|
128
|
+
return
|
129
|
+
|
130
|
+
try:
|
131
|
+
idx = int(choice) - 1
|
132
|
+
if 0 <= idx < len(evaluations):
|
133
|
+
selected_eval = evaluations[idx]
|
134
|
+
await view_evaluation(selected_eval["path"])
|
135
|
+
else:
|
136
|
+
print("Invalid selection")
|
137
|
+
except ValueError:
|
138
|
+
print("Invalid input")
|
139
|
+
|
140
|
+
# View specific run
|
141
|
+
elif args.run_id:
|
142
|
+
eval_path = evals_dir / args.run_id
|
143
|
+
await view_evaluation(eval_path)
|
144
|
+
|
145
|
+
# View latest
|
146
|
+
elif args.latest and evaluations:
|
147
|
+
latest_eval = evaluations[0]
|
148
|
+
await view_evaluation(latest_eval["path"])
|
149
|
+
|
150
|
+
|
151
|
+
if __name__ == "__main__":
|
152
|
+
asyncio.run(main())
|