synth-ai 0.2.9.dev5__py3-none-any.whl → 0.2.10__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.
Potentially problematic release.
This version of synth-ai might be problematic. Click here for more details.
- examples/__init__.py +16 -0
- examples/crafter_debug_render.py +23 -17
- examples/dev/qwen3_32b_qlora_4xh100.toml +40 -0
- examples/multi_step/crafter_rl_lora.md +29 -0
- examples/qwen_coder/README.md +102 -0
- examples/qwen_coder/_shared.py +113 -0
- examples/qwen_coder/configs/coder_lora_30b.toml +61 -0
- examples/qwen_coder/configs/coder_lora_4b.toml +57 -0
- examples/qwen_coder/configs/coder_lora_small.toml +58 -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/rl/configs/eval_base_qwen.toml +1 -1
- examples/rl/configs/rl_from_base_qwen17.toml +1 -1
- examples/rl/download_dataset.py +26 -10
- examples/rl/run_eval.py +53 -52
- examples/rl/run_rl_and_save.py +29 -12
- examples/rl/task_app/math_single_step.py +180 -41
- examples/rl/task_app/math_task_app.py +14 -6
- examples/sft/README.md +139 -0
- examples/sft/configs/crafter_fft_qwen0p6b.toml +44 -0
- examples/sft/configs/crafter_lora_qwen0p6b.toml +45 -0
- examples/sft/evaluate.py +117 -0
- examples/sft/export_dataset.py +117 -0
- examples/sft/generate_traces.py +162 -0
- examples/swe/__init__.py +12 -0
- examples/swe/task_app/README.md +105 -0
- examples/swe/task_app/__init__.py +2 -0
- examples/swe/task_app/grpo_swe_mini.py +571 -0
- examples/swe/task_app/grpo_swe_mini_task_app.py +136 -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 +1164 -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 +618 -0
- examples/swe/task_app/hosted/main.py +100 -0
- examples/swe/task_app/hosted/policy_routes.py +1079 -0
- examples/swe/task_app/hosted/registry.py +195 -0
- examples/swe/task_app/hosted/rollout.py +1869 -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 +137 -0
- examples/swe/task_app/hosted/utils.py +62 -0
- examples/vlm/PROPOSAL.md +53 -0
- examples/vlm/README.md +68 -0
- examples/vlm/configs/crafter_vlm_gpt4o.toml +44 -0
- examples/vlm/crafter_image_only_agent.py +207 -0
- examples/vlm/crafter_openai_vlm_agent.py +277 -0
- examples/vlm/filter_image_rows.py +63 -0
- examples/vlm/run_crafter_vlm_benchmark.py +316 -0
- examples/warming_up_to_rl/analyze_trace_db.py +12 -10
- examples/warming_up_to_rl/configs/rl_from_base_qwen4b.toml +11 -1
- examples/warming_up_to_rl/export_trace_sft.py +218 -36
- examples/warming_up_to_rl/groq_test.py +15 -8
- examples/warming_up_to_rl/manage_secrets.py +29 -25
- examples/warming_up_to_rl/readme.md +9 -2
- examples/warming_up_to_rl/run_eval.py +137 -61
- examples/warming_up_to_rl/run_fft_and_save.py +131 -60
- examples/warming_up_to_rl/run_local_rollout.py +88 -39
- examples/warming_up_to_rl/run_local_rollout_modal.py +114 -28
- examples/warming_up_to_rl/run_local_rollout_parallel.py +81 -20
- examples/warming_up_to_rl/run_local_rollout_traced.py +126 -23
- examples/warming_up_to_rl/run_rl_and_save.py +35 -12
- examples/warming_up_to_rl/run_rollout_remote.py +44 -19
- examples/warming_up_to_rl/task_app/README.md +6 -2
- examples/warming_up_to_rl/task_app/grpo_crafter.py +319 -57
- examples/warming_up_to_rl/task_app/grpo_crafter_task_app.py +11 -30
- examples/warming_up_to_rl/task_app/synth_envs_hosted/__init__.py +1 -1
- examples/warming_up_to_rl/task_app/synth_envs_hosted/branching.py +9 -11
- examples/warming_up_to_rl/task_app/synth_envs_hosted/environment_routes.py +137 -182
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/__init__.py +1 -1
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/__init__.py +1 -1
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/app.py +1 -1
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/environment.py +150 -57
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/policy.py +105 -69
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/react_agent.py +19 -7
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/shared.py +45 -42
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/tools.py +1 -1
- examples/warming_up_to_rl/task_app/synth_envs_hosted/hosted_app.py +47 -45
- examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/__init__.py +1 -1
- examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/openai_client.py +198 -92
- examples/warming_up_to_rl/task_app/synth_envs_hosted/main.py +0 -2
- examples/warming_up_to_rl/task_app/synth_envs_hosted/policy_routes.py +361 -263
- examples/warming_up_to_rl/task_app/synth_envs_hosted/registry.py +21 -23
- examples/warming_up_to_rl/task_app/synth_envs_hosted/rollout.py +394 -274
- examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/__init__.py +1 -1
- examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/volume.py +56 -62
- examples/warming_up_to_rl/task_app/synth_envs_hosted/test_agents.py +1 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/test_service.py +6 -15
- examples/warming_up_to_rl/task_app/synth_envs_hosted/utils.py +4 -3
- synth_ai/__init__.py +1 -0
- synth_ai/api/models/supported.py +376 -0
- synth_ai/api/train/builders.py +157 -26
- synth_ai/api/train/cli.py +213 -57
- synth_ai/api/train/config_finder.py +65 -5
- synth_ai/api/train/env_resolver.py +33 -15
- synth_ai/api/train/pollers.py +13 -4
- synth_ai/api/train/supported_algos.py +139 -0
- synth_ai/api/train/task_app.py +5 -3
- synth_ai/api/train/utils.py +33 -48
- synth_ai/cli/__init__.py +19 -4
- synth_ai/cli/_modal_wrapper.py +28 -0
- synth_ai/cli/_typer_patch.py +49 -0
- synth_ai/cli/balance.py +2 -3
- synth_ai/cli/calc.py +1 -1
- synth_ai/cli/demo.py +21 -6
- synth_ai/cli/recent.py +2 -2
- synth_ai/cli/rl_demo.py +77 -17
- synth_ai/cli/root.py +116 -39
- synth_ai/cli/status.py +2 -2
- synth_ai/cli/task_apps.py +1699 -259
- synth_ai/cli/traces.py +7 -4
- synth_ai/cli/turso.py +73 -0
- synth_ai/cli/watch.py +12 -18
- synth_ai/core/experiment.py +0 -2
- synth_ai/demo_registry.py +68 -31
- synth_ai/demos/core/cli.py +516 -194
- 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/configs/crafter_fft_4b.toml +2 -3
- synth_ai/demos/demo_task_apps/crafter/grpo_crafter_task_app.py +37 -30
- 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 +183 -82
- synth_ai/demos/demo_task_apps/math/task_app_entry.py +0 -2
- synth_ai/environments/examples/bandit/engine.py +12 -4
- synth_ai/environments/examples/bandit/taskset.py +4 -4
- synth_ai/environments/examples/crafter_classic/environment.py +76 -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/base.py +0 -2
- synth_ai/handshake.py +11 -9
- synth_ai/http.py +1 -1
- synth_ai/http_client.py +43 -11
- synth_ai/inference/__init__.py +0 -2
- synth_ai/inference/client.py +20 -6
- synth_ai/jobs/client.py +103 -78
- synth_ai/learning/__init__.py +41 -6
- synth_ai/learning/algorithms.py +14 -0
- synth_ai/learning/client.py +121 -29
- 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 +13 -7
- synth_ai/learning/jobs.py +43 -47
- synth_ai/{rl → learning/rl}/__init__.py +14 -5
- synth_ai/learning/rl/client.py +267 -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 +295 -0
- synth_ai/learning/sse.py +25 -26
- synth_ai/learning/validators.py +25 -24
- synth_ai/lm/__init__.py +21 -47
- synth_ai/task/__init__.py +26 -27
- synth_ai/task/apps/__init__.py +18 -19
- synth_ai/task/auth.py +35 -23
- synth_ai/task/client.py +15 -13
- synth_ai/task/contracts.py +37 -35
- synth_ai/task/datasets.py +9 -6
- synth_ai/task/errors.py +11 -10
- synth_ai/task/health.py +17 -11
- synth_ai/task/json.py +58 -24
- synth_ai/task/proxy.py +15 -14
- synth_ai/task/rubrics.py +22 -15
- synth_ai/task/server.py +43 -17
- synth_ai/task/tracing_utils.py +12 -7
- synth_ai/task/validators.py +0 -1
- synth_ai/task/vendors.py +5 -7
- synth_ai/tracing_v3/__init__.py +2 -0
- synth_ai/tracing_v3/abstractions.py +21 -4
- synth_ai/tracing_v3/db_config.py +26 -1
- synth_ai/tracing_v3/decorators.py +18 -15
- synth_ai/tracing_v3/examples/basic_usage.py +3 -2
- synth_ai/tracing_v3/hooks.py +6 -4
- synth_ai/tracing_v3/llm_call_record_helpers.py +6 -6
- synth_ai/tracing_v3/replica_sync.py +1 -0
- synth_ai/tracing_v3/session_tracer.py +63 -16
- synth_ai/tracing_v3/storage/base.py +89 -1
- synth_ai/tracing_v3/storage/config.py +21 -8
- synth_ai/tracing_v3/storage/factory.py +10 -8
- synth_ai/tracing_v3/storage/utils.py +4 -2
- synth_ai/tracing_v3/turso/daemon.py +7 -2
- synth_ai/tracing_v3/turso/models.py +5 -2
- synth_ai/tracing_v3/turso/native_manager.py +1173 -0
- synth_ai/tracing_v3/utils.py +4 -3
- synth_ai/v0/api/__init__.py +8 -0
- synth_ai/v0/api/models/__init__.py +8 -0
- synth_ai/v0/api/models/supported.py +8 -0
- synth_ai/v0/config/__init__.py +15 -0
- synth_ai/v0/config/base_url.py +12 -0
- synth_ai/v0/lm/__init__.py +51 -0
- synth_ai/{lm → v0/lm}/caching/ephemeral.py +3 -5
- synth_ai/{lm → v0/lm}/caching/handler.py +4 -4
- synth_ai/{lm → v0/lm}/caching/initialize.py +1 -1
- synth_ai/{lm → v0/lm}/caching/persistent.py +1 -1
- synth_ai/{lm → v0/lm}/config.py +6 -1
- synth_ai/{lm → v0/lm}/core/all.py +9 -9
- synth_ai/{lm → v0/lm}/core/exceptions.py +0 -2
- synth_ai/{lm → v0/lm}/core/main.py +19 -7
- synth_ai/{lm → v0/lm}/core/main_v3.py +10 -10
- synth_ai/{lm → v0/lm}/core/synth_models.py +2 -15
- synth_ai/{lm → v0/lm}/core/vendor_clients.py +6 -4
- synth_ai/{lm → v0/lm}/overrides.py +4 -4
- synth_ai/{lm → v0/lm}/provider_support/anthropic.py +4 -4
- synth_ai/{lm → v0/lm}/provider_support/openai.py +5 -5
- synth_ai/{lm → v0/lm}/structured_outputs/handler.py +5 -5
- synth_ai/{lm → v0/lm}/structured_outputs/rehabilitate.py +1 -1
- synth_ai/{lm → v0/lm}/vendors/core/anthropic_api.py +16 -16
- synth_ai/{lm → v0/lm}/vendors/core/gemini_api.py +5 -5
- synth_ai/{lm → v0/lm}/vendors/core/mistral_api.py +5 -5
- synth_ai/{lm → v0/lm}/vendors/core/openai_api.py +12 -10
- synth_ai/{lm → v0/lm}/vendors/openai_standard.py +11 -9
- synth_ai/{lm → v0/lm}/vendors/openai_standard_responses.py +8 -5
- synth_ai/{lm → v0/lm}/vendors/supported/custom_endpoint.py +4 -6
- synth_ai/{lm → v0/lm}/vendors/supported/deepseek.py +2 -2
- synth_ai/{lm → v0/lm}/vendors/supported/grok.py +2 -2
- synth_ai/{lm → v0/lm}/vendors/supported/groq.py +1 -1
- synth_ai/{lm → v0/lm}/vendors/supported/ollama.py +1 -1
- synth_ai/{lm → v0/lm}/vendors/supported/openrouter.py +3 -3
- synth_ai/{lm → v0/lm}/vendors/supported/together.py +1 -1
- synth_ai/{lm → v0/lm}/vendors/synth_client.py +38 -11
- synth_ai/v0/tracing/upload.py +32 -135
- synth_ai/v0/tracing_v3/__init__.py +10 -0
- synth_ai/v0/tracing_v3/abstractions.py +3 -0
- synth_ai/v0/tracing_v3/decorators.py +3 -0
- synth_ai/v0/tracing_v3/llm_call_record_helpers.py +3 -0
- synth_ai/v0/tracing_v3/session_tracer.py +3 -0
- {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.10.dist-info}/METADATA +10 -7
- {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.10.dist-info}/RECORD +294 -258
- examples/common_old/backend.py +0 -21
- examples/evals_old/README.md +0 -98
- examples/evals_old/__init__.py +0 -6
- examples/evals_old/compare_models.py +0 -1037
- examples/evals_old/example_log.md +0 -145
- examples/evals_old/run_demo.sh +0 -126
- examples/evals_old/trace_analysis.py +0 -270
- examples/finetuning_old/_backup_synth_qwen/config.toml +0 -29
- examples/finetuning_old/_backup_synth_qwen/example_log.md +0 -324
- examples/finetuning_old/_backup_synth_qwen/filter_traces.py +0 -60
- examples/finetuning_old/_backup_synth_qwen/filter_traces_achievements.py +0 -239
- examples/finetuning_old/_backup_synth_qwen/purge_v3_traces.py +0 -109
- examples/finetuning_old/_backup_synth_qwen/react_agent_lm.py +0 -1924
- examples/finetuning_old/_backup_synth_qwen/readme.md +0 -49
- examples/finetuning_old/_backup_synth_qwen/run_crafter_qwen4b.py +0 -114
- examples/finetuning_old/_backup_synth_qwen/run_demo.sh +0 -195
- examples/finetuning_old/_backup_synth_qwen/sft_kickoff.py +0 -118
- examples/finetuning_old/synth_qwen_v1/README.md +0 -68
- examples/finetuning_old/synth_qwen_v1/filter_traces.py +0 -60
- examples/finetuning_old/synth_qwen_v1/filter_traces_achievements.py +0 -239
- examples/finetuning_old/synth_qwen_v1/finetune.py +0 -46
- examples/finetuning_old/synth_qwen_v1/hello_ft_model.py +0 -71
- examples/finetuning_old/synth_qwen_v1/infer.py +0 -37
- examples/finetuning_old/synth_qwen_v1/poll.py +0 -44
- examples/finetuning_old/synth_qwen_v1/prepare_data.py +0 -35
- examples/finetuning_old/synth_qwen_v1/purge_v3_traces.py +0 -109
- examples/finetuning_old/synth_qwen_v1/react_agent_lm.py +0 -1932
- examples/finetuning_old/synth_qwen_v1/run_crafter_sft_job.py +0 -207
- examples/finetuning_old/synth_qwen_v1/run_ft_job.py +0 -232
- examples/finetuning_old/synth_qwen_v1/upload_data.py +0 -34
- examples/finetuning_old/synth_qwen_v1/util.py +0 -147
- examples/rl_old/task_app.py +0 -962
- synth_ai/experimental/synth_oss.py +0 -446
- synth_ai/install_sqld.sh +0 -40
- synth_ai/learning/filtering.py +0 -0
- 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/rl/secrets.py +0 -19
- synth_ai/scripts/verify_rewards.py +0 -100
- synth_ai/tracing/__init__.py +0 -30
- synth_ai/tracing_v1/__init__.py +0 -33
- synth_ai/tracing_v3/turso/__init__.py +0 -25
- synth_ai/tracing_v3/turso/manager.py +0 -774
- synth_ai/zyk/__init__.py +0 -30
- /synth_ai/{lm → v0/lm}/caching/__init__.py +0 -0
- /synth_ai/{lm → v0/lm}/caching/constants.py +0 -0
- /synth_ai/{lm → v0/lm}/caching/dbs.py +0 -0
- /synth_ai/{lm → v0/lm}/constants.py +0 -0
- /synth_ai/{lm → v0/lm}/core/__init__.py +0 -0
- /synth_ai/{lm → v0/lm}/cost/__init__.py +0 -0
- /synth_ai/{lm → v0/lm}/cost/monitor.py +0 -0
- /synth_ai/{lm → v0/lm}/cost/statefulness.py +0 -0
- /synth_ai/{lm → v0/lm}/injection.py +0 -0
- /synth_ai/{lm → v0/lm}/provider_support/__init__.py +0 -0
- /synth_ai/{lm → v0/lm}/provider_support/suppress_logging.py +0 -0
- /synth_ai/{lm → v0/lm}/structured_outputs/__init__.py +0 -0
- /synth_ai/{lm → v0/lm}/structured_outputs/inject.py +0 -0
- /synth_ai/{lm → v0/lm}/tools/__init__.py +0 -0
- /synth_ai/{lm → v0/lm}/tools/base.py +0 -0
- /synth_ai/{lm → v0/lm}/unified_interface.py +0 -0
- /synth_ai/{lm → v0/lm}/vendors/__init__.py +0 -0
- /synth_ai/{lm → v0/lm}/vendors/base.py +0 -0
- /synth_ai/{lm → v0/lm}/vendors/core/__init__.py +0 -0
- /synth_ai/{lm → v0/lm}/vendors/core/synth_dev_api.py +0 -0
- /synth_ai/{lm → v0/lm}/vendors/local/__init__.py +0 -0
- /synth_ai/{lm → v0/lm}/vendors/local/ollama.py +0 -0
- /synth_ai/{lm → v0/lm}/vendors/retries.py +0 -0
- /synth_ai/{lm → v0/lm}/vendors/supported/__init__.py +0 -0
- /synth_ai/{lm → v0/lm}/warmup.py +0 -0
- {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.10.dist-info}/WHEEL +0 -0
- {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.10.dist-info}/entry_points.txt +0 -0
- {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.10.dist-info}/licenses/LICENSE +0 -0
- {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.10.dist-info}/top_level.txt +0 -0
|
@@ -9,20 +9,20 @@ import openai
|
|
|
9
9
|
import pydantic_core
|
|
10
10
|
from pydantic import BaseModel
|
|
11
11
|
|
|
12
|
-
from synth_ai.lm.caching.initialize import (
|
|
12
|
+
from synth_ai.v0.lm.caching.initialize import (
|
|
13
13
|
get_cache_handler,
|
|
14
14
|
)
|
|
15
|
-
from synth_ai.lm.constants import SPECIAL_BASE_TEMPS
|
|
16
|
-
from synth_ai.lm.injection import apply_injection
|
|
17
|
-
from synth_ai.lm.overrides import (
|
|
15
|
+
from synth_ai.v0.lm.constants import SPECIAL_BASE_TEMPS
|
|
16
|
+
from synth_ai.v0.lm.injection import apply_injection
|
|
17
|
+
from synth_ai.v0.lm.overrides import (
|
|
18
18
|
apply_param_overrides,
|
|
19
19
|
apply_tool_overrides,
|
|
20
20
|
use_overrides_for_messages,
|
|
21
21
|
)
|
|
22
|
-
from synth_ai.lm.tools.base import BaseTool
|
|
23
|
-
from synth_ai.lm.vendors.base import BaseLMResponse, VendorBase
|
|
24
|
-
from synth_ai.lm.vendors.openai_standard_responses import OpenAIResponsesAPIMixin
|
|
25
|
-
from synth_ai.lm.vendors.retries import MAX_BACKOFF
|
|
22
|
+
from synth_ai.v0.lm.tools.base import BaseTool
|
|
23
|
+
from synth_ai.v0.lm.vendors.base import BaseLMResponse, VendorBase
|
|
24
|
+
from synth_ai.v0.lm.vendors.openai_standard_responses import OpenAIResponsesAPIMixin
|
|
25
|
+
from synth_ai.v0.lm.vendors.retries import MAX_BACKOFF
|
|
26
26
|
|
|
27
27
|
DEFAULT_EXCEPTIONS_TO_RETRY = (
|
|
28
28
|
pydantic_core._pydantic_core.ValidationError,
|
|
@@ -427,7 +427,9 @@ class OpenAIStandard(VendorBase, OpenAIResponsesAPIMixin):
|
|
|
427
427
|
"type": getattr(tc, "type", "function"),
|
|
428
428
|
"function": {
|
|
429
429
|
"name": getattr(getattr(tc, "function", None), "name", None),
|
|
430
|
-
"arguments": getattr(
|
|
430
|
+
"arguments": getattr(
|
|
431
|
+
getattr(tc, "function", None), "arguments", None
|
|
432
|
+
),
|
|
431
433
|
},
|
|
432
434
|
}
|
|
433
435
|
)
|
|
@@ -8,8 +8,8 @@ that extend the OpenAIStandard class functionality.
|
|
|
8
8
|
import uuid
|
|
9
9
|
from typing import Any
|
|
10
10
|
|
|
11
|
-
from synth_ai.lm.tools.base import BaseTool
|
|
12
|
-
from synth_ai.lm.vendors.base import BaseLMResponse
|
|
11
|
+
from synth_ai.v0.lm.tools.base import BaseTool
|
|
12
|
+
from synth_ai.v0.lm.vendors.base import BaseLMResponse
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def _silent_backoff_handler(_details):
|
|
@@ -223,7 +223,9 @@ class OpenAIResponsesAPIMixin:
|
|
|
223
223
|
if not synth_gpu_endpoint:
|
|
224
224
|
raise ValueError("SYNTH_GPU_HARMONY_ENDPOINT environment variable not set")
|
|
225
225
|
|
|
226
|
-
async with
|
|
226
|
+
async with (
|
|
227
|
+
aiohttp.ClientSession() as session,
|
|
228
|
+
session.post(
|
|
227
229
|
f"{synth_gpu_endpoint}/v1/completions",
|
|
228
230
|
json={
|
|
229
231
|
"model": model,
|
|
@@ -231,8 +233,9 @@ class OpenAIResponsesAPIMixin:
|
|
|
231
233
|
"max_tokens": lm_config.get("max_tokens", 4096),
|
|
232
234
|
"temperature": lm_config.get("temperature", 0.8),
|
|
233
235
|
},
|
|
234
|
-
) as resp
|
|
235
|
-
|
|
236
|
+
) as resp,
|
|
237
|
+
):
|
|
238
|
+
result = await resp.json()
|
|
236
239
|
|
|
237
240
|
# Parse response using Harmony
|
|
238
241
|
response_tokens = result.get("choices", [{}])[0].get("text", "")
|
|
@@ -11,9 +11,9 @@ import requests
|
|
|
11
11
|
from requests.adapters import HTTPAdapter
|
|
12
12
|
from urllib3.util.retry import Retry
|
|
13
13
|
|
|
14
|
-
from synth_ai.lm.caching.initialize import get_cache_handler
|
|
15
|
-
from synth_ai.lm.tools.base import BaseTool
|
|
16
|
-
from synth_ai.lm.vendors.base import BaseLMResponse, VendorBase
|
|
14
|
+
from synth_ai.v0.lm.caching.initialize import get_cache_handler
|
|
15
|
+
from synth_ai.v0.lm.tools.base import BaseTool
|
|
16
|
+
from synth_ai.v0.lm.vendors.base import BaseLMResponse, VendorBase
|
|
17
17
|
|
|
18
18
|
# Exception types for retry
|
|
19
19
|
CUSTOM_ENDPOINT_EXCEPTIONS_TO_RETRY: tuple[type[Exception], ...] = (
|
|
@@ -194,9 +194,7 @@ IMPORTANT: To use a tool, respond with JSON wrapped in ```json fences:
|
|
|
194
194
|
|
|
195
195
|
For regular responses, just respond normally without JSON fences."""
|
|
196
196
|
|
|
197
|
-
def _extract_tool_calls(
|
|
198
|
-
self, content: str, tools: list[BaseTool]
|
|
199
|
-
) -> tuple[list | None, str]:
|
|
197
|
+
def _extract_tool_calls(self, content: str, tools: list[BaseTool]) -> tuple[list | None, str]:
|
|
200
198
|
"""Extract and validate tool calls from response."""
|
|
201
199
|
# Look for JSON fenced blocks
|
|
202
200
|
json_pattern = r"```json\s*(\{.*?\})\s*```"
|
|
@@ -3,8 +3,8 @@ from typing import Any
|
|
|
3
3
|
|
|
4
4
|
from openai import AsyncOpenAI, OpenAI
|
|
5
5
|
|
|
6
|
-
from synth_ai.lm.tools.base import BaseTool
|
|
7
|
-
from synth_ai.lm.vendors.openai_standard import OpenAIStandard
|
|
6
|
+
from synth_ai.v0.lm.tools.base import BaseTool
|
|
7
|
+
from synth_ai.v0.lm.vendors.openai_standard import OpenAIStandard
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class DeepSeekAPI(OpenAIStandard):
|
|
@@ -3,8 +3,8 @@ from typing import Any
|
|
|
3
3
|
|
|
4
4
|
from openai import AsyncOpenAI, OpenAI
|
|
5
5
|
|
|
6
|
-
from synth_ai.lm.tools.base import BaseTool
|
|
7
|
-
from synth_ai.lm.vendors.openai_standard import OpenAIStandard
|
|
6
|
+
from synth_ai.v0.lm.tools.base import BaseTool
|
|
7
|
+
from synth_ai.v0.lm.vendors.openai_standard import OpenAIStandard
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class GrokAPI(OpenAIStandard):
|
|
@@ -3,9 +3,9 @@ from typing import Any
|
|
|
3
3
|
|
|
4
4
|
from openai import AsyncOpenAI, OpenAI
|
|
5
5
|
|
|
6
|
-
from synth_ai.lm.tools.base import BaseTool
|
|
7
|
-
from synth_ai.lm.vendors.base import BaseLMResponse
|
|
8
|
-
from synth_ai.lm.vendors.openai_standard import OpenAIStandard
|
|
6
|
+
from synth_ai.v0.lm.tools.base import BaseTool
|
|
7
|
+
from synth_ai.v0.lm.vendors.base import BaseLMResponse
|
|
8
|
+
from synth_ai.v0.lm.vendors.openai_standard import OpenAIStandard
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class OpenRouterAPI(OpenAIStandard):
|
|
@@ -276,8 +276,20 @@ class AsyncSynthClient:
|
|
|
276
276
|
This method provides the OpenAI client interface structure.
|
|
277
277
|
"""
|
|
278
278
|
return await self._chat_completions_create(
|
|
279
|
-
model,
|
|
280
|
-
|
|
279
|
+
model,
|
|
280
|
+
messages,
|
|
281
|
+
temperature,
|
|
282
|
+
max_tokens,
|
|
283
|
+
top_p,
|
|
284
|
+
frequency_penalty,
|
|
285
|
+
presence_penalty,
|
|
286
|
+
stop,
|
|
287
|
+
stream,
|
|
288
|
+
tools,
|
|
289
|
+
tool_choice,
|
|
290
|
+
response_format,
|
|
291
|
+
seed,
|
|
292
|
+
**kwargs,
|
|
281
293
|
)
|
|
282
294
|
|
|
283
295
|
async def _chat_completions_create(
|
|
@@ -368,7 +380,8 @@ class AsyncSynthClient:
|
|
|
368
380
|
if isinstance(bt, int) and isinstance(mt, int) and bt > mt:
|
|
369
381
|
logger.warning(
|
|
370
382
|
"thinking_budget (%s) exceeds max_tokens (%s) – forwarding as-is",
|
|
371
|
-
str(bt),
|
|
383
|
+
str(bt),
|
|
384
|
+
str(mt),
|
|
372
385
|
)
|
|
373
386
|
except Exception:
|
|
374
387
|
pass
|
|
@@ -387,6 +400,7 @@ class AsyncSynthClient:
|
|
|
387
400
|
|
|
388
401
|
# If streaming requested, return an async stream adapter
|
|
389
402
|
if stream:
|
|
403
|
+
|
|
390
404
|
async def _astream():
|
|
391
405
|
await self._ensure_client()
|
|
392
406
|
async with self._client.stream("POST", url, json=payload) as r: # type: ignore
|
|
@@ -678,6 +692,7 @@ def create_sync_client(config: SynthConfig | None = None) -> SyncSynthClient:
|
|
|
678
692
|
# Drop-in replacements for OpenAI clients
|
|
679
693
|
# These allow Synth to be used as a complete replacement for OpenAI
|
|
680
694
|
|
|
695
|
+
|
|
681
696
|
class AsyncOpenAI(AsyncSynthClient):
|
|
682
697
|
"""
|
|
683
698
|
Drop-in replacement for openai.AsyncOpenAI.
|
|
@@ -685,7 +700,7 @@ class AsyncOpenAI(AsyncSynthClient):
|
|
|
685
700
|
Use Synth backend instead of OpenAI while maintaining the same API.
|
|
686
701
|
|
|
687
702
|
Example:
|
|
688
|
-
from synth_ai.lm.vendors.synth_client import AsyncOpenAI
|
|
703
|
+
from synth_ai.v0.lm.vendors.synth_client import AsyncOpenAI
|
|
689
704
|
|
|
690
705
|
client = AsyncOpenAI(
|
|
691
706
|
api_key="sk_live_...",
|
|
@@ -710,16 +725,22 @@ class AsyncOpenAI(AsyncSynthClient):
|
|
|
710
725
|
"""
|
|
711
726
|
# Handle OpenAI-style initialization
|
|
712
727
|
from ..config import SynthConfig
|
|
728
|
+
|
|
713
729
|
if api_key or base_url:
|
|
714
730
|
config = SynthConfig(
|
|
715
|
-
base_url=base_url
|
|
716
|
-
|
|
731
|
+
base_url=base_url
|
|
732
|
+
or os.getenv(
|
|
733
|
+
"OPENAI_API_BASE", "https://synth-backend-dev-docker.onrender.com/api"
|
|
734
|
+
),
|
|
735
|
+
api_key=api_key or os.getenv("OPENAI_API_KEY", ""),
|
|
717
736
|
)
|
|
718
737
|
else:
|
|
719
738
|
# Fallback to environment variables (OPENAI_* first, then SYNTH_*)
|
|
720
739
|
env_base = os.getenv("OPENAI_API_BASE") or os.getenv("SYNTH_BASE_URL")
|
|
721
740
|
env_key = os.getenv("OPENAI_API_KEY") or os.getenv("SYNTH_API_KEY")
|
|
722
|
-
config =
|
|
741
|
+
config = (
|
|
742
|
+
SynthConfig(base_url=env_base, api_key=env_key) if env_base and env_key else None
|
|
743
|
+
)
|
|
723
744
|
|
|
724
745
|
super().__init__(config, **kwargs)
|
|
725
746
|
|
|
@@ -742,15 +763,21 @@ class OpenAI(SyncSynthClient):
|
|
|
742
763
|
"""
|
|
743
764
|
# Handle OpenAI-style initialization
|
|
744
765
|
from ..config import SynthConfig
|
|
766
|
+
|
|
745
767
|
if api_key or base_url:
|
|
746
768
|
config = SynthConfig(
|
|
747
|
-
base_url=base_url
|
|
748
|
-
|
|
769
|
+
base_url=base_url
|
|
770
|
+
or os.getenv(
|
|
771
|
+
"OPENAI_API_BASE", "https://synth-backend-dev-docker.onrender.com/api"
|
|
772
|
+
),
|
|
773
|
+
api_key=api_key or os.getenv("OPENAI_API_KEY", ""),
|
|
749
774
|
)
|
|
750
775
|
else:
|
|
751
776
|
env_base = os.getenv("OPENAI_API_BASE") or os.getenv("SYNTH_BASE_URL")
|
|
752
777
|
env_key = os.getenv("OPENAI_API_KEY") or os.getenv("SYNTH_API_KEY")
|
|
753
|
-
config =
|
|
778
|
+
config = (
|
|
779
|
+
SynthConfig(base_url=env_base, api_key=env_key) if env_base and env_key else None
|
|
780
|
+
)
|
|
754
781
|
|
|
755
782
|
super().__init__(config, **kwargs)
|
|
756
783
|
|
|
@@ -760,7 +787,7 @@ __all__ = [
|
|
|
760
787
|
"AsyncSynthClient",
|
|
761
788
|
"SyncSynthClient",
|
|
762
789
|
"AsyncOpenAI", # Drop-in replacement for openai.AsyncOpenAI
|
|
763
|
-
"OpenAI",
|
|
790
|
+
"OpenAI", # Drop-in replacement for openai.OpenAI
|
|
764
791
|
"create_async_client",
|
|
765
792
|
"create_sync_client",
|
|
766
793
|
"create_chat_completion_async",
|
synth_ai/v0/tracing/upload.py
CHANGED
|
@@ -373,140 +373,37 @@ def upload_helper(
|
|
|
373
373
|
raise ValueError("SYNTH_API_KEY environment variable not set")
|
|
374
374
|
base_url = os.getenv("SYNTH_ENDPOINT_OVERRIDE", PROD_BASE_URL_DEFAULT)
|
|
375
375
|
|
|
376
|
-
"""Legacy block below retained for reference and disabled for linting/parsing.
|
|
377
|
-
Start disabled block.
|
|
378
|
-
"""
|
|
379
|
-
"""
|
|
380
|
-
from .decorators import _local, active_events_var
|
|
381
|
-
from .trackers import synth_tracker_async, synth_tracker_sync
|
|
382
|
-
|
|
383
|
-
# First close any tracker events
|
|
384
|
-
if hasattr(synth_tracker_async, "active_events"):
|
|
385
|
-
for event_type, event in list(synth_tracker_async.active_events.items()):
|
|
386
|
-
if event and event.closed is None:
|
|
387
|
-
event.closed = time.time()
|
|
388
|
-
try:
|
|
389
|
-
event_store.add_event(
|
|
390
|
-
event.system_name,
|
|
391
|
-
event.system_id,
|
|
392
|
-
event.system_instance_id,
|
|
393
|
-
event,
|
|
394
|
-
)
|
|
395
|
-
if verbose:
|
|
396
|
-
print(f"Closed and stored tracker async event: {event_type}")
|
|
397
|
-
except Exception as e:
|
|
398
|
-
logging.error(f"Failed to store tracker event {event_type}: {str(e)}")
|
|
399
|
-
synth_tracker_async.active_events.clear()
|
|
400
|
-
|
|
401
|
-
# End all active events before uploading
|
|
402
|
-
if hasattr(_local, "active_events"):
|
|
403
|
-
for event_type, event in _local.active_events.items():
|
|
404
|
-
if event and event.closed is None:
|
|
405
|
-
event.closed = time.time()
|
|
406
|
-
if hasattr(_local, "system_instance_id"):
|
|
407
|
-
try:
|
|
408
|
-
event_store.add_event(
|
|
409
|
-
_local.system_name,
|
|
410
|
-
_local.system_id,
|
|
411
|
-
_local.system_instance_id,
|
|
412
|
-
event,
|
|
413
|
-
)
|
|
414
|
-
if verbose:
|
|
415
|
-
print(f"Closed and stored active event: {event_type}")
|
|
416
|
-
except Exception as e:
|
|
417
|
-
logging.error(f"Failed to store event {event_type}: {str(e)}")
|
|
418
|
-
_local.active_events.clear()
|
|
419
|
-
|
|
420
|
-
# NEW: Close all open asynchronous events
|
|
421
|
-
active_events_async = active_events_var.get()
|
|
422
|
-
if active_events_async:
|
|
423
|
-
current_time = time.time()
|
|
424
|
-
for event_type, event in list(active_events_async.items()):
|
|
425
|
-
if event and event.closed is None:
|
|
426
|
-
event.closed = current_time
|
|
427
|
-
try:
|
|
428
|
-
event_store.add_event(
|
|
429
|
-
event.system_name,
|
|
430
|
-
event.system_id,
|
|
431
|
-
event.system_instance_id,
|
|
432
|
-
event,
|
|
433
|
-
)
|
|
434
|
-
if verbose:
|
|
435
|
-
print(f"Closed and stored async event: {event_type}")
|
|
436
|
-
except Exception as e:
|
|
437
|
-
logging.error(f"Failed to store async event {event_type}: {str(e)}")
|
|
438
|
-
active_events_var.set({})
|
|
439
|
-
|
|
440
|
-
# Also close any unclosed events in existing traces
|
|
441
376
|
logged_traces = event_store.get_system_traces()
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
traces_dict = [trace.to_dict() for trace in traces]
|
|
464
|
-
dataset_dict = dataset.to_dict()
|
|
465
|
-
|
|
466
|
-
# Validate upload format
|
|
467
|
-
if verbose:
|
|
468
|
-
print("Validating upload format...")
|
|
469
|
-
validate_upload(traces_dict, dataset_dict)
|
|
470
|
-
if verbose:
|
|
471
|
-
print("Upload format validation successful")
|
|
472
|
-
|
|
473
|
-
# Send to server
|
|
474
|
-
upload_id, signed_url = send_system_traces_s3(
|
|
475
|
-
dataset=dataset,
|
|
476
|
-
traces=traces,
|
|
477
|
-
base_url=base_url,
|
|
478
|
-
api_key=api_key,
|
|
479
|
-
system_id=traces[0].system_id,
|
|
480
|
-
system_name=traces[0].system_name,
|
|
481
|
-
verbose=verbose,
|
|
482
|
-
)
|
|
483
|
-
|
|
484
|
-
questions_json, reward_signals_json, traces_json = format_upload_output(dataset, traces)
|
|
485
|
-
return (
|
|
486
|
-
{
|
|
487
|
-
"status": "success",
|
|
488
|
-
"upload_id": upload_id,
|
|
489
|
-
"signed_url": signed_url,
|
|
490
|
-
},
|
|
491
|
-
questions_json,
|
|
492
|
-
reward_signals_json,
|
|
493
|
-
traces_json,
|
|
494
|
-
)
|
|
377
|
+
combined_traces: List[SystemTrace] = list(logged_traces) + list(traces)
|
|
378
|
+
|
|
379
|
+
if not combined_traces:
|
|
380
|
+
raise ValueError("No system traces found")
|
|
381
|
+
|
|
382
|
+
traces_dict = [trace.to_dict() for trace in combined_traces]
|
|
383
|
+
dataset_dict = dataset.to_dict()
|
|
384
|
+
|
|
385
|
+
if verbose:
|
|
386
|
+
print("Validating upload format...")
|
|
387
|
+
validate_upload(traces_dict, dataset_dict)
|
|
388
|
+
|
|
389
|
+
upload_id, signed_url = send_system_traces_s3(
|
|
390
|
+
dataset=dataset,
|
|
391
|
+
traces=combined_traces,
|
|
392
|
+
base_url=base_url,
|
|
393
|
+
api_key=api_key,
|
|
394
|
+
system_id=combined_traces[0].system_id,
|
|
395
|
+
system_name=combined_traces[0].system_name,
|
|
396
|
+
verbose=verbose,
|
|
397
|
+
)
|
|
495
398
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
print("\nTraces:")
|
|
508
|
-
print(json.dumps(traces_dict, indent=2))
|
|
509
|
-
print("\nDataset:")
|
|
510
|
-
print(json.dumps(dataset_dict, indent=2))
|
|
511
|
-
raise
|
|
512
|
-
"""
|
|
399
|
+
questions_json, reward_signals_json, traces_json = format_upload_output(dataset, combined_traces)
|
|
400
|
+
return (
|
|
401
|
+
{
|
|
402
|
+
"status": "success",
|
|
403
|
+
"upload_id": upload_id,
|
|
404
|
+
"signed_url": signed_url,
|
|
405
|
+
},
|
|
406
|
+
questions_json,
|
|
407
|
+
reward_signals_json,
|
|
408
|
+
traces_json,
|
|
409
|
+
)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
# Backward-compat shim for legacy imports: `synth_ai.v0.tracing_v3.*`
|
|
4
|
+
# Re-export from the canonical `synth_ai.tracing_v3` package.
|
|
5
|
+
|
|
6
|
+
from synth_ai.tracing_v3 import * # type: ignore[F401,F403]
|
|
7
|
+
|
|
8
|
+
__all__ = [] # names are provided by the upstream module
|
|
9
|
+
|
|
10
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: synth-ai
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.10
|
|
4
4
|
Summary: RL as a service SDK - Core AI functionality and tracing
|
|
5
5
|
Author-email: Synth AI <josh@usesynth.ai>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -45,19 +45,21 @@ Requires-Dist: pynacl>=1.5.0
|
|
|
45
45
|
Requires-Dist: google-api-core>=2.25.1
|
|
46
46
|
Requires-Dist: google-generativeai>=0.8.5
|
|
47
47
|
Requires-Dist: crafter>=1.8.3
|
|
48
|
-
Requires-Dist: click
|
|
48
|
+
Requires-Dist: click<8.2,>=8.1.7
|
|
49
49
|
Requires-Dist: textual>=1.1.0
|
|
50
50
|
Requires-Dist: openai-harmony>=0.0.1
|
|
51
51
|
Requires-Dist: asyncpg>=0.30.0
|
|
52
52
|
Requires-Dist: aiohttp>=3.8.0
|
|
53
53
|
Requires-Dist: datasets>=4.0.0
|
|
54
54
|
Requires-Dist: transformers>=4.56.1
|
|
55
|
-
Requires-Dist: modal
|
|
55
|
+
Requires-Dist: modal==1.1.4
|
|
56
56
|
Provides-Extra: dev
|
|
57
57
|
Requires-Dist: build>=1.2.2.post1; extra == "dev"
|
|
58
58
|
Requires-Dist: twine>=4.0.0; extra == "dev"
|
|
59
59
|
Requires-Dist: keyring>=24.0.0; extra == "dev"
|
|
60
60
|
Requires-Dist: pytest>=8.3.3; extra == "dev"
|
|
61
|
+
Requires-Dist: pytest-xdist>=3.6.1; extra == "dev"
|
|
62
|
+
Requires-Dist: pytest-timeout>=2.3.1; extra == "dev"
|
|
61
63
|
Requires-Dist: pytest-asyncio>=0.24.0; extra == "dev"
|
|
62
64
|
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
63
65
|
Requires-Dist: pyright>=1.1.350; extra == "dev"
|
|
@@ -78,10 +80,11 @@ Dynamic: license-file
|
|
|
78
80
|
[](https://www.python.org/)
|
|
79
81
|
[](LICENSE)
|
|
80
82
|
[](https://pypi.org/project/synth-ai/)
|
|
81
|
-

|
|
84
|
+

|
|
85
|
+

|
|
83
86
|
|
|
84
|
-
Docs: [Synth‑AI Documentation](https://docs.usesynth.ai/
|
|
87
|
+
Docs: [Synth‑AI Documentation](https://docs.usesynth.ai/welcome/introduction)
|
|
85
88
|
|
|
86
89
|
Fast and effective reinforcement learning for agents, via an API
|
|
87
90
|
|
|
@@ -105,7 +108,7 @@ uvx synth-ai deploy
|
|
|
105
108
|
uvx synth-ai run
|
|
106
109
|
```
|
|
107
110
|
|
|
108
|
-
To walk through kicking off your first RL run, see the [Synth‑AI Documentation](https://docs.usesynth.ai/
|
|
111
|
+
To walk through kicking off your first RL run, see the [Synth‑AI Documentation](https://docs.usesynth.ai/welcome/introduction).
|
|
109
112
|
|
|
110
113
|
### What `setup` does now
|
|
111
114
|
|