synth-ai 0.2.9.dev0__py3-none-any.whl → 0.2.23.dev3__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.
- examples/README.md +1 -0
- examples/__init__.py +16 -0
- examples/analyze_semantic_words.sh +17 -0
- examples/baseline/banking77_baseline.py +243 -0
- examples/baseline/banking77_pipeline_baseline.py +294 -0
- examples/baseline/crafter_baseline.py +407 -0
- examples/baseline/pokemon_red_baseline.py +326 -0
- examples/baseline/simple_baseline.py +56 -0
- examples/baseline/warming_up_to_rl_baseline.py +239 -0
- examples/blog_posts/gepa/README.md +355 -0
- examples/blog_posts/gepa/configs/banking77_gepa_local.toml +95 -0
- examples/blog_posts/gepa/configs/banking77_gepa_test.toml +80 -0
- examples/blog_posts/gepa/configs/banking77_mipro_local.toml +50 -0
- examples/blog_posts/gepa/configs/banking77_pipeline_gepa_local.toml +101 -0
- examples/blog_posts/gepa/configs/banking77_pipeline_gepa_test.toml +96 -0
- examples/blog_posts/gepa/configs/hotpotqa_gepa_local.toml +57 -0
- examples/blog_posts/gepa/configs/hotpotqa_gepa_qwen.toml +35 -0
- examples/blog_posts/gepa/configs/hotpotqa_mipro_local.toml +51 -0
- examples/blog_posts/gepa/configs/hover_gepa_local.toml +57 -0
- examples/blog_posts/gepa/configs/hover_gepa_qwen.toml +35 -0
- examples/blog_posts/gepa/configs/hover_mipro_local.toml +51 -0
- examples/blog_posts/gepa/configs/ifbench_gepa_local.toml +57 -0
- examples/blog_posts/gepa/configs/ifbench_gepa_qwen.toml +35 -0
- examples/blog_posts/gepa/configs/ifbench_mipro_local.toml +51 -0
- examples/blog_posts/gepa/configs/pupa_gepa_local.toml +58 -0
- examples/blog_posts/gepa/configs/pupa_mipro_local.toml +52 -0
- examples/blog_posts/gepa/deploy_banking77_task_app.sh +54 -0
- examples/blog_posts/gepa/gepa_baseline.py +204 -0
- examples/blog_posts/gepa/query_prompts_example.py +97 -0
- examples/blog_posts/gepa/run_gepa_banking77.sh +112 -0
- examples/blog_posts/gepa/run_gepa_banking77_pipeline.sh +163 -0
- examples/blog_posts/gepa/task_apps.py +105 -0
- examples/blog_posts/gepa/test_gepa_local.sh +67 -0
- examples/blog_posts/gepa/verify_banking77_setup.sh +123 -0
- examples/blog_posts/mipro/README.md +415 -0
- examples/blog_posts/mipro/configs/banking77_mipro_local.toml +91 -0
- examples/blog_posts/mipro/configs/banking77_mipro_test.toml +87 -0
- examples/blog_posts/mipro/configs/banking77_pipeline_mipro_gemini_flash_lite_local.toml +98 -0
- examples/blog_posts/mipro/configs/banking77_pipeline_mipro_gpt41mini_local.toml +96 -0
- examples/blog_posts/mipro/configs/banking77_pipeline_mipro_local.toml +94 -0
- examples/blog_posts/mipro/configs/banking77_pipeline_mipro_test.toml +170 -0
- examples/blog_posts/mipro/deploy_banking77_pipeline_task_app.sh +59 -0
- examples/blog_posts/mipro/deploy_banking77_task_app.sh +41 -0
- examples/blog_posts/mipro/multi_step.md +79 -0
- examples/blog_posts/mipro/run_mipro_banking77.sh +191 -0
- examples/blog_posts/mipro/run_mipro_banking77_pipeline.sh +171 -0
- examples/blog_posts/mipro/run_mipro_banking77_pipeline_gemini_flash_lite.sh +177 -0
- examples/blog_posts/mipro/run_mipro_banking77_pipeline_gpt41mini.sh +173 -0
- examples/blog_posts/mipro/verify_banking77_setup.sh +117 -0
- examples/blog_posts/pokemon_vl/README.md +98 -0
- examples/blog_posts/pokemon_vl/configs/eval_gpt5nano.toml +26 -0
- examples/blog_posts/pokemon_vl/configs/eval_qwen3_vl.toml +27 -0
- examples/blog_posts/pokemon_vl/configs/eval_rl_final.toml +24 -0
- examples/blog_posts/pokemon_vl/configs/filter_high_reward.toml +10 -0
- examples/blog_posts/pokemon_vl/configs/train_rl_from_sft.toml +43 -0
- examples/blog_posts/pokemon_vl/configs/train_sft_qwen4b_vl.toml +40 -0
- examples/blog_posts/pokemon_vl/extract_images.py +239 -0
- examples/blog_posts/pokemon_vl/pokemon_vl_baseline.py +326 -0
- examples/blog_posts/pokemon_vl/run_eval_extract_images.py +209 -0
- examples/blog_posts/pokemon_vl/run_qwen_eval_extract_images.py +212 -0
- examples/blog_posts/pokemon_vl/text_box_analysis.md +106 -0
- examples/blog_posts/warming_up_to_rl/ARCHITECTURE.md +195 -0
- examples/blog_posts/warming_up_to_rl/FINAL_TEST_RESULTS.md +127 -0
- examples/blog_posts/warming_up_to_rl/INFERENCE_SUCCESS.md +132 -0
- examples/blog_posts/warming_up_to_rl/README.md +158 -0
- examples/blog_posts/warming_up_to_rl/SMOKE_TESTING.md +164 -0
- examples/blog_posts/warming_up_to_rl/SMOKE_TEST_COMPLETE.md +253 -0
- examples/blog_posts/warming_up_to_rl/configs/eval_baseline_qwen32b_10x20.toml +25 -0
- examples/blog_posts/warming_up_to_rl/configs/eval_ft_qwen4b.toml +25 -0
- examples/blog_posts/warming_up_to_rl/configs/eval_ft_qwen4b_10x20.toml +26 -0
- examples/blog_posts/warming_up_to_rl/configs/eval_groq_qwen32b.toml +25 -0
- examples/blog_posts/warming_up_to_rl/configs/eval_openai_gpt_oss_120b.toml +29 -0
- examples/blog_posts/warming_up_to_rl/configs/filter_high_reward_dataset.toml +10 -0
- examples/blog_posts/warming_up_to_rl/configs/smoke_test.toml +75 -0
- examples/blog_posts/warming_up_to_rl/configs/train_rl_from_sft.toml +91 -0
- examples/blog_posts/warming_up_to_rl/configs/train_sft_qwen4b.toml +40 -0
- examples/blog_posts/warming_up_to_rl/warming_up_to_rl_baseline.py +187 -0
- examples/crafter_debug_render.py +186 -0
- examples/dev/qwen3_32b_qlora_4xh100.toml +45 -0
- examples/gepa/banking77_pipeline_gepa.toml +96 -0
- examples/gepa/multi_stage_gepa_example.toml +84 -0
- examples/gepa/run_gepa_banking77_pipeline.sh +157 -0
- examples/multi_step/SFT_README.md +147 -0
- examples/multi_step/configs/README_verilog_rl.md +77 -0
- examples/multi_step/configs/VERILOG_REWARDS.md +103 -0
- examples/multi_step/configs/VERILOG_RL_CHECKLIST.md +196 -0
- examples/multi_step/configs/crafter_eval_synth_qwen4b.toml +35 -0
- examples/multi_step/configs/crafter_eval_text_only_groq_qwen32b.toml +36 -0
- examples/multi_step/configs/crafter_rl_outcome.toml +75 -0
- examples/multi_step/configs/crafter_rl_stepwise_hosted_judge.toml +145 -0
- examples/multi_step/configs/crafter_rl_stepwise_shaped.toml +84 -0
- examples/multi_step/configs/crafter_rl_stepwise_simple.toml +79 -0
- examples/multi_step/configs/crafter_rl_stepwise_simple_NEW_FORMAT.toml +105 -0
- examples/multi_step/configs/crafter_sft_qwen30b_lora.toml +62 -0
- examples/multi_step/configs/crafter_synth_backend.md +40 -0
- examples/multi_step/configs/verilog_eval_groq_qwen32b.toml +31 -0
- examples/multi_step/configs/verilog_eval_synth_qwen8b.toml +33 -0
- examples/multi_step/configs/verilog_rl_lora.toml +147 -0
- examples/multi_step/convert_traces_to_sft.py +84 -0
- examples/multi_step/crafter_rl_lora.md +70 -0
- examples/multi_step/judges/crafter_backend_judge.py +220 -0
- examples/multi_step/judges/verilog_backend_judge.py +234 -0
- examples/multi_step/readme.md +48 -0
- examples/multi_step/run_sft_qwen30b.sh +45 -0
- examples/multi_step/sse_metrics_streaming_notes.md +357 -0
- examples/multi_step/task_app_config_notes.md +494 -0
- examples/multi_step/verilog_rl_lora.md +218 -0
- examples/qwen_coder/README.md +102 -0
- examples/qwen_coder/_shared.py +113 -0
- examples/qwen_coder/configs/coder_lora_30b.toml +60 -0
- examples/qwen_coder/configs/coder_lora_4b.toml +61 -0
- examples/qwen_coder/configs/coder_lora_small.toml +57 -0
- examples/qwen_coder/generate_dataset.py +98 -0
- examples/qwen_coder/infer_ft_smoke.py +65 -0
- examples/qwen_coder/infer_prod_proxy.py +73 -0
- examples/qwen_coder/infer_via_synth.py +87 -0
- examples/qwen_coder/scripts/infer_coder.sh +19 -0
- examples/qwen_coder/scripts/train_coder_30b.sh +22 -0
- examples/qwen_coder/sft_full_17b.py +103 -0
- examples/qwen_coder/sft_lora_30b.py +110 -0
- examples/qwen_coder/subset_jsonl.py +39 -0
- examples/qwen_coder/todos.md +38 -0
- examples/qwen_coder/validate_jsonl.py +60 -0
- examples/qwen_vl/BUGS_AND_FIXES.md +232 -0
- examples/qwen_vl/IMAGE_VALIDATION_COMPLETE.md +271 -0
- examples/qwen_vl/IMAGE_VALIDATION_SUMMARY.md +260 -0
- examples/qwen_vl/INFERENCE_SFT_TESTS.md +412 -0
- examples/qwen_vl/NEXT_STEPS_2B.md +325 -0
- examples/qwen_vl/QUICKSTART.md +327 -0
- examples/qwen_vl/QUICKSTART_RL_VISION.md +110 -0
- examples/qwen_vl/README.md +152 -0
- examples/qwen_vl/RL_VISION_COMPLETE.md +475 -0
- examples/qwen_vl/RL_VISION_TESTING.md +333 -0
- examples/qwen_vl/SDK_VISION_INTEGRATION.md +328 -0
- examples/qwen_vl/SETUP_COMPLETE.md +274 -0
- examples/qwen_vl/VISION_TESTS_COMPLETE.md +489 -0
- examples/qwen_vl/VLM_PIPELINE_COMPLETE.md +242 -0
- examples/qwen_vl/__init__.py +2 -0
- examples/qwen_vl/collect_data_via_cli.md +415 -0
- examples/qwen_vl/collect_vision_traces.py +368 -0
- examples/qwen_vl/configs/crafter_rl_vision_qwen3vl4b.toml +110 -0
- examples/qwen_vl/configs/crafter_vlm_sft_example.toml +59 -0
- examples/qwen_vl/configs/eval_gpt4o_mini_vision.toml +26 -0
- examples/qwen_vl/configs/eval_gpt4o_vision_proper.toml +29 -0
- examples/qwen_vl/configs/eval_gpt5nano_vision.toml +26 -0
- examples/qwen_vl/configs/eval_qwen3vl_vision.toml +26 -0
- examples/qwen_vl/configs/filter_qwen3vl_sft.toml +49 -0
- examples/qwen_vl/configs/filter_vision_sft.toml +52 -0
- examples/qwen_vl/configs/filter_vision_test.toml +8 -0
- examples/qwen_vl/configs/sft_qwen3_vl_2b_test.toml +54 -0
- examples/qwen_vl/crafter_gpt5nano_agent.py +308 -0
- examples/qwen_vl/crafter_qwen_vl_agent.py +300 -0
- examples/qwen_vl/run_vision_comparison.sh +61 -0
- examples/qwen_vl/run_vision_sft_pipeline.sh +175 -0
- examples/qwen_vl/test_image_validation.py +201 -0
- examples/qwen_vl/test_sft_vision_data.py +110 -0
- examples/rl/README.md +169 -0
- examples/rl/configs/eval_base_qwen.toml +17 -0
- examples/rl/configs/eval_rl_qwen.toml +13 -0
- examples/rl/configs/rl_from_base_qwen.toml +62 -0
- examples/rl/configs/rl_from_base_qwen17.toml +80 -0
- examples/rl/configs/rl_from_ft_qwen.toml +37 -0
- examples/rl/download_dataset.py +80 -0
- examples/rl/run_eval.py +436 -0
- examples/rl/run_rl_and_save.py +111 -0
- examples/rl/task_app/README.md +21 -0
- {synth_ai/task/apps → examples/rl/task_app}/math_single_step.py +188 -50
- examples/rl/task_app/math_task_app.py +111 -0
- examples/run_crafter_demo.sh +10 -0
- examples/sdk_prompt_learning_example.py +55 -0
- examples/sft/README.md +139 -0
- examples/sft/configs/crafter_fft_qwen0p6b.toml +49 -0
- examples/sft/configs/crafter_lora_qwen0p6b.toml +49 -0
- examples/sft/evaluate.py +117 -0
- examples/sft/export_dataset.py +120 -0
- examples/sft/generate_traces.py +164 -0
- examples/swe/__init__.py +12 -0
- examples/swe/task_app/README.md +135 -0
- examples/swe/task_app/__init__.py +2 -0
- examples/swe/task_app/grpo_swe_mini.py +604 -0
- examples/swe/task_app/grpo_swe_mini_task_app.py +124 -0
- examples/swe/task_app/hosted/README.md +173 -0
- examples/swe/task_app/hosted/__init__.py +5 -0
- examples/swe/task_app/hosted/branching.py +143 -0
- examples/swe/task_app/hosted/environment_routes.py +1289 -0
- examples/swe/task_app/hosted/envs/__init__.py +1 -0
- examples/swe/task_app/hosted/envs/crafter/__init__.py +6 -0
- examples/swe/task_app/hosted/envs/crafter/app.py +1 -0
- examples/swe/task_app/hosted/envs/crafter/environment.py +522 -0
- examples/swe/task_app/hosted/envs/crafter/policy.py +478 -0
- examples/swe/task_app/hosted/envs/crafter/react_agent.py +108 -0
- examples/swe/task_app/hosted/envs/crafter/shared.py +305 -0
- examples/swe/task_app/hosted/envs/crafter/tools.py +47 -0
- examples/swe/task_app/hosted/envs/mini_swe/__init__.py +8 -0
- examples/swe/task_app/hosted/envs/mini_swe/environment.py +1191 -0
- examples/swe/task_app/hosted/envs/mini_swe/policy.py +355 -0
- examples/swe/task_app/hosted/envs/mini_swe/shared.py +83 -0
- examples/swe/task_app/hosted/envs/mini_swe/tools.py +96 -0
- examples/swe/task_app/hosted/hosted_app.py +204 -0
- examples/swe/task_app/hosted/inference/__init__.py +5 -0
- examples/swe/task_app/hosted/inference/openai_client.py +584 -0
- examples/swe/task_app/hosted/main.py +100 -0
- examples/swe/task_app/hosted/policy_routes.py +1094 -0
- examples/swe/task_app/hosted/registry.py +195 -0
- examples/swe/task_app/hosted/rollout.py +1905 -0
- examples/swe/task_app/hosted/storage/__init__.py +5 -0
- examples/swe/task_app/hosted/storage/volume.py +211 -0
- examples/swe/task_app/hosted/test_agents.py +161 -0
- examples/swe/task_app/hosted/test_service.py +136 -0
- examples/swe/task_app/hosted/utils.py +62 -0
- examples/swe/task_app/morph_backend.py +178 -0
- examples/task_apps/IMAGE_ONLY_EVAL_QUICKSTART.md +258 -0
- examples/task_apps/TESTING.md +275 -0
- examples/task_apps/banking77/__init__.py +6 -0
- examples/task_apps/banking77/banking77_task_app.py +912 -0
- examples/task_apps/banking77/deploy_wrapper.py +46 -0
- examples/task_apps/banking77_pipeline/__init__.py +6 -0
- examples/task_apps/banking77_pipeline/banking77_pipeline_task_app.py +489 -0
- examples/task_apps/banking77_pipeline/deploy_wrapper.py +50 -0
- examples/task_apps/crafter/CREATE_SFT_DATASET.md +286 -0
- examples/task_apps/crafter/EVAL_IMAGE_ONLY_RESULTS.md +152 -0
- examples/task_apps/crafter/FILTER_COMMAND_STATUS.md +187 -0
- examples/task_apps/crafter/FILTER_COMMAND_SUCCESS.md +281 -0
- examples/task_apps/crafter/QUERY_EXAMPLES.md +203 -0
- examples/task_apps/crafter/README_IMAGE_ONLY_EVAL.md +316 -0
- examples/task_apps/crafter/eval_image_only_gpt4o.toml +28 -0
- examples/task_apps/crafter/eval_text_only_groq_llama.toml +36 -0
- examples/task_apps/crafter/filter_sft_dataset.toml +16 -0
- examples/task_apps/crafter/task_app/README.md +42 -0
- examples/task_apps/crafter/task_app/__init__.py +5 -0
- examples/task_apps/crafter/task_app/grpo_crafter.py +1055 -0
- examples/task_apps/crafter/task_app/grpo_crafter_task_app.py +146 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/README.md +173 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/__init__.py +5 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/branching.py +143 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/environment_routes.py +1226 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/__init__.py +1 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/__init__.py +6 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/app.py +1 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/environment.py +532 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/policy.py +583 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/react_agent.py +122 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/shared.py +305 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/tools.py +47 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/hosted_app.py +253 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/inference/__init__.py +5 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/inference/openai_client.py +999 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/main.py +100 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/policy_routes.py +1252 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/registry.py +195 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/rollout.py +2233 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/storage/__init__.py +5 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/storage/volume.py +211 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/test_agents.py +161 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/test_service.py +136 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/utils.py +411 -0
- examples/task_apps/dev/pokemon_emerald/__init__.py +2 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/README.md +811 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/__init__.py +120 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/action.py +160 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/memory.py +155 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/perception.py +69 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/planning.py +96 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/simple.py +1502 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/system_prompt.py +4 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/grab_map.py +68 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/manual.py +216 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/__init__.py +35 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/emerald_utils.py +631 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/emulator.py +1544 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/enums.py +1428 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/memory_reader.py +4848 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/types.py +41 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/utils.py +298 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pyproject.toml +95 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/run.py +204 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/server/app.py +2152 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/server/client.py +429 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/server/frame_server.py +155 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/README.md +78 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/run_tests.py +122 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_agent_direct.py +76 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_agent_prompts.py +413 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_battle_state_formatting.py +204 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_dialogue_detection.py +133 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_dialogue_detection_comprehensive.py +229 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_direct_agent_emulator.py +300 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_fps_adjustment_pytest.py +205 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_house_to_outside_direct.py +200 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_house_to_outside_transition.py +284 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_map_ground_truth_comparison.py +468 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_memory_map.py +575 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_server_map_validation.py +311 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_torchic_state.py +259 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/anticheat.py +372 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/checkpoint.py +296 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/error_handler.py +275 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/get_local_ip.py +22 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/helpers.py +44 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/llm_logger.py +514 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/map_formatter.py +415 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/map_stitcher.py +1763 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/map_stitcher_singleton.py +33 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/map_trimmer.py +106 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/map_visualizer.py +334 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/ocr_dialogue.py +1020 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/recording.py +188 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/state_formatter.py +1481 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/vlm.py +862 -0
- examples/task_apps/dev/pokemon_emerald/modal_app.py +114 -0
- examples/task_apps/dev/pokemon_emerald/task_app/README.md +81 -0
- examples/task_apps/dev/pokemon_emerald/task_app/__init__.py +6 -0
- examples/task_apps/dev/pokemon_emerald/task_app/pokemon_emerald.py +685 -0
- examples/task_apps/enron/__init__.py +2 -0
- examples/task_apps/enron/eval_groq_qwen32.toml +16 -0
- examples/task_apps/enron/filter_sft.toml +5 -0
- examples/task_apps/enron/task_app/README.md +14 -0
- examples/task_apps/enron/task_app/__init__.py +1 -0
- examples/task_apps/enron/task_app/grpo_enron.py +906 -0
- examples/task_apps/enron/task_app/grpo_enron_task_app.py +146 -0
- examples/task_apps/enron/tests/__init__.py +4 -0
- examples/task_apps/enron/tests/conftest.py +115 -0
- examples/task_apps/enron/tests/integration/__init__.py +4 -0
- examples/task_apps/enron/tests/integration/test_enron_eval.py +179 -0
- examples/task_apps/enron/tests/integration/test_enron_rollout.py +135 -0
- examples/task_apps/enron/tests/unit/__init__.py +4 -0
- examples/task_apps/enron/tests/unit/test_enron_environment.py +126 -0
- examples/task_apps/gepa_benchmarks/__init__.py +7 -0
- examples/task_apps/gepa_benchmarks/common.py +260 -0
- examples/task_apps/gepa_benchmarks/hotpotqa_task_app.py +507 -0
- examples/task_apps/gepa_benchmarks/hover_task_app.py +436 -0
- examples/task_apps/gepa_benchmarks/ifbench_task_app.py +563 -0
- examples/task_apps/gepa_benchmarks/pupa_task_app.py +460 -0
- examples/task_apps/math/README.md +21 -0
- examples/task_apps/math/math_single_step.py +1000 -0
- examples/task_apps/math/math_task_app.py +115 -0
- examples/task_apps/pokemon_battle/__init__.py +2 -0
- examples/task_apps/pokemon_battle/modal_app.py +104 -0
- examples/task_apps/pokemon_battle/task_app/README.md +68 -0
- examples/task_apps/pokemon_battle/task_app/__init__.py +6 -0
- examples/task_apps/pokemon_battle/task_app/pokemon_showdown.py +932 -0
- examples/task_apps/pokemon_red/EVAL_IMAGE_ONLY_COMPLETE.md +283 -0
- examples/task_apps/pokemon_red/EVAL_IMAGE_ONLY_STATUS.md +155 -0
- examples/task_apps/pokemon_red/README.md +356 -0
- examples/task_apps/pokemon_red/README_IMAGE_ONLY_EVAL.md +428 -0
- examples/task_apps/pokemon_red/__init__.py +3 -0
- examples/task_apps/pokemon_red/eval_image_only_gpt4o.toml +30 -0
- examples/task_apps/pokemon_red/eval_pokemon_red_policy.py +224 -0
- examples/task_apps/pokemon_red/pallet_town_rl_config.toml +75 -0
- examples/task_apps/pokemon_red/task_app.py +1048 -0
- examples/task_apps/pokemon_red/test_pallet_town_rewards.py +193 -0
- examples/task_apps/sokoban/README.md +306 -0
- examples/task_apps/sokoban/__init__.py +3 -0
- examples/task_apps/sokoban/eval_groq_qwen32.toml +16 -0
- examples/task_apps/sokoban/eval_openai_gpt5.toml +16 -0
- examples/task_apps/sokoban/filter_sft.toml +5 -0
- examples/task_apps/sokoban/task_app.py +1058 -0
- examples/task_apps/sokoban/tests/__init__.py +4 -0
- examples/task_apps/sokoban/tests/conftest.py +113 -0
- examples/task_apps/sokoban/tests/integration/__init__.py +4 -0
- examples/task_apps/sokoban/tests/integration/test_sokoban_eval.py +57 -0
- examples/task_apps/sokoban/tests/integration/test_sokoban_rollout.py +198 -0
- examples/task_apps/sokoban/tests/unit/__init__.py +4 -0
- examples/task_apps/sokoban/tests/unit/test_sokoban_environment.py +114 -0
- examples/task_apps/verilog/__init__.py +1 -0
- examples/task_apps/verilog/eval_groq_qwen32b.toml +22 -0
- examples/task_apps/verilog/filter_sft.toml +5 -0
- examples/task_apps/verilog/task_app/README.md +12 -0
- examples/task_apps/verilog/task_app/__init__.py +1 -0
- examples/task_apps/verilog/task_app/grpo_verilog.py +1166 -0
- examples/task_apps/verilog/task_app/grpo_verilog_task_app.py +145 -0
- examples/task_apps/verilog/tests/__init__.py +4 -0
- examples/task_apps/verilog/tests/conftest.py +115 -0
- examples/task_apps/verilog/tests/integration/__init__.py +4 -0
- examples/task_apps/verilog/tests/integration/test_verilog_eval.py +181 -0
- examples/task_apps/verilog/tests/integration/test_verilog_rollout.py +55 -0
- examples/task_apps/verilog/tests/unit/__init__.py +4 -0
- examples/task_apps/verilog/tests/unit/test_verilog_scoring.py +118 -0
- examples/tunnel_gepa_banking77/README.md +106 -0
- examples/tunnel_gepa_banking77/banking77_gepa_tunnel.toml +95 -0
- examples/tunnel_gepa_banking77/keep_tunnel_running.py +60 -0
- examples/tunnel_gepa_banking77/run_gepa_with_tunnel.sh +226 -0
- examples/vlm/PROPOSAL.md +53 -0
- examples/vlm/README.md +68 -0
- examples/vlm/configs/crafter_vlm_gpt4o.toml +49 -0
- examples/vlm/crafter_image_only_agent.py +207 -0
- examples/vlm/crafter_openai_vlm_agent.py +275 -0
- examples/vlm/filter_image_rows.py +63 -0
- examples/vlm/run_crafter_vlm_benchmark.py +316 -0
- examples/warming_up_to_rl/_utils.py +92 -0
- examples/warming_up_to_rl/analyze_trace_db.py +422 -0
- examples/warming_up_to_rl/configs/crafter_fft.toml +53 -0
- examples/warming_up_to_rl/configs/crafter_fft_4b.toml +54 -0
- examples/warming_up_to_rl/configs/eval_fft_qwen4b.toml +22 -0
- examples/warming_up_to_rl/configs/eval_groq_qwen32b.toml +15 -0
- examples/warming_up_to_rl/configs/eval_modal_qwen4b.toml +24 -0
- examples/warming_up_to_rl/configs/eval_stepwise_complex.toml +35 -0
- examples/warming_up_to_rl/configs/eval_stepwise_consistent.toml +26 -0
- examples/warming_up_to_rl/configs/eval_stepwise_per_achievement.toml +36 -0
- examples/warming_up_to_rl/configs/eval_stepwise_simple.toml +32 -0
- examples/warming_up_to_rl/configs/rl_from_base_qwen4b.toml +85 -0
- examples/warming_up_to_rl/configs/rl_from_ft.toml +58 -0
- examples/warming_up_to_rl/export_trace_sft.py +837 -0
- examples/warming_up_to_rl/groq_test.py +97 -0
- examples/warming_up_to_rl/manage_secrets.py +131 -0
- examples/warming_up_to_rl/old/event_rewards.md +234 -0
- examples/warming_up_to_rl/old/notes.md +73 -0
- examples/warming_up_to_rl/readme.md +110 -0
- examples/warming_up_to_rl/run_eval.py +736 -0
- examples/warming_up_to_rl/run_fft_and_save.py +380 -0
- examples/warming_up_to_rl/run_local_rollout.py +239 -0
- examples/warming_up_to_rl/run_local_rollout_modal.py +248 -0
- examples/warming_up_to_rl/run_local_rollout_parallel.py +405 -0
- examples/warming_up_to_rl/run_local_rollout_traced.py +477 -0
- examples/warming_up_to_rl/run_rl_and_save.py +124 -0
- examples/warming_up_to_rl/run_rollout_remote.py +156 -0
- examples/warming_up_to_rl/task_app/README.md +42 -0
- examples/warming_up_to_rl/task_app/grpo_crafter.py +876 -0
- examples/warming_up_to_rl/task_app/grpo_crafter_task_app.py +135 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/README.md +173 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/__init__.py +5 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/branching.py +143 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/environment_routes.py +1226 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/__init__.py +1 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/__init__.py +6 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/app.py +1 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/environment.py +522 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/policy.py +454 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/react_agent.py +108 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/shared.py +305 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/tools.py +47 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/hosted_app.py +253 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/__init__.py +5 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/openai_client.py +729 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/main.py +100 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/policy_routes.py +1114 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/registry.py +195 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/rollout.py +1891 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/__init__.py +5 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/volume.py +211 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/test_agents.py +161 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/test_service.py +137 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/utils.py +129 -0
- examples/workflows/math_rl/configs/eval_base_qwen.toml +15 -0
- examples/workflows/math_rl/configs/eval_rl_qwen.toml +11 -0
- examples/workflows/math_rl/configs/rl_from_base_qwen.toml +62 -0
- examples/workflows/math_rl/configs/rl_from_base_qwen17.toml +80 -0
- examples/workflows/math_rl/configs/rl_from_ft_qwen.toml +35 -0
- examples/workflows/math_rl/download_dataset.py +80 -0
- examples/workflows/math_rl/run_eval.py +436 -0
- examples/workflows/math_rl/run_rl_and_save.py +111 -0
- synth_ai/__init__.py +47 -23
- synth_ai/_utils/__init__.py +47 -0
- synth_ai/_utils/base_url.py +10 -0
- synth_ai/_utils/http.py +10 -0
- synth_ai/_utils/prompts.py +10 -0
- synth_ai/_utils/task_app_state.py +12 -0
- synth_ai/_utils/user_config.py +10 -0
- synth_ai/api/models/supported.py +514 -0
- synth_ai/api/train/__init__.py +60 -2
- synth_ai/api/train/builders.py +347 -39
- synth_ai/api/train/cli.py +895 -160
- synth_ai/api/train/config_finder.py +103 -25
- synth_ai/api/train/configs/__init__.py +65 -0
- synth_ai/api/train/configs/prompt_learning.py +496 -0
- synth_ai/api/train/configs/rl.py +188 -0
- synth_ai/api/train/configs/sft.py +99 -0
- synth_ai/api/train/configs/shared.py +81 -0
- synth_ai/api/train/env_resolver.py +70 -20
- synth_ai/api/train/pollers.py +29 -4
- synth_ai/api/train/prompt_learning.py +425 -0
- synth_ai/api/train/sft.py +390 -0
- synth_ai/api/train/supported_algos.py +147 -0
- synth_ai/api/train/task_app.py +6 -4
- synth_ai/api/train/utils.py +64 -52
- synth_ai/api/train/validators.py +1117 -0
- synth_ai/api/tunnel.py +49 -0
- synth_ai/auth/credentials.py +94 -0
- synth_ai/baseline/__init__.py +25 -0
- synth_ai/baseline/config.py +209 -0
- synth_ai/baseline/discovery.py +214 -0
- synth_ai/baseline/execution.py +146 -0
- synth_ai/cfgs.py +227 -0
- synth_ai/cli/__init__.py +85 -63
- synth_ai/cli/_modal_wrapper.py +31 -0
- synth_ai/cli/_storage.py +20 -0
- synth_ai/cli/_typer_patch.py +47 -0
- synth_ai/cli/_validate_task_app.py +29 -0
- synth_ai/cli/balance.py +16 -4
- synth_ai/cli/calc.py +36 -21
- synth_ai/cli/claude.py +70 -0
- synth_ai/cli/codex.py +267 -0
- synth_ai/cli/commands/__init__.py +18 -0
- synth_ai/cli/commands/baseline/__init__.py +12 -0
- synth_ai/cli/commands/baseline/core.py +637 -0
- synth_ai/cli/commands/baseline/list.py +93 -0
- synth_ai/cli/commands/demo/__init__.py +6 -0
- synth_ai/cli/commands/demo/core.py +163 -0
- synth_ai/cli/commands/eval/__init__.py +19 -0
- synth_ai/cli/commands/eval/core.py +1112 -0
- synth_ai/cli/commands/eval/errors.py +81 -0
- synth_ai/cli/commands/eval/validation.py +133 -0
- synth_ai/cli/commands/filter/__init__.py +12 -0
- synth_ai/cli/commands/filter/core.py +424 -0
- synth_ai/cli/commands/filter/errors.py +55 -0
- synth_ai/cli/commands/filter/validation.py +77 -0
- synth_ai/cli/commands/help/__init__.py +185 -0
- synth_ai/cli/commands/help/core.py +72 -0
- synth_ai/cli/commands/smoke/__init__.py +7 -0
- synth_ai/cli/commands/smoke/core.py +1437 -0
- synth_ai/cli/commands/status/__init__.py +66 -0
- synth_ai/cli/commands/status/client.py +192 -0
- synth_ai/cli/commands/status/config.py +92 -0
- synth_ai/cli/commands/status/errors.py +20 -0
- synth_ai/cli/commands/status/formatters.py +164 -0
- synth_ai/cli/commands/status/subcommands/__init__.py +9 -0
- synth_ai/cli/commands/status/subcommands/files.py +79 -0
- synth_ai/cli/commands/status/subcommands/jobs.py +334 -0
- synth_ai/cli/commands/status/subcommands/models.py +79 -0
- synth_ai/cli/commands/status/subcommands/pricing.py +22 -0
- synth_ai/cli/commands/status/subcommands/runs.py +81 -0
- synth_ai/cli/commands/status/subcommands/session.py +183 -0
- synth_ai/cli/commands/status/subcommands/summary.py +47 -0
- synth_ai/cli/commands/status/subcommands/usage.py +203 -0
- synth_ai/cli/commands/status/utils.py +114 -0
- synth_ai/cli/commands/train/__init__.py +53 -0
- synth_ai/cli/commands/train/core.py +21 -0
- synth_ai/cli/commands/train/errors.py +117 -0
- synth_ai/cli/commands/train/judge_schemas.py +200 -0
- synth_ai/cli/commands/train/judge_validation.py +305 -0
- synth_ai/cli/commands/train/validation.py +386 -0
- synth_ai/cli/demo.py +32 -140
- synth_ai/cli/deploy.py +233 -0
- synth_ai/cli/eval/__init__.py +36 -0
- synth_ai/cli/eval/core.py +5 -0
- synth_ai/cli/eval/errors.py +31 -0
- synth_ai/cli/eval/validation.py +5 -0
- synth_ai/cli/filter/__init__.py +28 -0
- synth_ai/cli/filter/core.py +5 -0
- synth_ai/cli/filter/errors.py +23 -0
- synth_ai/cli/filter/validation.py +5 -0
- synth_ai/cli/legacy_root_backup.py +28 -22
- synth_ai/cli/lib/__init__.py +10 -0
- synth_ai/cli/lib/task_app_discovery.py +7 -0
- synth_ai/cli/lib/task_app_env.py +518 -0
- synth_ai/cli/mcp.py +34 -0
- synth_ai/cli/modal_serve/__init__.py +12 -0
- synth_ai/cli/modal_serve/core.py +14 -0
- synth_ai/cli/modal_serve/errors.py +8 -0
- synth_ai/cli/modal_serve/validation.py +11 -0
- synth_ai/cli/opencode.py +256 -0
- synth_ai/cli/recent.py +13 -7
- synth_ai/cli/rl_demo.py +156 -116
- synth_ai/cli/root.py +131 -132
- synth_ai/cli/serve/__init__.py +12 -0
- synth_ai/cli/serve/core.py +14 -0
- synth_ai/cli/serve/errors.py +8 -0
- synth_ai/cli/serve/validation.py +11 -0
- synth_ai/cli/setup.py +49 -0
- synth_ai/cli/status.py +7 -125
- synth_ai/cli/task_app_deploy.py +7 -0
- synth_ai/cli/task_app_list.py +25 -0
- synth_ai/cli/task_app_modal_serve.py +11 -0
- synth_ai/cli/task_app_serve.py +11 -0
- synth_ai/cli/task_apps.py +2284 -257
- synth_ai/cli/traces.py +9 -5
- synth_ai/cli/train/__init__.py +12 -0
- synth_ai/cli/train/core.py +21 -0
- synth_ai/cli/train/errors.py +8 -0
- synth_ai/cli/train/validation.py +24 -0
- synth_ai/cli/train.py +5 -0
- synth_ai/cli/turso.py +73 -0
- synth_ai/cli/watch.py +13 -18
- synth_ai/demos/__init__.py +10 -0
- synth_ai/demos/core/__init__.py +28 -1
- synth_ai/demos/core/cli.py +579 -291
- synth_ai/demos/crafter/__init__.py +1 -0
- synth_ai/demos/crafter/crafter_fft_4b.toml +55 -0
- synth_ai/demos/crafter/grpo_crafter_task_app.py +185 -0
- synth_ai/demos/crafter/rl_from_base_qwen4b.toml +74 -0
- synth_ai/demos/demo_registry.py +176 -0
- synth_ai/demos/demo_task_apps/__init__.py +3 -3
- synth_ai/demos/demo_task_apps/core.py +64 -28
- synth_ai/demos/demo_task_apps/crafter/__init__.py +1 -0
- synth_ai/demos/demo_task_apps/crafter/configs/crafter_fft_4b.toml +53 -0
- synth_ai/demos/demo_task_apps/crafter/configs/rl_from_base_qwen4b.toml +73 -0
- synth_ai/demos/demo_task_apps/crafter/grpo_crafter_task_app.py +184 -0
- synth_ai/demos/demo_task_apps/math/_common.py +1 -2
- synth_ai/demos/demo_task_apps/math/app.py +2 -1
- synth_ai/demos/demo_task_apps/math/deploy_modal.py +3 -6
- synth_ai/demos/demo_task_apps/math/modal_task_app.py +185 -83
- synth_ai/demos/demo_task_apps/math/task_app_entry.py +0 -2
- synth_ai/demos/math/__init__.py +1 -0
- synth_ai/demos/math/_common.py +16 -0
- synth_ai/demos/math/app.py +38 -0
- synth_ai/demos/math/config.toml +76 -0
- synth_ai/demos/math/deploy_modal.py +54 -0
- synth_ai/demos/math/modal_task_app.py +703 -0
- synth_ai/demos/math/task_app_entry.py +51 -0
- synth_ai/environments/environment/core.py +7 -1
- synth_ai/environments/examples/bandit/engine.py +12 -5
- synth_ai/environments/examples/bandit/environment.py +0 -1
- synth_ai/environments/examples/bandit/taskset.py +4 -4
- synth_ai/environments/examples/crafter_classic/engine_deterministic_patch.py +7 -4
- synth_ai/environments/examples/crafter_classic/engine_serialization_patch_v3.py +9 -5
- synth_ai/environments/examples/crafter_classic/environment.py +93 -2
- synth_ai/environments/examples/crafter_classic/world_config_patch_simple.py +4 -3
- synth_ai/environments/examples/enron/engine.py +7 -2
- synth_ai/environments/examples/enron/environment.py +68 -0
- synth_ai/environments/examples/red/engine.py +60 -12
- synth_ai/environments/examples/red/engine_helpers/memory_map.py +7 -0
- synth_ai/environments/examples/red/engine_helpers/reward_components.py +151 -179
- synth_ai/environments/examples/red/engine_helpers/reward_library/pallet_town_progression.py +477 -0
- synth_ai/environments/examples/red/engine_helpers/state_extraction.py +32 -0
- synth_ai/environments/examples/red/environment.py +86 -0
- synth_ai/environments/examples/red/trace_hooks_v3.py +168 -0
- synth_ai/environments/examples/sokoban/taskset.py +116 -0
- synth_ai/environments/examples/verilog/engine.py +104 -12
- synth_ai/environments/examples/wordle/environment.py +0 -1
- synth_ai/environments/reproducibility/tree.py +5 -6
- synth_ai/environments/service/app.py +11 -12
- synth_ai/environments/service/core_routes.py +10 -9
- synth_ai/environments/stateful/engine.py +1 -1
- synth_ai/environments/tasks/core.py +1 -0
- synth_ai/environments/tasks/filters.py +5 -6
- synth_ai/environments/tasks/utils.py +4 -5
- synth_ai/evals/__init__.py +15 -0
- synth_ai/evals/base.py +14 -5
- synth_ai/evals/client.py +82 -0
- synth_ai/evals/types.py +42 -0
- synth_ai/http.py +8 -22
- synth_ai/http_client.py +45 -12
- synth_ai/inference/__init__.py +0 -2
- synth_ai/inference/client.py +21 -7
- synth_ai/jobs/client.py +129 -80
- synth_ai/judge_schemas.py +127 -0
- synth_ai/learning/__init__.py +51 -6
- synth_ai/learning/algorithms.py +14 -0
- synth_ai/learning/client.py +122 -30
- synth_ai/learning/config.py +2 -40
- synth_ai/learning/constants.py +0 -2
- synth_ai/learning/ft_client.py +4 -56
- synth_ai/learning/health.py +14 -8
- synth_ai/learning/jobs.py +43 -47
- synth_ai/learning/prompt_learning_client.py +276 -0
- synth_ai/learning/prompt_learning_types.py +185 -0
- synth_ai/{rl → learning/rl}/__init__.py +14 -5
- synth_ai/learning/rl/client.py +269 -0
- synth_ai/learning/rl/config.py +31 -0
- synth_ai/{rl → learning/rl}/contracts.py +5 -10
- synth_ai/{rl → learning/rl}/env_keys.py +45 -16
- synth_ai/learning/rl/secrets.py +13 -0
- synth_ai/learning/rl_client.py +2 -253
- synth_ai/learning/sft/__init__.py +29 -0
- synth_ai/learning/sft/client.py +68 -0
- synth_ai/learning/sft/config.py +270 -0
- synth_ai/learning/sft/data.py +698 -0
- synth_ai/learning/sse.py +25 -26
- synth_ai/learning/validators.py +29 -25
- synth_ai/mcp/__init__.py +5 -0
- synth_ai/mcp/__main__.py +8 -0
- synth_ai/mcp/main.py +254 -0
- synth_ai/mcp/setup.py +100 -0
- synth_ai/modal.py +257 -0
- synth_ai/pricing/__init__.py +3 -0
- synth_ai/pricing/model_pricing.py +64 -0
- synth_ai/session/__init__.py +75 -0
- synth_ai/session/client.py +383 -0
- synth_ai/session/constants.py +63 -0
- synth_ai/session/exceptions.py +105 -0
- synth_ai/session/manager.py +139 -0
- synth_ai/session/models.py +89 -0
- synth_ai/session/query.py +110 -0
- synth_ai/spec/__init__.py +46 -0
- synth_ai/spec/dataclasses.py +149 -0
- synth_ai/spec/loader.py +144 -0
- synth_ai/spec/serializer.py +199 -0
- synth_ai/spec/validation.py +250 -0
- synth_ai/streaming/__init__.py +29 -0
- synth_ai/streaming/config.py +94 -0
- synth_ai/streaming/handlers.py +589 -0
- synth_ai/streaming/streamer.py +320 -0
- synth_ai/streaming/types.py +95 -0
- synth_ai/task/__init__.py +50 -30
- synth_ai/task/apps/__init__.py +63 -19
- synth_ai/task/auth.py +35 -23
- synth_ai/task/client.py +15 -13
- synth_ai/task/config.py +261 -0
- synth_ai/task/contracts.py +165 -64
- synth_ai/task/datasets.py +9 -6
- synth_ai/task/errors.py +11 -10
- synth_ai/task/health.py +17 -11
- synth_ai/task/inference_api.py +101 -0
- synth_ai/task/json.py +58 -24
- synth_ai/task/proxy.py +59 -66
- synth_ai/task/rubrics/__init__.py +55 -0
- synth_ai/task/rubrics/loaders.py +156 -0
- synth_ai/task/rubrics/models.py +57 -0
- synth_ai/task/rubrics/scoring.py +116 -0
- synth_ai/task/rubrics/strict.py +149 -0
- synth_ai/task/rubrics.py +22 -15
- synth_ai/task/server.py +65 -31
- synth_ai/task/trace_correlation_helpers.py +328 -0
- synth_ai/task/tracing_utils.py +44 -28
- synth_ai/task/validators.py +449 -6
- synth_ai/task/vendors.py +5 -7
- synth_ai/tracing_v3/__init__.py +4 -0
- synth_ai/tracing_v3/abstractions.py +21 -4
- synth_ai/tracing_v3/config.py +167 -22
- synth_ai/tracing_v3/constants.py +21 -0
- synth_ai/tracing_v3/db_config.py +42 -29
- synth_ai/tracing_v3/decorators.py +80 -45
- synth_ai/tracing_v3/examples/basic_usage.py +15 -9
- synth_ai/tracing_v3/hooks.py +6 -4
- synth_ai/tracing_v3/llm_call_record_helpers.py +161 -61
- synth_ai/tracing_v3/migration_helper.py +1 -2
- synth_ai/tracing_v3/replica_sync.py +12 -7
- synth_ai/tracing_v3/serialization.py +130 -0
- synth_ai/tracing_v3/session_tracer.py +73 -16
- synth_ai/tracing_v3/storage/base.py +89 -1
- synth_ai/tracing_v3/storage/config.py +63 -16
- synth_ai/tracing_v3/storage/factory.py +11 -9
- synth_ai/tracing_v3/storage/utils.py +15 -11
- synth_ai/tracing_v3/trace_utils.py +317 -0
- synth_ai/tracing_v3/turso/__init__.py +8 -21
- synth_ai/tracing_v3/turso/daemon.py +123 -15
- synth_ai/tracing_v3/turso/models.py +5 -2
- synth_ai/tracing_v3/turso/native_manager.py +1293 -0
- synth_ai/tracing_v3/utils.py +5 -4
- synth_ai/tunnel.py +143 -0
- synth_ai/tunnel_deploy.py +278 -0
- synth_ai/types.py +8 -0
- synth_ai/urls.py +11 -0
- synth_ai/utils/__init__.py +166 -0
- synth_ai/utils/agents.py +74 -0
- synth_ai/utils/apps.py +152 -0
- synth_ai/utils/base_url.py +94 -0
- synth_ai/utils/bin.py +39 -0
- synth_ai/utils/claude.py +36 -0
- synth_ai/utils/cli.py +284 -0
- synth_ai/utils/config.py +81 -0
- synth_ai/utils/env.py +346 -0
- synth_ai/utils/errors.py +85 -0
- synth_ai/utils/http.py +172 -0
- synth_ai/utils/json.py +72 -0
- synth_ai/utils/log_filter.py +99 -0
- synth_ai/utils/logging.py +198 -0
- synth_ai/utils/modal.py +299 -0
- synth_ai/utils/paths.py +95 -0
- synth_ai/utils/process.py +233 -0
- synth_ai/utils/prompts.py +39 -0
- synth_ai/utils/sqld.py +122 -0
- synth_ai/utils/ssl.py +25 -0
- synth_ai/utils/task_app_discovery.py +882 -0
- synth_ai/utils/task_app_env.py +186 -0
- synth_ai/utils/task_app_state.py +318 -0
- synth_ai/utils/tunnel/__init__.py +12 -0
- synth_ai/utils/tunnel/config.py +55 -0
- synth_ai/utils/user_config.py +137 -0
- synth_ai/uvicorn.py +77 -0
- synth_ai-0.2.23.dev3.dist-info/METADATA +357 -0
- synth_ai-0.2.23.dev3.dist-info/RECORD +983 -0
- {synth_ai-0.2.9.dev0.dist-info → synth_ai-0.2.23.dev3.dist-info}/entry_points.txt +0 -1
- {synth_ai-0.2.9.dev0.dist-info → synth_ai-0.2.23.dev3.dist-info}/top_level.txt +1 -0
- synth_ai/cli/man.py +0 -106
- synth_ai/core/experiment.py +0 -15
- synth_ai/core/system.py +0 -15
- synth_ai/demo_registry.py +0 -258
- synth_ai/environments/examples/sokoban/units/astar_common.py +0 -95
- synth_ai/experimental/synth_oss.py +0 -446
- synth_ai/handshake.py +0 -107
- synth_ai/install_sqld.sh +0 -40
- synth_ai/learning/offline/dpo.py +0 -0
- synth_ai/learning/offline/providers.py +0 -7
- synth_ai/learning/offline/sft.py +0 -0
- synth_ai/learning/offline/shared.py +0 -0
- synth_ai/learning/online/grpo.py +0 -0
- synth_ai/learning/online/irft.py +0 -0
- synth_ai/learning/prompts/banking77_injection_eval.py +0 -168
- synth_ai/learning/prompts/gepa.py +0 -0
- synth_ai/learning/prompts/hello_world_in_context_injection_ex.py +0 -213
- synth_ai/learning/prompts/mipro.py +0 -289
- synth_ai/learning/prompts/random_search.py +0 -246
- synth_ai/learning/prompts/run_mipro_banking77.py +0 -172
- synth_ai/learning/prompts/run_random_search_banking77.py +0 -324
- synth_ai/lm/__init__.py +0 -51
- synth_ai/lm/caching/constants.py +0 -6
- synth_ai/lm/caching/dbs.py +0 -0
- synth_ai/lm/caching/ephemeral.py +0 -102
- synth_ai/lm/caching/handler.py +0 -137
- synth_ai/lm/caching/initialize.py +0 -11
- synth_ai/lm/caching/persistent.py +0 -114
- synth_ai/lm/config.py +0 -110
- synth_ai/lm/constants.py +0 -32
- synth_ai/lm/core/__init__.py +0 -8
- synth_ai/lm/core/all.py +0 -73
- synth_ai/lm/core/exceptions.py +0 -7
- synth_ai/lm/core/main.py +0 -319
- synth_ai/lm/core/main_v3.py +0 -594
- synth_ai/lm/core/synth_models.py +0 -48
- synth_ai/lm/core/vendor_clients.py +0 -188
- synth_ai/lm/cost/monitor.py +0 -1
- synth_ai/lm/cost/statefulness.py +0 -1
- synth_ai/lm/injection.py +0 -80
- synth_ai/lm/overrides.py +0 -206
- synth_ai/lm/provider_support/__init__.py +0 -8
- synth_ai/lm/provider_support/anthropic.py +0 -972
- synth_ai/lm/provider_support/openai.py +0 -1139
- synth_ai/lm/provider_support/suppress_logging.py +0 -31
- synth_ai/lm/structured_outputs/handler.py +0 -440
- synth_ai/lm/structured_outputs/inject.py +0 -297
- synth_ai/lm/structured_outputs/rehabilitate.py +0 -185
- synth_ai/lm/tools/__init__.py +0 -3
- synth_ai/lm/tools/base.py +0 -172
- synth_ai/lm/unified_interface.py +0 -202
- synth_ai/lm/vendors/base.py +0 -81
- synth_ai/lm/vendors/core/anthropic_api.py +0 -387
- synth_ai/lm/vendors/core/gemini_api.py +0 -292
- synth_ai/lm/vendors/core/mistral_api.py +0 -322
- synth_ai/lm/vendors/core/openai_api.py +0 -225
- synth_ai/lm/vendors/core/synth_dev_api.py +0 -0
- synth_ai/lm/vendors/local/ollama.py +0 -0
- synth_ai/lm/vendors/openai_standard.py +0 -780
- synth_ai/lm/vendors/openai_standard_responses.py +0 -256
- synth_ai/lm/vendors/retries.py +0 -22
- synth_ai/lm/vendors/supported/custom_endpoint.py +0 -417
- synth_ai/lm/vendors/supported/deepseek.py +0 -69
- synth_ai/lm/vendors/supported/grok.py +0 -75
- synth_ai/lm/vendors/supported/groq.py +0 -16
- synth_ai/lm/vendors/supported/ollama.py +0 -15
- synth_ai/lm/vendors/supported/openrouter.py +0 -74
- synth_ai/lm/vendors/supported/together.py +0 -11
- synth_ai/lm/vendors/synth_client.py +0 -808
- synth_ai/lm/warmup.py +0 -186
- synth_ai/rl/secrets.py +0 -19
- synth_ai/scripts/verify_rewards.py +0 -100
- synth_ai/task/apps/grpo_crafter.py +0 -438
- synth_ai/tracing/__init__.py +0 -30
- synth_ai/tracing_v1/__init__.py +0 -33
- synth_ai/tracing_v3/turso/manager.py +0 -774
- synth_ai/v0/tracing/abstractions.py +0 -224
- synth_ai/v0/tracing/base_client.py +0 -91
- synth_ai/v0/tracing/client_manager.py +0 -131
- synth_ai/v0/tracing/config.py +0 -142
- synth_ai/v0/tracing/context.py +0 -146
- synth_ai/v0/tracing/decorators.py +0 -682
- synth_ai/v0/tracing/events/__init__.py +0 -0
- synth_ai/v0/tracing/events/manage.py +0 -147
- synth_ai/v0/tracing/events/scope.py +0 -86
- synth_ai/v0/tracing/events/store.py +0 -228
- synth_ai/v0/tracing/immediate_client.py +0 -151
- synth_ai/v0/tracing/local.py +0 -18
- synth_ai/v0/tracing/log_client_base.py +0 -73
- synth_ai/v0/tracing/retry_queue.py +0 -186
- synth_ai/v0/tracing/trackers.py +0 -515
- synth_ai/v0/tracing/upload.py +0 -512
- synth_ai/v0/tracing/utils.py +0 -9
- synth_ai/v0/tracing_v1/__init__.py +0 -16
- synth_ai/v0/tracing_v1/abstractions.py +0 -224
- synth_ai/v0/tracing_v1/base_client.py +0 -91
- synth_ai/v0/tracing_v1/client_manager.py +0 -131
- synth_ai/v0/tracing_v1/config.py +0 -142
- synth_ai/v0/tracing_v1/context.py +0 -146
- synth_ai/v0/tracing_v1/decorators.py +0 -703
- synth_ai/v0/tracing_v1/events/__init__.py +0 -0
- synth_ai/v0/tracing_v1/events/manage.py +0 -147
- synth_ai/v0/tracing_v1/events/scope.py +0 -86
- synth_ai/v0/tracing_v1/events/store.py +0 -228
- synth_ai/v0/tracing_v1/immediate_client.py +0 -151
- synth_ai/v0/tracing_v1/local.py +0 -18
- synth_ai/v0/tracing_v1/log_client_base.py +0 -73
- synth_ai/v0/tracing_v1/retry_queue.py +0 -186
- synth_ai/v0/tracing_v1/trackers.py +0 -515
- synth_ai/v0/tracing_v1/upload.py +0 -527
- synth_ai/v0/tracing_v1/utils.py +0 -9
- synth_ai/zyk/__init__.py +0 -30
- synth_ai-0.2.9.dev0.dist-info/METADATA +0 -131
- synth_ai-0.2.9.dev0.dist-info/RECORD +0 -444
- {synth_ai/lm/caching → examples/task_apps}/__init__.py +0 -0
- {synth_ai/lm/cost → examples/task_apps/crafter}/__init__.py +0 -0
- {synth_ai/lm/structured_outputs → examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/server}/__init__.py +0 -0
- {synth_ai/lm/vendors → examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests}/__init__.py +0 -0
- {synth_ai/lm/vendors/core → examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils}/__init__.py +0 -0
- {synth_ai/lm/vendors/local → examples/task_apps/math}/__init__.py +0 -0
- {synth_ai/lm/vendors/supported → examples/workflows}/__init__.py +0 -0
- {synth_ai/v0/tracing → examples/workflows/math_rl}/__init__.py +0 -0
- /synth_ai/{compound/cais.py → cli/__main__.py} +0 -0
- /synth_ai/{learning/filtering.py → py.typed} +0 -0
- {synth_ai-0.2.9.dev0.dist-info → synth_ai-0.2.23.dev3.dist-info}/WHEEL +0 -0
- {synth_ai-0.2.9.dev0.dist-info → synth_ai-0.2.23.dev3.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Persistent caching for LM responses.
|
|
3
|
-
|
|
4
|
-
This module provides a SQLite-based cache that persists LM responses
|
|
5
|
-
across application restarts, useful for long-term caching of expensive API calls.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import json
|
|
9
|
-
import os
|
|
10
|
-
import sqlite3
|
|
11
|
-
from dataclasses import dataclass
|
|
12
|
-
|
|
13
|
-
from pydantic import BaseModel
|
|
14
|
-
|
|
15
|
-
from synth_ai.lm.vendors.base import BaseLMResponse
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@dataclass
|
|
19
|
-
class PersistentCache:
|
|
20
|
-
"""
|
|
21
|
-
Persistent cache implementation using SQLite.
|
|
22
|
-
|
|
23
|
-
This cache stores LM responses in a SQLite database that persists
|
|
24
|
-
across application restarts.
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
def __init__(self, db_path: str = ".cache/persistent_cache.db"):
|
|
28
|
-
os.makedirs(os.path.dirname(db_path), exist_ok=True)
|
|
29
|
-
self.conn = sqlite3.connect(db_path)
|
|
30
|
-
self.cursor = self.conn.cursor()
|
|
31
|
-
self.cursor.execute("""CREATE TABLE IF NOT EXISTS cache
|
|
32
|
-
(key TEXT PRIMARY KEY, response TEXT)""")
|
|
33
|
-
self.conn.commit()
|
|
34
|
-
|
|
35
|
-
def hit_cache(
|
|
36
|
-
self, key: str, response_model: type[BaseModel] | None = None
|
|
37
|
-
) -> BaseLMResponse | None:
|
|
38
|
-
"""
|
|
39
|
-
Check if a response exists in cache for the given key.
|
|
40
|
-
|
|
41
|
-
Args:
|
|
42
|
-
key: Cache key to look up
|
|
43
|
-
response_model: Optional Pydantic model class to reconstruct structured output
|
|
44
|
-
|
|
45
|
-
Returns:
|
|
46
|
-
BaseLMResponse if found in cache, None otherwise
|
|
47
|
-
"""
|
|
48
|
-
self.cursor.execute("SELECT response FROM cache WHERE key = ?", (key,))
|
|
49
|
-
result = self.cursor.fetchone()
|
|
50
|
-
if not result:
|
|
51
|
-
return None
|
|
52
|
-
|
|
53
|
-
try:
|
|
54
|
-
cache_data = json.loads(result[0])
|
|
55
|
-
except json.JSONDecodeError:
|
|
56
|
-
# Handle legacy string responses
|
|
57
|
-
return BaseLMResponse(raw_response=result[0], structured_output=None, tool_calls=None)
|
|
58
|
-
|
|
59
|
-
if not isinstance(cache_data, dict):
|
|
60
|
-
return BaseLMResponse(raw_response=cache_data, structured_output=None, tool_calls=None)
|
|
61
|
-
|
|
62
|
-
raw_response = cache_data.get("raw_response")
|
|
63
|
-
tool_calls = cache_data.get("tool_calls")
|
|
64
|
-
structured_output = cache_data.get("structured_output")
|
|
65
|
-
|
|
66
|
-
if response_model and structured_output:
|
|
67
|
-
structured_output = response_model(**structured_output)
|
|
68
|
-
|
|
69
|
-
return BaseLMResponse(
|
|
70
|
-
raw_response=raw_response,
|
|
71
|
-
structured_output=structured_output,
|
|
72
|
-
tool_calls=tool_calls,
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
def add_to_cache(self, key: str, response: BaseLMResponse | str) -> None:
|
|
76
|
-
"""
|
|
77
|
-
Add a response to the cache.
|
|
78
|
-
|
|
79
|
-
Args:
|
|
80
|
-
key: Cache key to store under
|
|
81
|
-
response: Either a BaseLMResponse object or raw string response
|
|
82
|
-
|
|
83
|
-
Raises:
|
|
84
|
-
ValueError: If response type is not supported
|
|
85
|
-
|
|
86
|
-
Note:
|
|
87
|
-
Uses INSERT OR REPLACE to update existing cache entries.
|
|
88
|
-
"""
|
|
89
|
-
if isinstance(response, str):
|
|
90
|
-
cache_data = response
|
|
91
|
-
elif isinstance(response, BaseLMResponse):
|
|
92
|
-
cache_data = {
|
|
93
|
-
"raw_response": response.raw_response
|
|
94
|
-
if response.raw_response is not None
|
|
95
|
-
else None,
|
|
96
|
-
"tool_calls": response.tool_calls if response.tool_calls is not None else None,
|
|
97
|
-
"structured_output": (
|
|
98
|
-
response.structured_output.model_dump()
|
|
99
|
-
if response.structured_output is not None
|
|
100
|
-
else None
|
|
101
|
-
),
|
|
102
|
-
}
|
|
103
|
-
else:
|
|
104
|
-
raise ValueError(f"Invalid response type: {type(response)}")
|
|
105
|
-
|
|
106
|
-
self.cursor.execute(
|
|
107
|
-
"INSERT OR REPLACE INTO cache (key, response) VALUES (?, ?)",
|
|
108
|
-
(key, json.dumps(cache_data)),
|
|
109
|
-
)
|
|
110
|
-
self.conn.commit()
|
|
111
|
-
|
|
112
|
-
def close(self) -> None:
|
|
113
|
-
"""Close the database connection and free resources."""
|
|
114
|
-
self.conn.close()
|
synth_ai/lm/config.py
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Configuration management for LM providers.
|
|
3
|
-
Loads sensitive configuration from environment variables.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import os
|
|
7
|
-
from dataclasses import dataclass
|
|
8
|
-
|
|
9
|
-
from dotenv import load_dotenv
|
|
10
|
-
|
|
11
|
-
# Load environment variables from .env file
|
|
12
|
-
load_dotenv()
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def should_use_cache() -> bool:
|
|
16
|
-
"""
|
|
17
|
-
Check if caching should be enabled based on environment variable.
|
|
18
|
-
|
|
19
|
-
Returns:
|
|
20
|
-
bool: True if caching is enabled (default), False if explicitly disabled.
|
|
21
|
-
|
|
22
|
-
Note:
|
|
23
|
-
Caching is controlled by the USE_ZYK_CACHE environment variable.
|
|
24
|
-
Set to "false", "0", or "no" to disable caching.
|
|
25
|
-
"""
|
|
26
|
-
cache_env = os.getenv("USE_ZYK_CACHE", "true").lower()
|
|
27
|
-
return cache_env not in ("false", "0", "no")
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
# List of models that are considered reasoning models
|
|
31
|
-
# These models typically have special handling for temperature and other parameters
|
|
32
|
-
reasoning_models = ["o1", "o3-mini", "o3", "o4-mini", "claude-3-7-sonnet-latest"]
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@dataclass
|
|
36
|
-
class SynthConfig:
|
|
37
|
-
"""Synth API configuration loaded from environment."""
|
|
38
|
-
|
|
39
|
-
base_url: str
|
|
40
|
-
api_key: str
|
|
41
|
-
timeout: float = 120.0
|
|
42
|
-
max_retries: int = 3
|
|
43
|
-
|
|
44
|
-
@classmethod
|
|
45
|
-
def from_env(cls) -> "SynthConfig":
|
|
46
|
-
"""Load configuration from environment variables."""
|
|
47
|
-
# Support both SYNTH_ and MODAL_ prefixes for compatibility
|
|
48
|
-
base_url = os.getenv("SYNTH_BASE_URL") or os.getenv("MODAL_BASE_URL")
|
|
49
|
-
api_key = os.getenv("SYNTH_API_KEY") or os.getenv("MODAL_API_KEY")
|
|
50
|
-
|
|
51
|
-
if not base_url:
|
|
52
|
-
raise ValueError(
|
|
53
|
-
"SYNTH_BASE_URL or MODAL_BASE_URL not found in environment. "
|
|
54
|
-
"Please set it in your .env file:\n"
|
|
55
|
-
"SYNTH_BASE_URL=<your-synth-url>"
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
if not api_key:
|
|
59
|
-
raise ValueError(
|
|
60
|
-
"SYNTH_API_KEY or MODAL_API_KEY not found in environment. "
|
|
61
|
-
"Please set it in your .env file:\n"
|
|
62
|
-
"SYNTH_API_KEY=<your-api-key>"
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
# Ensure base URL includes /v1 for OpenAI client compatibility
|
|
66
|
-
# OpenAI client doesn't automatically add /v1, so we need to include it
|
|
67
|
-
if not base_url.endswith("/v1"):
|
|
68
|
-
base_url = base_url.rstrip("/") + "/v1"
|
|
69
|
-
|
|
70
|
-
return cls(
|
|
71
|
-
base_url=base_url.rstrip("/"), # Remove trailing slash if present
|
|
72
|
-
api_key=api_key,
|
|
73
|
-
timeout=float(os.getenv("SYNTH_TIMEOUT", "120")),
|
|
74
|
-
max_retries=int(os.getenv("SYNTH_MAX_RETRIES", "3")),
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
def get_base_url_without_v1(self) -> str:
|
|
78
|
-
"""Get base URL without /v1 for direct API calls."""
|
|
79
|
-
if self.base_url.endswith("/v1"):
|
|
80
|
-
return self.base_url[:-3]
|
|
81
|
-
return self.base_url
|
|
82
|
-
|
|
83
|
-
def __repr__(self) -> str:
|
|
84
|
-
"""Safe representation without exposing sensitive data."""
|
|
85
|
-
return f"SynthConfig(base_url={self.base_url}, api_key=*****, timeout={self.timeout})"
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
@dataclass
|
|
89
|
-
class OpenAIConfig:
|
|
90
|
-
"""OpenAI API configuration loaded from environment."""
|
|
91
|
-
|
|
92
|
-
api_key: str
|
|
93
|
-
|
|
94
|
-
@classmethod
|
|
95
|
-
def from_env(cls) -> "OpenAIConfig":
|
|
96
|
-
"""Load configuration from environment variables."""
|
|
97
|
-
api_key = os.getenv("OPENAI_API_KEY")
|
|
98
|
-
|
|
99
|
-
if not api_key:
|
|
100
|
-
raise ValueError(
|
|
101
|
-
"OPENAI_API_KEY not found in environment. "
|
|
102
|
-
"Please set it in your .env file:\n"
|
|
103
|
-
"OPENAI_API_KEY=<your-openai-api-key>"
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
return cls(api_key=api_key)
|
|
107
|
-
|
|
108
|
-
def __repr__(self) -> str:
|
|
109
|
-
"""Safe representation without exposing sensitive data."""
|
|
110
|
-
return "OpenAIConfig(api_key=*****)"
|
synth_ai/lm/constants.py
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Constants for LM module.
|
|
3
|
-
|
|
4
|
-
This module defines constants used across the LM (Language Model) module,
|
|
5
|
-
including model names, reasoning models, thinking budgets, and temperature settings.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
# Reasoning model names by provider
|
|
9
|
-
OPENAI_REASONING_MODELS = ["o4", "o4-mini", "o3", "o3-mini", "o1-mini", "o1"]
|
|
10
|
-
CLAUDE_REASONING_MODELS = ["claude-3-7-sonnet-latest"]
|
|
11
|
-
GEMINI_REASONING_MODELS = ["gemini-2.5-flash", "gemini-2.5-pro"]
|
|
12
|
-
|
|
13
|
-
# Gemini models that support thinking
|
|
14
|
-
GEMINI_REASONING_MODELS = ["gemini-2.5-flash", "gemini-2.5-pro"]
|
|
15
|
-
GEMINI_THINKING_BUDGETS = {
|
|
16
|
-
"high": 10000, # High thinking budget for complex reasoning
|
|
17
|
-
"medium": 5000, # Medium thinking budget for standard reasoning
|
|
18
|
-
"low": 2500, # Low thinking budget for simple reasoning
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
# Anthropic Sonnet 3.7 budgets
|
|
22
|
-
SONNET_37_BUDGETS = {
|
|
23
|
-
"high": 8192, # High budget for complex tasks
|
|
24
|
-
"medium": 4096, # Medium budget for standard tasks
|
|
25
|
-
"low": 2048, # Low budget for simple tasks
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
# Combined list of all reasoning models
|
|
29
|
-
REASONING_MODELS = OPENAI_REASONING_MODELS + CLAUDE_REASONING_MODELS + GEMINI_REASONING_MODELS
|
|
30
|
-
|
|
31
|
-
# Special base temperatures for reasoning models (all set to 1.0)
|
|
32
|
-
SPECIAL_BASE_TEMPS = dict.fromkeys(REASONING_MODELS, 1)
|
synth_ai/lm/core/__init__.py
DELETED
synth_ai/lm/core/all.py
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
from synth_ai.lm.vendors.core.anthropic_api import AnthropicAPI
|
|
2
|
-
from synth_ai.lm.vendors.core.gemini_api import GeminiAPI
|
|
3
|
-
from synth_ai.lm.vendors.core.openai_api import (
|
|
4
|
-
OpenAIPrivate,
|
|
5
|
-
OpenAIStructuredOutputClient,
|
|
6
|
-
)
|
|
7
|
-
from synth_ai.lm.vendors.supported.custom_endpoint import CustomEndpointAPI
|
|
8
|
-
from synth_ai.lm.vendors.supported.deepseek import DeepSeekAPI
|
|
9
|
-
from synth_ai.lm.vendors.supported.grok import GrokAPI
|
|
10
|
-
from synth_ai.lm.vendors.supported.groq import GroqAPI
|
|
11
|
-
from synth_ai.lm.vendors.supported.openrouter import OpenRouterAPI
|
|
12
|
-
from synth_ai.lm.vendors.supported.together import TogetherAPI
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class OpenAIClient(OpenAIPrivate):
|
|
16
|
-
def __init__(self, synth_logging: bool = True):
|
|
17
|
-
super().__init__(
|
|
18
|
-
synth_logging=synth_logging,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class AnthropicClient(AnthropicAPI):
|
|
23
|
-
def __init__(self):
|
|
24
|
-
super().__init__()
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class GeminiClient(GeminiAPI):
|
|
28
|
-
def __init__(self):
|
|
29
|
-
super().__init__()
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class DeepSeekClient(DeepSeekAPI):
|
|
33
|
-
def __init__(self):
|
|
34
|
-
super().__init__()
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class TogetherClient(TogetherAPI):
|
|
38
|
-
def __init__(self):
|
|
39
|
-
super().__init__()
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
class GroqClient(GroqAPI):
|
|
43
|
-
def __init__(self):
|
|
44
|
-
super().__init__()
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class GrokClient(GrokAPI):
|
|
48
|
-
def __init__(self):
|
|
49
|
-
super().__init__()
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
class CustomEndpointClient(CustomEndpointAPI):
|
|
53
|
-
def __init__(self, endpoint_url: str):
|
|
54
|
-
super().__init__(endpoint_url=endpoint_url)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
class OpenRouterClient(OpenRouterAPI):
|
|
58
|
-
def __init__(self):
|
|
59
|
-
super().__init__()
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
__all__ = [
|
|
63
|
-
"OpenAIClient",
|
|
64
|
-
"AnthropicClient",
|
|
65
|
-
"GeminiClient",
|
|
66
|
-
"DeepSeekClient",
|
|
67
|
-
"TogetherClient",
|
|
68
|
-
"GroqClient",
|
|
69
|
-
"GrokClient",
|
|
70
|
-
"CustomEndpointClient",
|
|
71
|
-
"OpenRouterClient",
|
|
72
|
-
"OpenAIStructuredOutputClient",
|
|
73
|
-
]
|
synth_ai/lm/core/exceptions.py
DELETED
synth_ai/lm/core/main.py
DELETED
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from typing import Any, Literal
|
|
3
|
-
|
|
4
|
-
from pydantic import BaseModel, Field
|
|
5
|
-
|
|
6
|
-
from synth_ai.lm.config import reasoning_models
|
|
7
|
-
from synth_ai.lm.core.exceptions import StructuredOutputCoercionFailureException
|
|
8
|
-
from synth_ai.lm.core.vendor_clients import (
|
|
9
|
-
anthropic_naming_regexes,
|
|
10
|
-
get_client,
|
|
11
|
-
openai_naming_regexes,
|
|
12
|
-
)
|
|
13
|
-
from synth_ai.lm.structured_outputs.handler import StructuredOutputHandler
|
|
14
|
-
from synth_ai.lm.tools.base import BaseTool
|
|
15
|
-
from synth_ai.lm.vendors.base import VendorBase
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def build_messages(
|
|
19
|
-
sys_msg: str,
|
|
20
|
-
user_msg: str,
|
|
21
|
-
images_bytes: list[bytes] = [],
|
|
22
|
-
model_name: str | None = None,
|
|
23
|
-
) -> list[dict]:
|
|
24
|
-
"""
|
|
25
|
-
Build a messages list for API calls, handling image formatting based on the model provider.
|
|
26
|
-
|
|
27
|
-
Args:
|
|
28
|
-
sys_msg: System message content
|
|
29
|
-
user_msg: User message content
|
|
30
|
-
images_bytes: List of base64-encoded image bytes
|
|
31
|
-
model_name: Model name to determine proper image format (OpenAI vs Anthropic)
|
|
32
|
-
|
|
33
|
-
Returns:
|
|
34
|
-
List[Dict]: Formatted messages list ready for API calls
|
|
35
|
-
|
|
36
|
-
Note:
|
|
37
|
-
Different providers require different image formats:
|
|
38
|
-
- OpenAI: Uses "image_url" with data URL format
|
|
39
|
-
- Anthropic: Uses "image" with source object containing base64 data
|
|
40
|
-
"""
|
|
41
|
-
if len(images_bytes) > 0 and any(regex.match(model_name) for regex in openai_naming_regexes):
|
|
42
|
-
return [
|
|
43
|
-
{"role": "system", "content": sys_msg},
|
|
44
|
-
{
|
|
45
|
-
"role": "user",
|
|
46
|
-
"content": [{"type": "text", "text": user_msg}]
|
|
47
|
-
+ [
|
|
48
|
-
{
|
|
49
|
-
"type": "image_url",
|
|
50
|
-
"image_url": {"url": f"data:image/jpeg;base64,{image_bytes}"},
|
|
51
|
-
}
|
|
52
|
-
for image_bytes in images_bytes
|
|
53
|
-
],
|
|
54
|
-
},
|
|
55
|
-
]
|
|
56
|
-
elif len(images_bytes) > 0 and any(
|
|
57
|
-
regex.match(model_name) for regex in anthropic_naming_regexes
|
|
58
|
-
):
|
|
59
|
-
system_info = {"role": "system", "content": sys_msg}
|
|
60
|
-
user_info = {
|
|
61
|
-
"role": "user",
|
|
62
|
-
"content": [{"type": "text", "text": user_msg}]
|
|
63
|
-
+ [
|
|
64
|
-
{
|
|
65
|
-
"type": "image",
|
|
66
|
-
"source": {
|
|
67
|
-
"type": "base64",
|
|
68
|
-
"media_type": "image/png",
|
|
69
|
-
"data": image_bytes,
|
|
70
|
-
},
|
|
71
|
-
}
|
|
72
|
-
for image_bytes in images_bytes
|
|
73
|
-
],
|
|
74
|
-
}
|
|
75
|
-
return [system_info, user_info]
|
|
76
|
-
elif len(images_bytes) > 0:
|
|
77
|
-
raise ValueError("Images are not yet supported for this model")
|
|
78
|
-
else:
|
|
79
|
-
return [
|
|
80
|
-
{"role": "system", "content": sys_msg},
|
|
81
|
-
{"role": "user", "content": user_msg},
|
|
82
|
-
]
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
class LM:
|
|
86
|
-
"""
|
|
87
|
-
Language Model interface for interacting with various AI providers.
|
|
88
|
-
|
|
89
|
-
Args:
|
|
90
|
-
model_name: The name of the model to use.
|
|
91
|
-
formatting_model_name: The model to use for formatting structured outputs.
|
|
92
|
-
temperature: The temperature setting for the model (0.0 to 1.0).
|
|
93
|
-
max_retries: Number of retries for API calls ("None", "Few", or "Many").
|
|
94
|
-
structured_output_mode: Mode for structured outputs ("stringified_json" or "forced_json").
|
|
95
|
-
synth_logging: Whether to enable Synth logging.
|
|
96
|
-
provider: Optional provider override. If specified, forces the use of a specific vendor
|
|
97
|
-
implementation regardless of model name. Can also be set via SYNTH_AI_DEFAULT_PROVIDER
|
|
98
|
-
environment variable. Supported values: "openai", "anthropic", "groq", "gemini",
|
|
99
|
-
"deepseek", "grok", "mistral", "openrouter", "together", or a custom string.
|
|
100
|
-
"""
|
|
101
|
-
|
|
102
|
-
# if str
|
|
103
|
-
model_name: str
|
|
104
|
-
client: VendorBase
|
|
105
|
-
lm_config: dict[str, Any]
|
|
106
|
-
structured_output_handler: StructuredOutputHandler
|
|
107
|
-
|
|
108
|
-
def __init__(
|
|
109
|
-
self,
|
|
110
|
-
model_name: str,
|
|
111
|
-
formatting_model_name: str,
|
|
112
|
-
temperature: float,
|
|
113
|
-
max_retries: Literal["None", "Few", "Many"] = "Few",
|
|
114
|
-
structured_output_mode: Literal["stringified_json", "forced_json"] = "stringified_json",
|
|
115
|
-
synth_logging: bool = True,
|
|
116
|
-
provider: Literal["openai", "anthropic", "groq", "gemini", "deepseek", "grok", "mistral", "openrouter", "together"] | str | None = None,
|
|
117
|
-
enable_thinking: bool | None = None,
|
|
118
|
-
):
|
|
119
|
-
# print("Structured output mode", structured_output_mode)
|
|
120
|
-
# Check for environment variable if provider is not specified
|
|
121
|
-
effective_provider = provider or os.environ.get("SYNTH_AI_DEFAULT_PROVIDER")
|
|
122
|
-
|
|
123
|
-
self.client = get_client(
|
|
124
|
-
model_name,
|
|
125
|
-
with_formatting=structured_output_mode == "forced_json",
|
|
126
|
-
synth_logging=synth_logging,
|
|
127
|
-
provider=effective_provider,
|
|
128
|
-
)
|
|
129
|
-
# print(self.client.__class__)
|
|
130
|
-
|
|
131
|
-
formatting_client = get_client(
|
|
132
|
-
formatting_model_name, with_formatting=True, synth_logging=synth_logging, provider=None
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
max_retries_dict = {"None": 0, "Few": 2, "Many": 5}
|
|
136
|
-
self.structured_output_handler = StructuredOutputHandler(
|
|
137
|
-
self.client,
|
|
138
|
-
formatting_client,
|
|
139
|
-
structured_output_mode,
|
|
140
|
-
{"max_retries": max_retries_dict.get(max_retries, 2)},
|
|
141
|
-
)
|
|
142
|
-
self.backup_structured_output_handler = StructuredOutputHandler(
|
|
143
|
-
self.client,
|
|
144
|
-
formatting_client,
|
|
145
|
-
"forced_json",
|
|
146
|
-
{"max_retries": max_retries_dict.get(max_retries, 2)},
|
|
147
|
-
)
|
|
148
|
-
# Override temperature to 1 for reasoning models
|
|
149
|
-
effective_temperature = 1.0 if model_name in reasoning_models else temperature
|
|
150
|
-
self.lm_config = {"temperature": effective_temperature}
|
|
151
|
-
if enable_thinking is not None:
|
|
152
|
-
# For providers that support it (e.g., Synth + Qwen3), this will be forwarded
|
|
153
|
-
self.lm_config["enable_thinking"] = enable_thinking
|
|
154
|
-
self.model_name = model_name
|
|
155
|
-
|
|
156
|
-
def respond_sync(
|
|
157
|
-
self,
|
|
158
|
-
system_message: str | None = None,
|
|
159
|
-
user_message: str | None = None,
|
|
160
|
-
messages: list[dict] | None = None,
|
|
161
|
-
images_as_bytes: list[bytes] = [],
|
|
162
|
-
response_model: BaseModel | None = None,
|
|
163
|
-
use_ephemeral_cache_only: bool = False,
|
|
164
|
-
tools: list[BaseTool] | None = None,
|
|
165
|
-
reasoning_effort: str = "low",
|
|
166
|
-
):
|
|
167
|
-
assert (system_message is None) == (user_message is None), (
|
|
168
|
-
"Must provide both system_message and user_message or neither"
|
|
169
|
-
)
|
|
170
|
-
assert (messages is None) != (system_message is None), (
|
|
171
|
-
"Must provide either messages or system_message/user_message pair, but not both"
|
|
172
|
-
)
|
|
173
|
-
assert not (response_model and tools), "Cannot provide both response_model and tools"
|
|
174
|
-
if messages is None:
|
|
175
|
-
messages = build_messages(
|
|
176
|
-
system_message, user_message, images_as_bytes, self.model_name
|
|
177
|
-
)
|
|
178
|
-
result = None
|
|
179
|
-
if response_model:
|
|
180
|
-
try:
|
|
181
|
-
result = self.structured_output_handler.call_sync(
|
|
182
|
-
messages,
|
|
183
|
-
model=self.model_name,
|
|
184
|
-
lm_config=self.lm_config,
|
|
185
|
-
response_model=response_model,
|
|
186
|
-
use_ephemeral_cache_only=use_ephemeral_cache_only,
|
|
187
|
-
reasoning_effort=reasoning_effort,
|
|
188
|
-
)
|
|
189
|
-
except StructuredOutputCoercionFailureException:
|
|
190
|
-
# print("Falling back to backup handler")
|
|
191
|
-
result = self.backup_structured_output_handler.call_sync(
|
|
192
|
-
messages,
|
|
193
|
-
model=self.model_name,
|
|
194
|
-
lm_config=self.lm_config,
|
|
195
|
-
response_model=response_model,
|
|
196
|
-
use_ephemeral_cache_only=use_ephemeral_cache_only,
|
|
197
|
-
reasoning_effort=reasoning_effort,
|
|
198
|
-
)
|
|
199
|
-
else:
|
|
200
|
-
result = self.client._hit_api_sync(
|
|
201
|
-
messages=messages,
|
|
202
|
-
model=self.model_name,
|
|
203
|
-
lm_config=self.lm_config,
|
|
204
|
-
use_ephemeral_cache_only=use_ephemeral_cache_only,
|
|
205
|
-
tools=tools,
|
|
206
|
-
reasoning_effort=reasoning_effort,
|
|
207
|
-
)
|
|
208
|
-
assert isinstance(result.raw_response, str), "Raw response must be a string"
|
|
209
|
-
assert (
|
|
210
|
-
isinstance(result.structured_output, BaseModel) or result.structured_output is None
|
|
211
|
-
), "Structured output must be a Pydantic model or None"
|
|
212
|
-
assert isinstance(result.tool_calls, list) or result.tool_calls is None, (
|
|
213
|
-
"Tool calls must be a list or None"
|
|
214
|
-
)
|
|
215
|
-
return result
|
|
216
|
-
|
|
217
|
-
async def respond_async(
|
|
218
|
-
self,
|
|
219
|
-
system_message: str | None = None,
|
|
220
|
-
user_message: str | None = None,
|
|
221
|
-
messages: list[dict] | None = None,
|
|
222
|
-
images_as_bytes: list[bytes] = [],
|
|
223
|
-
response_model: BaseModel | None = None,
|
|
224
|
-
use_ephemeral_cache_only: bool = False,
|
|
225
|
-
tools: list[BaseTool] | None = None,
|
|
226
|
-
reasoning_effort: str = "low",
|
|
227
|
-
):
|
|
228
|
-
# "In respond_async")
|
|
229
|
-
assert (system_message is None) == (user_message is None), (
|
|
230
|
-
"Must provide both system_message and user_message or neither"
|
|
231
|
-
)
|
|
232
|
-
assert (messages is None) != (system_message is None), (
|
|
233
|
-
"Must provide either messages or system_message/user_message pair, but not both"
|
|
234
|
-
)
|
|
235
|
-
|
|
236
|
-
assert not (response_model and tools), "Cannot provide both response_model and tools"
|
|
237
|
-
if messages is None:
|
|
238
|
-
messages = build_messages(
|
|
239
|
-
system_message, user_message, images_as_bytes, self.model_name
|
|
240
|
-
)
|
|
241
|
-
result = None
|
|
242
|
-
if response_model:
|
|
243
|
-
try:
|
|
244
|
-
print("Trying structured output handler")
|
|
245
|
-
result = await self.structured_output_handler.call_async(
|
|
246
|
-
messages,
|
|
247
|
-
model=self.model_name,
|
|
248
|
-
lm_config=self.lm_config,
|
|
249
|
-
response_model=response_model,
|
|
250
|
-
use_ephemeral_cache_only=use_ephemeral_cache_only,
|
|
251
|
-
reasoning_effort=reasoning_effort,
|
|
252
|
-
)
|
|
253
|
-
except StructuredOutputCoercionFailureException:
|
|
254
|
-
print("Falling back to backup handler")
|
|
255
|
-
result = await self.backup_structured_output_handler.call_async(
|
|
256
|
-
messages,
|
|
257
|
-
model=self.model_name,
|
|
258
|
-
lm_config=self.lm_config,
|
|
259
|
-
response_model=response_model,
|
|
260
|
-
use_ephemeral_cache_only=use_ephemeral_cache_only,
|
|
261
|
-
reasoning_effort=reasoning_effort,
|
|
262
|
-
)
|
|
263
|
-
else:
|
|
264
|
-
# print("Calling API no response model")
|
|
265
|
-
result = await self.client._hit_api_async(
|
|
266
|
-
messages=messages,
|
|
267
|
-
model=self.model_name,
|
|
268
|
-
lm_config=self.lm_config,
|
|
269
|
-
use_ephemeral_cache_only=use_ephemeral_cache_only,
|
|
270
|
-
tools=tools,
|
|
271
|
-
reasoning_effort=reasoning_effort,
|
|
272
|
-
)
|
|
273
|
-
assert isinstance(result.raw_response, str), "Raw response must be a string"
|
|
274
|
-
assert (
|
|
275
|
-
isinstance(result.structured_output, BaseModel) or result.structured_output is None
|
|
276
|
-
), "Structured output must be a Pydantic model or None"
|
|
277
|
-
assert isinstance(result.tool_calls, list) or result.tool_calls is None, (
|
|
278
|
-
"Tool calls must be a list or None"
|
|
279
|
-
)
|
|
280
|
-
return result
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
if __name__ == "__main__":
|
|
284
|
-
import asyncio
|
|
285
|
-
|
|
286
|
-
# Update json instructions to handle nested pydantic?
|
|
287
|
-
class Thought(BaseModel):
|
|
288
|
-
argument_keys: list[str] = Field(description="The keys of the arguments")
|
|
289
|
-
argument_values: list[str] = Field(
|
|
290
|
-
description="Stringified JSON for the values of the arguments"
|
|
291
|
-
)
|
|
292
|
-
|
|
293
|
-
class TestModel(BaseModel):
|
|
294
|
-
emotion: str = Field(description="The emotion expressed")
|
|
295
|
-
concern: str = Field(description="The concern expressed")
|
|
296
|
-
action: str = Field(description="The action to be taken")
|
|
297
|
-
thought: Thought = Field(description="The thought process")
|
|
298
|
-
|
|
299
|
-
class Config:
|
|
300
|
-
schema_extra = {"required": ["thought", "emotion", "concern", "action"]}
|
|
301
|
-
|
|
302
|
-
lm = LM(
|
|
303
|
-
model_name="gpt-4o-mini",
|
|
304
|
-
formatting_model_name="gpt-4o-mini",
|
|
305
|
-
temperature=1,
|
|
306
|
-
max_retries="Few",
|
|
307
|
-
structured_output_mode="forced_json",
|
|
308
|
-
)
|
|
309
|
-
print(
|
|
310
|
-
asyncio.run(
|
|
311
|
-
lm.respond_async(
|
|
312
|
-
system_message="You are a helpful assistant ",
|
|
313
|
-
user_message="Hello, how are you?",
|
|
314
|
-
images_as_bytes=[],
|
|
315
|
-
response_model=TestModel,
|
|
316
|
-
use_ephemeral_cache_only=False,
|
|
317
|
-
)
|
|
318
|
-
)
|
|
319
|
-
)
|