synth-ai 0.1.9__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 +37 -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/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.1.9.dist-info/METADATA +0 -37
- synth_ai-0.1.9.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.1.9.dist-info → synth_ai-0.2.1.dev0.dist-info}/WHEEL +0 -0
- {synth_ai-0.1.9.dist-info → synth_ai-0.2.1.dev0.dist-info}/licenses/LICENSE +0 -0
- {synth_ai-0.1.9.dist-info → synth_ai-0.2.1.dev0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,515 @@
|
|
1
|
+
import asyncio
|
2
|
+
import contextvars
|
3
|
+
from typing import Any, Dict, List, Literal, Optional, Tuple, Union
|
4
|
+
|
5
|
+
from pydantic import BaseModel
|
6
|
+
|
7
|
+
from synth_ai.tracing.config import VALID_TYPES, Message, ModelParams
|
8
|
+
from synth_ai.tracing.local import _local
|
9
|
+
|
10
|
+
# Existing SynthTrackerSync and SynthTrackerAsync classes...
|
11
|
+
|
12
|
+
|
13
|
+
class SynthTrackerSync:
|
14
|
+
"""Tracker for synchronous functions.
|
15
|
+
|
16
|
+
Purpose is to annotate the inside of your sync functions to track intermediate values.
|
17
|
+
Decorator @trace_event_sync is used to annotate the functions and track the inputs and outputs.
|
18
|
+
This tracker is instead used to access the data inside of decorated functions.
|
19
|
+
"""
|
20
|
+
|
21
|
+
_local = _local
|
22
|
+
|
23
|
+
@classmethod
|
24
|
+
def initialize(cls) -> None:
|
25
|
+
cls._local.initialized = True
|
26
|
+
cls._local.inputs = []
|
27
|
+
cls._local.outputs = []
|
28
|
+
|
29
|
+
@classmethod
|
30
|
+
def track_lm(
|
31
|
+
cls,
|
32
|
+
messages: List[Dict[str, str]],
|
33
|
+
model_name: str,
|
34
|
+
model_params: Optional[Dict[str, Union[str, int, float]]] = None,
|
35
|
+
finetune: bool = False,
|
36
|
+
):
|
37
|
+
# print("Tracking LM call in sync context - ",messages) # Added logging
|
38
|
+
if getattr(cls._local, "initialized", False):
|
39
|
+
cls._local.inputs.append(
|
40
|
+
{
|
41
|
+
"origin": "agent",
|
42
|
+
"messages": messages,
|
43
|
+
"model_name": model_name,
|
44
|
+
"model_params": model_params,
|
45
|
+
"finetune": finetune,
|
46
|
+
}
|
47
|
+
)
|
48
|
+
else:
|
49
|
+
pass
|
50
|
+
|
51
|
+
@classmethod
|
52
|
+
def track_state(
|
53
|
+
cls,
|
54
|
+
variable_name: str,
|
55
|
+
variable_value: Union[BaseModel, str, dict, int, float, bool, list, None],
|
56
|
+
origin: Literal["agent", "environment"],
|
57
|
+
annotation: Optional[str] = None,
|
58
|
+
):
|
59
|
+
# Skip if value is not a trackable type instead of raising error
|
60
|
+
if not isinstance(variable_value, VALID_TYPES):
|
61
|
+
return
|
62
|
+
|
63
|
+
if getattr(cls._local, "initialized", False):
|
64
|
+
if isinstance(variable_value, BaseModel):
|
65
|
+
variable_value = variable_value.model_dump()
|
66
|
+
cls._local.outputs.append(
|
67
|
+
{
|
68
|
+
"origin": origin,
|
69
|
+
"variable_name": variable_name,
|
70
|
+
"variable_value": variable_value,
|
71
|
+
"annotation": annotation,
|
72
|
+
}
|
73
|
+
)
|
74
|
+
# logger.debug(f"Tracked state: {variable_name}")
|
75
|
+
else:
|
76
|
+
pass
|
77
|
+
# raise RuntimeError(
|
78
|
+
# "Trace not initialized. Use within a function decorated with @trace_event_sync."
|
79
|
+
# )
|
80
|
+
|
81
|
+
@classmethod
|
82
|
+
def get_traced_data(cls) -> Tuple[List[Dict[str, Any]], List[Dict[str, Any]]]:
|
83
|
+
return getattr(cls._local, "inputs", []), getattr(cls._local, "outputs", [])
|
84
|
+
|
85
|
+
@classmethod
|
86
|
+
def finalize(cls) -> None:
|
87
|
+
# Clean up the thread-local storage
|
88
|
+
cls._local.initialized = False
|
89
|
+
cls._local.inputs = []
|
90
|
+
cls._local.outputs = []
|
91
|
+
# logger.debug("Finalized trace data")
|
92
|
+
|
93
|
+
@classmethod
|
94
|
+
def track_lm_output(
|
95
|
+
cls,
|
96
|
+
messages: List[Dict[str, str]],
|
97
|
+
model_name: str,
|
98
|
+
finetune: bool = False,
|
99
|
+
):
|
100
|
+
"""
|
101
|
+
Tracks 'messages' as if they were output from the LLM.
|
102
|
+
"""
|
103
|
+
if getattr(cls._local, "initialized", False):
|
104
|
+
cls._local.outputs.append(
|
105
|
+
{
|
106
|
+
"origin": "agent",
|
107
|
+
"messages": messages,
|
108
|
+
"model_name": model_name,
|
109
|
+
"finetune": finetune,
|
110
|
+
}
|
111
|
+
)
|
112
|
+
else:
|
113
|
+
pass
|
114
|
+
|
115
|
+
|
116
|
+
# Context variables for asynchronous tracing
|
117
|
+
trace_inputs_var = contextvars.ContextVar("trace_inputs", default=None)
|
118
|
+
trace_outputs_var = contextvars.ContextVar("trace_outputs", default=None)
|
119
|
+
trace_initialized_var = contextvars.ContextVar("trace_initialized", default=False)
|
120
|
+
|
121
|
+
|
122
|
+
class SynthTrackerAsync:
|
123
|
+
"""Tracker for synchronous functions.
|
124
|
+
|
125
|
+
Purpose is to annotate the inside of your sync functions to track intermediate values.
|
126
|
+
Decorator @trace_event_sync is used to annotate the functions and track the inputs and outputs.
|
127
|
+
This tracker is instead used to access the data inside of decorated functions.
|
128
|
+
"""
|
129
|
+
|
130
|
+
@classmethod
|
131
|
+
def initialize(cls) -> None:
|
132
|
+
trace_initialized_var.set(True)
|
133
|
+
trace_inputs_var.set([]) # List of tuples: (origin, var)
|
134
|
+
trace_outputs_var.set([]) # List of tuples: (origin, var)
|
135
|
+
# logger.debug("AsyncTrace initialized")
|
136
|
+
|
137
|
+
@classmethod
|
138
|
+
def track_lm(
|
139
|
+
cls,
|
140
|
+
messages: List[Dict[str, str]],
|
141
|
+
model_name: str,
|
142
|
+
model_params: Optional[Dict[str, Union[str, int, float]]] = None,
|
143
|
+
finetune: bool = False,
|
144
|
+
):
|
145
|
+
# print("Tracking LM call in async context") # Added logging
|
146
|
+
if trace_initialized_var.get():
|
147
|
+
trace_inputs = trace_inputs_var.get()
|
148
|
+
trace_inputs.append(
|
149
|
+
{
|
150
|
+
"origin": "agent",
|
151
|
+
"messages": messages,
|
152
|
+
"model_name": model_name,
|
153
|
+
"model_params": model_params,
|
154
|
+
"finetune": finetune,
|
155
|
+
}
|
156
|
+
)
|
157
|
+
trace_inputs_var.set(trace_inputs)
|
158
|
+
else:
|
159
|
+
pass
|
160
|
+
# raise RuntimeError(
|
161
|
+
# "Trace not initialized. Use within a function decorated with @trace_event_async."
|
162
|
+
# )
|
163
|
+
|
164
|
+
@classmethod
|
165
|
+
def track_state(
|
166
|
+
cls,
|
167
|
+
variable_name: str,
|
168
|
+
variable_value: Union[BaseModel, str, dict, int, float, bool, list, None],
|
169
|
+
origin: Literal["agent", "environment"],
|
170
|
+
annotation: Optional[str] = None,
|
171
|
+
io_type: Literal["input", "output"] = "output",
|
172
|
+
):
|
173
|
+
# Skip if value is not a trackable type instead of raising error
|
174
|
+
if not isinstance(variable_value, VALID_TYPES):
|
175
|
+
return
|
176
|
+
|
177
|
+
if trace_initialized_var.get():
|
178
|
+
if isinstance(variable_value, BaseModel):
|
179
|
+
variable_value = variable_value.model_dump()
|
180
|
+
trace_outputs = trace_outputs_var.get()
|
181
|
+
if io_type == "input":
|
182
|
+
trace_inputs = trace_inputs_var.get()
|
183
|
+
trace_inputs.append(
|
184
|
+
{
|
185
|
+
"origin": origin,
|
186
|
+
"variable_name": variable_name,
|
187
|
+
"variable_value": variable_value,
|
188
|
+
"annotation": annotation,
|
189
|
+
}
|
190
|
+
)
|
191
|
+
trace_inputs_var.set(trace_inputs)
|
192
|
+
else:
|
193
|
+
trace_outputs.append(
|
194
|
+
{
|
195
|
+
"origin": origin,
|
196
|
+
"variable_name": variable_name,
|
197
|
+
"variable_value": variable_value,
|
198
|
+
"annotation": annotation,
|
199
|
+
}
|
200
|
+
)
|
201
|
+
trace_outputs_var.set(trace_outputs)
|
202
|
+
# logger.debug(f"Tracked state: {variable_name}")
|
203
|
+
else:
|
204
|
+
pass
|
205
|
+
# raise RuntimeError(
|
206
|
+
# "Trace not initialized. Use within a function decorated with @trace_event_async."
|
207
|
+
# )
|
208
|
+
|
209
|
+
@classmethod
|
210
|
+
def get_traced_data(cls) -> Tuple[List[Dict[str, Any]], List[Dict[str, Any]]]:
|
211
|
+
traced_inputs = trace_inputs_var.get()
|
212
|
+
traced_outputs = trace_outputs_var.get()
|
213
|
+
return traced_inputs, traced_outputs
|
214
|
+
|
215
|
+
@classmethod
|
216
|
+
def finalize(cls) -> None:
|
217
|
+
trace_initialized_var.set(False)
|
218
|
+
trace_inputs_var.set([])
|
219
|
+
trace_outputs_var.set([])
|
220
|
+
# logger.debug("Finalized async trace data")
|
221
|
+
|
222
|
+
@classmethod
|
223
|
+
def track_lm_output(
|
224
|
+
cls,
|
225
|
+
messages: List[Dict[str, str]],
|
226
|
+
model_name: str,
|
227
|
+
finetune: bool = False,
|
228
|
+
):
|
229
|
+
"""
|
230
|
+
Tracks 'messages' as if they were output from the LLM.
|
231
|
+
"""
|
232
|
+
if trace_initialized_var.get():
|
233
|
+
trace_outputs = trace_outputs_var.get()
|
234
|
+
trace_outputs.append(
|
235
|
+
{
|
236
|
+
"origin": "agent",
|
237
|
+
"messages": messages,
|
238
|
+
"model_name": model_name,
|
239
|
+
"finetune": finetune,
|
240
|
+
}
|
241
|
+
)
|
242
|
+
trace_outputs_var.set(trace_outputs)
|
243
|
+
else:
|
244
|
+
pass
|
245
|
+
|
246
|
+
|
247
|
+
# Make traces available globally
|
248
|
+
synth_tracker_sync = SynthTrackerSync
|
249
|
+
synth_tracker_async = SynthTrackerAsync
|
250
|
+
|
251
|
+
|
252
|
+
class SynthTracker:
|
253
|
+
"""Tracker for synchronous and asynchronous functions. Intelligently chooses between sync and async trackers.
|
254
|
+
|
255
|
+
Purpose is to annotate the inside of your sync and async functions to track intermediate values.
|
256
|
+
Decorators @trace_event_sync and @trace_event_async are used to annotate the functions and track the inputs and outputs.
|
257
|
+
This tracker is instead used to access the data inside of decorated functions.
|
258
|
+
"""
|
259
|
+
|
260
|
+
@classmethod
|
261
|
+
def is_called_by_async(cls) -> bool:
|
262
|
+
try:
|
263
|
+
asyncio.get_running_loop() # Attempt to get the running event loop
|
264
|
+
# Debug logging disabled: print("DEBUG: Running in async context")
|
265
|
+
return True # If successful, we are in an async context
|
266
|
+
except RuntimeError:
|
267
|
+
# Debug logging disabled: print("DEBUG: Running in sync context")
|
268
|
+
return False # If there's no running event loop, we are in a sync context
|
269
|
+
|
270
|
+
@classmethod
|
271
|
+
def track_lm(
|
272
|
+
cls,
|
273
|
+
messages: List[Dict[str, str]],
|
274
|
+
model_name: str,
|
275
|
+
model_params: Optional[Dict[str, Union[str, int, float]]] = None,
|
276
|
+
finetune: bool = False,
|
277
|
+
):
|
278
|
+
# Debug logging disabled: print("DEBUG: Tracking LM call")
|
279
|
+
"""
|
280
|
+
Track a language model interaction within the current trace.
|
281
|
+
Automatically detects whether to use sync or async tracking.
|
282
|
+
|
283
|
+
Args:
|
284
|
+
messages (List[Dict[str, str]]): List of message dictionaries containing the conversation.
|
285
|
+
Each message should have:
|
286
|
+
- 'role': str - The role of the speaker (e.g., "user", "assistant", "system")
|
287
|
+
- 'content': str - The content of the message
|
288
|
+
|
289
|
+
model_name (str): Name of the language model being used
|
290
|
+
Examples: "gpt-4o-mini", "gpt-4o-mini", "claude-3-opus-20240229"
|
291
|
+
|
292
|
+
finetune (bool, optional): Whether this interaction is part of a fine-tuning process.
|
293
|
+
Defaults to False.
|
294
|
+
|
295
|
+
Raises:
|
296
|
+
RuntimeError: If called outside a traced context (use with @trace_event_sync
|
297
|
+
or @trace_event_async decorator)
|
298
|
+
TypeError: If messages or model_name are not of the correct type
|
299
|
+
|
300
|
+
Example:
|
301
|
+
```python
|
302
|
+
@trace_event_sync(origin="agent", event_type="chat")
|
303
|
+
def process_chat(self, user_input: str):
|
304
|
+
messages = [
|
305
|
+
{"role": "user", "content": user_input}
|
306
|
+
]
|
307
|
+
SynthTracker.track_lm(
|
308
|
+
messages=messages,
|
309
|
+
model_name="gpt-4o-mini"
|
310
|
+
)
|
311
|
+
```
|
312
|
+
"""
|
313
|
+
if cls.is_called_by_async() and trace_initialized_var.get():
|
314
|
+
# print("DEBUG: Tracking LM call in async context") # Added logging
|
315
|
+
synth_tracker_async.track_lm(
|
316
|
+
messages,
|
317
|
+
model_name,
|
318
|
+
model_params,
|
319
|
+
finetune,
|
320
|
+
)
|
321
|
+
elif getattr(synth_tracker_sync._local, "initialized", False):
|
322
|
+
# print("DEBUG: Tracking LM call in sync context") # Added logging
|
323
|
+
synth_tracker_sync.track_lm(
|
324
|
+
messages,
|
325
|
+
model_name,
|
326
|
+
model_params,
|
327
|
+
finetune,
|
328
|
+
)
|
329
|
+
else:
|
330
|
+
# Debug logging disabled: print("DEBUG: Skipping LM tracking - not initialized") # Added logging
|
331
|
+
pass
|
332
|
+
|
333
|
+
@classmethod
|
334
|
+
def track_state(
|
335
|
+
cls,
|
336
|
+
variable_name: str,
|
337
|
+
variable_value: Union[BaseModel, str, dict, int, float, bool, list, None],
|
338
|
+
origin: Literal["agent", "environment"],
|
339
|
+
annotation: Optional[str] = None,
|
340
|
+
):
|
341
|
+
"""
|
342
|
+
Track a state change or variable value within the current trace.
|
343
|
+
Automatically detects whether to use sync or async tracking.
|
344
|
+
|
345
|
+
Args:
|
346
|
+
variable_name (str): Name of the variable or state being tracked
|
347
|
+
|
348
|
+
variable_value (Union[BaseModel, str, dict, int, float, bool, list, None]):
|
349
|
+
Value to track. Must be one of the supported types:
|
350
|
+
- BaseModel (Pydantic models)
|
351
|
+
- Basic Python types (str, dict, int, float, bool, list)
|
352
|
+
- None
|
353
|
+
|
354
|
+
origin (Literal["agent", "environment"]): Source of the state change
|
355
|
+
- "agent": Changes from the AI/agent system
|
356
|
+
- "environment": Changes from external sources/environment
|
357
|
+
|
358
|
+
annotation (Optional[str], optional): Additional notes about the state change.
|
359
|
+
Defaults to None.
|
360
|
+
|
361
|
+
Raises:
|
362
|
+
RuntimeError: If called outside a traced context (use with @trace_event_sync
|
363
|
+
or @trace_event_async decorator)
|
364
|
+
TypeError: If variable_value is not one of the supported types
|
365
|
+
ValueError: If origin is not "agent" or "environment"
|
366
|
+
|
367
|
+
Example:
|
368
|
+
```python
|
369
|
+
@trace_event_sync(origin="agent", event_type="process")
|
370
|
+
def update_state(self, new_value: dict):
|
371
|
+
SynthTracker.track_state(
|
372
|
+
variable_name="system_state",
|
373
|
+
variable_value=new_value,
|
374
|
+
origin="agent",
|
375
|
+
annotation="Updated after processing"
|
376
|
+
)
|
377
|
+
```
|
378
|
+
"""
|
379
|
+
if cls.is_called_by_async() and trace_initialized_var.get():
|
380
|
+
# logger.debug("Using async tracker to track state")
|
381
|
+
synth_tracker_async.track_state(variable_name, variable_value, origin, annotation)
|
382
|
+
elif getattr(synth_tracker_sync._local, "initialized", False):
|
383
|
+
# logger.debug("Using sync tracker to track state")
|
384
|
+
synth_tracker_sync.track_state(variable_name, variable_value, origin, annotation)
|
385
|
+
else:
|
386
|
+
# raise RuntimeError("Trace not initialized in track_state.")
|
387
|
+
pass
|
388
|
+
|
389
|
+
@classmethod
|
390
|
+
def get_traced_data(
|
391
|
+
cls,
|
392
|
+
async_sync: Literal[
|
393
|
+
"async", "sync", ""
|
394
|
+
] = "", # Force only async or sync data to be returned
|
395
|
+
) -> Tuple[list, list]:
|
396
|
+
traced_inputs, traced_outputs = [], []
|
397
|
+
# Debug logging disabled: print(
|
398
|
+
# f"\nDEBUG: Getting traced data with async_sync='{async_sync}'"
|
399
|
+
# ) # Added logging
|
400
|
+
|
401
|
+
if async_sync in ["async", ""]:
|
402
|
+
# Debug logging disabled: print("DEBUG: Retrieving async traced data")
|
403
|
+
traced_inputs_async, traced_outputs_async = synth_tracker_async.get_traced_data()
|
404
|
+
# Debug logging disabled: print(
|
405
|
+
# f"DEBUG: Found {len(traced_inputs_async)} async inputs and {len(traced_outputs_async)} async outputs"
|
406
|
+
# ) # Added logging
|
407
|
+
traced_inputs.extend(traced_inputs_async)
|
408
|
+
traced_outputs.extend(traced_outputs_async)
|
409
|
+
|
410
|
+
if async_sync in ["sync", ""]:
|
411
|
+
# Debug logging disabled: print("DEBUG: Retrieving sync traced data")
|
412
|
+
traced_inputs_sync, traced_outputs_sync = synth_tracker_sync.get_traced_data()
|
413
|
+
# Debug logging disabled: print(
|
414
|
+
# f"DEBUG: Found {len(traced_inputs_sync)} sync inputs and {len(traced_outputs_sync)} sync outputs"
|
415
|
+
# ) # Added logging
|
416
|
+
traced_inputs.extend(traced_inputs_sync)
|
417
|
+
traced_outputs.extend(traced_outputs_sync)
|
418
|
+
|
419
|
+
# Debug logging disabled: print(
|
420
|
+
# f"DEBUG: Final combined data: {len(traced_inputs)} inputs and {len(traced_outputs)} outputs\n"
|
421
|
+
# ) # Added logging
|
422
|
+
return traced_inputs, traced_outputs
|
423
|
+
|
424
|
+
@classmethod
|
425
|
+
def track_lm_output(
|
426
|
+
cls,
|
427
|
+
messages: List[Dict[str, str]],
|
428
|
+
model_name: str,
|
429
|
+
finetune: bool = False,
|
430
|
+
):
|
431
|
+
"""
|
432
|
+
Tracks 'messages' as if they were output from the LLM.
|
433
|
+
Automatically detects whether to use sync or async tracking.
|
434
|
+
"""
|
435
|
+
if cls.is_called_by_async() and trace_initialized_var.get():
|
436
|
+
# Debug logging disabled: print("DEBUG: Tracking LM output in async context")
|
437
|
+
synth_tracker_async.track_lm_output(
|
438
|
+
messages=messages,
|
439
|
+
model_name=model_name,
|
440
|
+
finetune=finetune,
|
441
|
+
)
|
442
|
+
elif getattr(synth_tracker_sync._local, "initialized", False):
|
443
|
+
# Debug logging disabled: print("DEBUG: Tracking LM output in sync context")
|
444
|
+
synth_tracker_sync.track_lm_output(
|
445
|
+
messages=messages,
|
446
|
+
model_name=model_name,
|
447
|
+
finetune=finetune,
|
448
|
+
)
|
449
|
+
else:
|
450
|
+
# Debug logging disabled: print("DEBUG: Skipping LM output tracking - not initialized")
|
451
|
+
pass
|
452
|
+
|
453
|
+
|
454
|
+
def track_messages_sync(
|
455
|
+
input_messages: List[Message],
|
456
|
+
output_messages: List[Message],
|
457
|
+
model_name: str,
|
458
|
+
model_params: Optional[ModelParams] = None,
|
459
|
+
finetune: bool = False,
|
460
|
+
) -> None:
|
461
|
+
"""Track both input and output messages in a conversation synchronously.
|
462
|
+
|
463
|
+
Args:
|
464
|
+
input_messages: List of input messages (e.g., user messages)
|
465
|
+
output_messages: List of output messages (e.g., assistant responses)
|
466
|
+
model_name: Name of the language model being used
|
467
|
+
model_params: Optional parameters used for the model
|
468
|
+
finetune: Whether this conversation should be used for fine-tuning
|
469
|
+
"""
|
470
|
+
# Track input messages
|
471
|
+
synth_tracker_sync.track_lm(
|
472
|
+
messages=input_messages,
|
473
|
+
model_name=model_name,
|
474
|
+
model_params=model_params,
|
475
|
+
finetune=finetune,
|
476
|
+
)
|
477
|
+
|
478
|
+
# Track output messages
|
479
|
+
synth_tracker_sync.track_lm_output(
|
480
|
+
messages=output_messages,
|
481
|
+
model_name=model_name,
|
482
|
+
finetune=finetune,
|
483
|
+
)
|
484
|
+
|
485
|
+
|
486
|
+
async def track_messages_async(
|
487
|
+
input_messages: List[Message],
|
488
|
+
output_messages: List[Message],
|
489
|
+
model_name: str,
|
490
|
+
model_params: Optional[ModelParams] = None,
|
491
|
+
finetune: bool = False,
|
492
|
+
) -> None:
|
493
|
+
"""Track both input and output messages in a conversation asynchronously.
|
494
|
+
|
495
|
+
Args:
|
496
|
+
input_messages: List of input messages (e.g., user messages)
|
497
|
+
output_messages: List of output messages (e.g., assistant responses)
|
498
|
+
model_name: Name of the language model being used
|
499
|
+
model_params: Optional parameters used for the model
|
500
|
+
finetune: Whether this conversation should be used for fine-tuning
|
501
|
+
"""
|
502
|
+
# Track input messages
|
503
|
+
synth_tracker_async.track_lm(
|
504
|
+
messages=input_messages,
|
505
|
+
model_name=model_name,
|
506
|
+
model_params=model_params,
|
507
|
+
finetune=finetune,
|
508
|
+
)
|
509
|
+
|
510
|
+
# Track output messages
|
511
|
+
synth_tracker_async.track_lm_output(
|
512
|
+
messages=output_messages,
|
513
|
+
model_name=model_name,
|
514
|
+
finetune=finetune,
|
515
|
+
)
|