synth-ai 0.2.14__py3-none-any.whl → 0.4.4__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.
- synth_ai/__init__.py +25 -46
- synth_ai/__main__.py +30 -3
- synth_ai/cli/__init__.py +98 -72
- synth_ai/cli/__main__.py +42 -0
- synth_ai/cli/_internal/__init__.py +5 -0
- synth_ai/cli/_internal/modal_wrapper.py +31 -0
- synth_ai/cli/_internal/storage.py +20 -0
- synth_ai/cli/_internal/typer_patch.py +47 -0
- synth_ai/cli/_internal/validate_task_app.py +29 -0
- synth_ai/cli/agents/__init__.py +17 -0
- synth_ai/cli/agents/claude.py +77 -0
- synth_ai/cli/agents/codex.py +265 -0
- synth_ai/cli/agents/opencode.py +253 -0
- synth_ai/cli/commands/__init__.py +18 -0
- synth_ai/cli/commands/artifacts/__init__.py +13 -0
- synth_ai/cli/commands/artifacts/client.py +119 -0
- synth_ai/cli/commands/artifacts/config.py +57 -0
- synth_ai/cli/commands/artifacts/core.py +24 -0
- synth_ai/cli/commands/artifacts/download.py +188 -0
- synth_ai/cli/commands/artifacts/export.py +186 -0
- synth_ai/cli/commands/artifacts/list.py +156 -0
- synth_ai/cli/commands/artifacts/parsing.py +250 -0
- synth_ai/cli/commands/artifacts/show.py +336 -0
- synth_ai/cli/commands/demo/__init__.py +3 -0
- synth_ai/cli/commands/demo/core.py +153 -0
- synth_ai/cli/commands/eval/__init__.py +10 -0
- synth_ai/cli/commands/eval/config.py +338 -0
- synth_ai/cli/commands/eval/core.py +258 -0
- synth_ai/cli/commands/eval/runner.py +704 -0
- synth_ai/cli/commands/eval/validation.py +60 -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/scan/__init__.py +19 -0
- synth_ai/cli/commands/scan/cloudflare_scanner.py +403 -0
- synth_ai/cli/commands/scan/core.py +344 -0
- synth_ai/cli/commands/scan/health_checker.py +242 -0
- synth_ai/cli/commands/scan/local_scanner.py +278 -0
- synth_ai/cli/commands/scan/models.py +83 -0
- synth_ai/cli/commands/smoke/__init__.py +7 -0
- synth_ai/cli/commands/smoke/core.py +1428 -0
- synth_ai/cli/commands/status/__init__.py +3 -0
- synth_ai/cli/commands/status/client.py +91 -0
- synth_ai/cli/commands/status/config.py +12 -0
- synth_ai/cli/commands/status/errors.py +11 -0
- synth_ai/cli/commands/status/subcommands/__init__.py +3 -0
- synth_ai/cli/commands/status/subcommands/config.py +13 -0
- synth_ai/cli/commands/status/subcommands/files.py +34 -0
- synth_ai/cli/commands/status/subcommands/jobs.py +51 -0
- synth_ai/cli/commands/status/subcommands/models.py +35 -0
- synth_ai/cli/commands/status/subcommands/runs.py +34 -0
- synth_ai/cli/commands/status/subcommands/session.py +77 -0
- synth_ai/cli/commands/status/subcommands/summary.py +39 -0
- synth_ai/cli/commands/status/subcommands/utils.py +41 -0
- synth_ai/cli/commands/status/utils.py +23 -0
- synth_ai/cli/commands/train/__init__.py +51 -0
- synth_ai/cli/commands/train/core.py +22 -0
- synth_ai/cli/commands/train/errors.py +117 -0
- synth_ai/cli/commands/train/prompt_learning_validation.py +632 -0
- synth_ai/cli/commands/train/validation.py +392 -0
- synth_ai/cli/commands/train/verifier_schemas.py +200 -0
- synth_ai/cli/commands/train/verifier_validation.py +235 -0
- synth_ai/cli/demo_apps/__init__.py +10 -0
- synth_ai/cli/demo_apps/core/__init__.py +28 -0
- synth_ai/cli/demo_apps/core/cli.py +1735 -0
- synth_ai/cli/demo_apps/crafter/crafter_fft_4b.toml +55 -0
- synth_ai/cli/demo_apps/crafter/grpo_crafter_task_app.py +186 -0
- synth_ai/cli/demo_apps/crafter/rl_from_base_qwen4b.toml +74 -0
- synth_ai/cli/demo_apps/demo_registry.py +176 -0
- synth_ai/cli/demo_apps/demo_task_apps/core.py +440 -0
- synth_ai/cli/demo_apps/demo_task_apps/crafter/__init__.py +1 -0
- synth_ai/cli/demo_apps/demo_task_apps/crafter/grpo_crafter_task_app.py +185 -0
- synth_ai/cli/demo_apps/demo_task_apps/math/config.toml +73 -0
- synth_ai/cli/demo_apps/demo_task_apps/math/modal_task_app.py +738 -0
- synth_ai/cli/demo_apps/demo_task_apps/math/task_app_entry.py +39 -0
- synth_ai/cli/demo_apps/math/__init__.py +1 -0
- synth_ai/cli/demo_apps/math/_common.py +16 -0
- synth_ai/cli/demo_apps/math/app.py +38 -0
- synth_ai/cli/demo_apps/math/config.toml +75 -0
- synth_ai/cli/demo_apps/math/deploy_modal.py +54 -0
- synth_ai/cli/demo_apps/math/modal_task_app.py +698 -0
- synth_ai/cli/demo_apps/math/task_app_entry.py +53 -0
- synth_ai/cli/demo_apps/mipro/main.py +271 -0
- synth_ai/cli/demo_apps/mipro/task_app.py +911 -0
- synth_ai/cli/demo_apps/mipro/train_cfg.toml +92 -0
- synth_ai/cli/demos/__init__.py +12 -0
- synth_ai/cli/demos/demo.py +32 -0
- synth_ai/cli/demos/rl_demo.py +254 -0
- synth_ai/cli/deploy.py +216 -0
- synth_ai/cli/infra/__init__.py +14 -0
- synth_ai/cli/infra/balance.py +216 -0
- synth_ai/cli/infra/mcp.py +35 -0
- synth_ai/cli/infra/modal_app.py +36 -0
- synth_ai/cli/infra/setup.py +69 -0
- synth_ai/cli/infra/status.py +16 -0
- synth_ai/cli/infra/turso.py +77 -0
- synth_ai/cli/lib/__init__.py +10 -0
- synth_ai/cli/lib/agents.py +76 -0
- synth_ai/cli/lib/apps/modal_app.py +101 -0
- synth_ai/cli/lib/apps/task_app.py +642 -0
- synth_ai/cli/lib/bin.py +39 -0
- synth_ai/cli/lib/env.py +375 -0
- synth_ai/cli/lib/errors.py +85 -0
- synth_ai/cli/lib/modal.py +315 -0
- synth_ai/cli/lib/plotting.py +126 -0
- synth_ai/cli/lib/prompt_args.py +39 -0
- synth_ai/cli/lib/prompts.py +284 -0
- synth_ai/cli/lib/sqld.py +122 -0
- synth_ai/cli/lib/task_app_discovery.py +884 -0
- synth_ai/cli/lib/task_app_env.py +295 -0
- synth_ai/cli/lib/train_cfgs.py +300 -0
- synth_ai/cli/lib/tunnel_records.py +207 -0
- synth_ai/cli/local/__init__.py +14 -0
- synth_ai/cli/local/experiment_queue/__init__.py +72 -0
- synth_ai/cli/local/experiment_queue/api_schemas.py +221 -0
- synth_ai/cli/local/experiment_queue/celery_app.py +208 -0
- synth_ai/cli/local/experiment_queue/config.py +128 -0
- synth_ai/cli/local/experiment_queue/config_utils.py +272 -0
- synth_ai/cli/local/experiment_queue/database.py +175 -0
- synth_ai/cli/local/experiment_queue/dispatcher.py +119 -0
- synth_ai/cli/local/experiment_queue/models.py +231 -0
- synth_ai/cli/local/experiment_queue/progress_info.py +160 -0
- synth_ai/cli/local/experiment_queue/results.py +373 -0
- synth_ai/cli/local/experiment_queue/schemas.py +131 -0
- synth_ai/cli/local/experiment_queue/service.py +344 -0
- synth_ai/cli/local/experiment_queue/status.py +372 -0
- synth_ai/cli/local/experiment_queue/status_tracker.py +360 -0
- synth_ai/cli/local/experiment_queue/tasks.py +1984 -0
- synth_ai/cli/local/experiment_queue/trace_storage.py +65 -0
- synth_ai/cli/local/experiment_queue/validation.py +157 -0
- synth_ai/cli/local/session/__init__.py +92 -0
- synth_ai/cli/local/session/client.py +383 -0
- synth_ai/cli/local/session/constants.py +63 -0
- synth_ai/cli/local/session/exceptions.py +105 -0
- synth_ai/cli/local/session/manager.py +139 -0
- synth_ai/cli/local/session/models.py +89 -0
- synth_ai/cli/local/session/query.py +110 -0
- synth_ai/cli/root.py +30 -6
- synth_ai/cli/task_apps/__init__.py +37 -0
- synth_ai/cli/task_apps/commands.py +3145 -0
- synth_ai/cli/task_apps/deploy.py +7 -0
- synth_ai/cli/task_apps/list.py +26 -0
- synth_ai/cli/task_apps/main.py +36 -0
- synth_ai/cli/task_apps/modal_serve.py +11 -0
- synth_ai/cli/task_apps/serve.py +11 -0
- synth_ai/cli/training/__init__.py +8 -0
- synth_ai/cli/training/train.py +5 -0
- synth_ai/cli/training/train_cfg.py +34 -0
- synth_ai/cli/training/watch.py +506 -0
- synth_ai/cli/turso.py +34 -55
- synth_ai/cli/utils/__init__.py +8 -0
- synth_ai/cli/utils/experiments.py +235 -0
- synth_ai/cli/utils/queue.py +504 -0
- synth_ai/cli/utils/recent.py +133 -0
- synth_ai/cli/utils/traces.py +164 -0
- synth_ai/contracts/__init__.py +67 -0
- synth_ai/core/__init__.py +100 -0
- synth_ai/core/_utils/__init__.py +54 -0
- synth_ai/core/_utils/base_url.py +10 -0
- synth_ai/core/_utils/http.py +10 -0
- synth_ai/core/_utils/prompts.py +14 -0
- synth_ai/core/_utils/task_app_state.py +12 -0
- synth_ai/core/_utils/user_config.py +10 -0
- synth_ai/core/apps/common.py +116 -0
- synth_ai/core/auth.py +95 -0
- synth_ai/core/cfgs.py +240 -0
- synth_ai/core/config/__init__.py +16 -0
- synth_ai/core/config/base.py +168 -0
- synth_ai/core/config/resolver.py +89 -0
- synth_ai/core/env.py +231 -0
- synth_ai/core/errors.py +125 -0
- synth_ai/core/http.py +230 -0
- synth_ai/core/integrations/__init__.py +11 -0
- synth_ai/core/integrations/cloudflare.py +1886 -0
- synth_ai/core/integrations/mcp/__init__.py +6 -0
- synth_ai/core/integrations/mcp/__main__.py +8 -0
- synth_ai/core/integrations/mcp/claude.py +36 -0
- synth_ai/core/integrations/mcp/main.py +254 -0
- synth_ai/core/integrations/mcp/setup.py +100 -0
- synth_ai/core/integrations/modal.py +277 -0
- synth_ai/core/json.py +72 -0
- synth_ai/core/log_filter.py +99 -0
- synth_ai/core/logging.py +82 -0
- synth_ai/core/paths.py +107 -0
- synth_ai/core/pricing.py +109 -0
- synth_ai/core/process.py +233 -0
- synth_ai/core/ssl.py +25 -0
- synth_ai/core/storage/__init__.py +71 -0
- synth_ai/core/task_app_state.py +318 -0
- synth_ai/core/telemetry.py +282 -0
- synth_ai/core/tracing_v3/__init__.py +99 -0
- synth_ai/core/tracing_v3/abstractions.py +348 -0
- synth_ai/core/tracing_v3/config.py +229 -0
- synth_ai/core/tracing_v3/constants.py +21 -0
- synth_ai/core/tracing_v3/db_config.py +182 -0
- synth_ai/core/tracing_v3/decorators.py +401 -0
- synth_ai/core/tracing_v3/llm_call_record_helpers.py +437 -0
- synth_ai/core/tracing_v3/migration_helper.py +119 -0
- synth_ai/core/tracing_v3/session_tracer.py +542 -0
- synth_ai/core/tracing_v3/storage/base.py +211 -0
- synth_ai/core/tracing_v3/storage/config.py +109 -0
- synth_ai/core/tracing_v3/storage/factory.py +39 -0
- synth_ai/core/tracing_v3/trace_utils.py +326 -0
- synth_ai/core/tracing_v3/turso/daemon.py +278 -0
- synth_ai/core/tracing_v3/turso/models.py +470 -0
- synth_ai/core/tracing_v3/turso/native_manager.py +1385 -0
- synth_ai/core/tracing_v3/utils.py +108 -0
- synth_ai/core/urls.py +18 -0
- synth_ai/core/user_config.py +137 -0
- synth_ai/core/uvicorn.py +222 -0
- synth_ai/data/__init__.py +83 -0
- synth_ai/data/enums.py +122 -0
- synth_ai/data/rewards.py +249 -0
- synth_ai/data/traces.py +35 -0
- synth_ai/products/__init__.py +6 -0
- synth_ai/products/graph_evolve/__init__.py +45 -0
- synth_ai/products/graph_evolve/client.py +226 -0
- synth_ai/products/graph_evolve/config.py +591 -0
- synth_ai/products/graph_evolve/converters/__init__.py +42 -0
- synth_ai/products/graph_evolve/converters/openai_sft.py +484 -0
- synth_ai/products/graph_evolve/examples/hotpotqa/config.toml +109 -0
- synth_ai/products/graph_evolve/run.py +222 -0
- synth_ai/products/graph_gepa/__init__.py +23 -0
- synth_ai/products/graph_gepa/converters/__init__.py +19 -0
- synth_ai/products/graph_gepa/converters/openai_sft.py +29 -0
- synth_ai/sdk/__init__.py +129 -0
- synth_ai/sdk/api/__init__.py +1 -0
- synth_ai/sdk/api/eval/__init__.py +33 -0
- synth_ai/sdk/api/eval/job.py +732 -0
- synth_ai/sdk/api/models/supported.py +514 -0
- synth_ai/sdk/api/research_agent/__init__.py +296 -0
- synth_ai/sdk/api/train/__init__.py +85 -0
- synth_ai/sdk/api/train/builders.py +1076 -0
- synth_ai/sdk/api/train/cli.py +2196 -0
- synth_ai/sdk/api/train/config_finder.py +267 -0
- synth_ai/sdk/api/train/configs/__init__.py +67 -0
- synth_ai/sdk/api/train/configs/prompt_learning.py +1800 -0
- synth_ai/sdk/api/train/configs/rl.py +436 -0
- synth_ai/sdk/api/train/configs/sft.py +263 -0
- synth_ai/sdk/api/train/configs/shared.py +81 -0
- synth_ai/sdk/api/train/context_learning.py +312 -0
- synth_ai/sdk/api/train/env_resolver.py +418 -0
- synth_ai/sdk/api/train/graph_validators.py +216 -0
- synth_ai/sdk/api/train/graphgen.py +1102 -0
- synth_ai/sdk/api/train/graphgen_models.py +873 -0
- synth_ai/sdk/api/train/graphgen_validators.py +109 -0
- synth_ai/sdk/api/train/local_api.py +10 -0
- synth_ai/sdk/api/train/pollers.py +160 -0
- synth_ai/sdk/api/train/progress/__init__.py +97 -0
- synth_ai/sdk/api/train/progress/dataclasses.py +569 -0
- synth_ai/sdk/api/train/progress/events.py +326 -0
- synth_ai/sdk/api/train/progress/results.py +428 -0
- synth_ai/sdk/api/train/progress/tracker.py +641 -0
- synth_ai/sdk/api/train/prompt_learning.py +800 -0
- synth_ai/sdk/api/train/rl.py +478 -0
- synth_ai/sdk/api/train/sft.py +398 -0
- synth_ai/sdk/api/train/summary.py +522 -0
- synth_ai/sdk/api/train/supported_algos.py +147 -0
- synth_ai/sdk/api/train/task_app.py +351 -0
- synth_ai/sdk/api/train/utils.py +279 -0
- synth_ai/sdk/api/train/validators.py +2424 -0
- synth_ai/sdk/graphs/__init__.py +15 -0
- synth_ai/sdk/graphs/completions.py +776 -0
- synth_ai/sdk/graphs/verifier_schemas.py +222 -0
- synth_ai/sdk/inference/__init__.py +6 -0
- synth_ai/sdk/inference/client.py +128 -0
- synth_ai/sdk/jobs/__init__.py +16 -0
- synth_ai/sdk/jobs/client.py +371 -0
- synth_ai/sdk/learning/__init__.py +99 -0
- synth_ai/sdk/learning/client.py +240 -0
- synth_ai/sdk/learning/context_learning_client.py +531 -0
- synth_ai/sdk/learning/context_learning_types.py +294 -0
- synth_ai/sdk/learning/ft_client.py +7 -0
- synth_ai/sdk/learning/health.py +49 -0
- synth_ai/sdk/learning/jobs.py +202 -0
- synth_ai/sdk/learning/prompt_extraction.py +334 -0
- synth_ai/sdk/learning/prompt_learning_client.py +455 -0
- synth_ai/sdk/learning/prompt_learning_types.py +186 -0
- synth_ai/sdk/learning/rl/__init__.py +35 -0
- synth_ai/sdk/learning/rl/client.py +268 -0
- synth_ai/sdk/learning/rl/contracts.py +23 -0
- synth_ai/sdk/learning/rl/env_keys.py +166 -0
- synth_ai/sdk/learning/rl/secrets.py +13 -0
- synth_ai/sdk/learning/sft/client.py +95 -0
- synth_ai/sdk/learning/sft/config.py +270 -0
- synth_ai/sdk/learning/sft/data.py +698 -0
- synth_ai/sdk/learning/validators.py +52 -0
- synth_ai/sdk/localapi/__init__.py +40 -0
- synth_ai/sdk/localapi/apps/__init__.py +28 -0
- synth_ai/sdk/localapi/client.py +10 -0
- synth_ai/sdk/localapi/contracts.py +10 -0
- synth_ai/sdk/localapi/helpers.py +519 -0
- synth_ai/sdk/localapi/rollouts.py +93 -0
- synth_ai/sdk/localapi/server.py +29 -0
- synth_ai/sdk/localapi/template.py +49 -0
- synth_ai/sdk/streaming/__init__.py +35 -0
- synth_ai/sdk/streaming/config.py +94 -0
- synth_ai/sdk/streaming/handlers.py +1997 -0
- synth_ai/sdk/streaming/streamer.py +708 -0
- synth_ai/sdk/streaming/types.py +112 -0
- synth_ai/sdk/task/__init__.py +164 -0
- synth_ai/sdk/task/apps/__init__.py +169 -0
- synth_ai/sdk/task/client.py +175 -0
- synth_ai/sdk/task/config.py +256 -0
- synth_ai/sdk/task/contracts.py +340 -0
- synth_ai/sdk/task/datasets.py +108 -0
- synth_ai/sdk/task/in_process.py +1200 -0
- synth_ai/sdk/task/in_process_runner.py +314 -0
- synth_ai/sdk/task/inference_api.py +299 -0
- synth_ai/sdk/task/proxy.py +287 -0
- synth_ai/sdk/task/rubrics/__init__.py +54 -0
- synth_ai/sdk/task/rubrics/loaders.py +156 -0
- synth_ai/sdk/task/rubrics/strict.py +148 -0
- synth_ai/sdk/task/rubrics.py +219 -0
- synth_ai/sdk/task/server.py +640 -0
- synth_ai/sdk/task/trace_correlation_helpers.py +557 -0
- synth_ai/sdk/task/tracing_utils.py +95 -0
- synth_ai/sdk/task/validators.py +441 -0
- synth_ai/sdk/training/__init__.py +93 -0
- synth_ai/sdk/tunnels/__init__.py +118 -0
- synth_ai/sdk/tunnels/cleanup.py +83 -0
- synth_ai/sdk/tunnels/ports.py +120 -0
- synth_ai/sdk/tunnels/tunneled_api.py +363 -0
- synth_ai/utils/__init__.py +213 -0
- synth_ai-0.4.4.dist-info/METADATA +262 -0
- synth_ai-0.4.4.dist-info/RECORD +369 -0
- synth_ai-0.4.4.dist-info/top_level.txt +1 -0
- examples/__init__.py +0 -16
- examples/analyze_semantic_words.sh +0 -17
- examples/crafter_debug_render.py +0 -186
- examples/dev/qwen3_32b_qlora_4xh100.toml +0 -40
- examples/multi_step/configs/README_verilog_rl.md +0 -77
- examples/multi_step/configs/VERILOG_REWARDS.md +0 -90
- examples/multi_step/configs/VERILOG_RL_CHECKLIST.md +0 -183
- examples/multi_step/configs/crafter_eval_synth_qwen4b.toml +0 -35
- examples/multi_step/configs/crafter_eval_text_only_groq_qwen32b.toml +0 -36
- examples/multi_step/configs/crafter_rl_outcome.toml +0 -74
- examples/multi_step/configs/crafter_rl_stepwise_hosted_judge.toml +0 -187
- examples/multi_step/configs/crafter_rl_stepwise_shaped.toml +0 -83
- examples/multi_step/configs/crafter_rl_stepwise_simple.toml +0 -78
- examples/multi_step/configs/crafter_synth_backend.md +0 -40
- examples/multi_step/configs/verilog_eval_groq_qwen32b.toml +0 -31
- examples/multi_step/configs/verilog_eval_synth_qwen8b.toml +0 -33
- examples/multi_step/configs/verilog_rl_lora.toml +0 -190
- examples/multi_step/crafter_rl_lora.md +0 -70
- examples/multi_step/judges/crafter_backend_judge.py +0 -220
- examples/multi_step/judges/verilog_backend_judge.py +0 -234
- examples/multi_step/readme.md +0 -48
- examples/multi_step/sse_metrics_streaming_notes.md +0 -357
- examples/multi_step/task_app_config_notes.md +0 -494
- examples/multi_step/verilog_rl_lora.md +0 -218
- examples/qwen_coder/README.md +0 -102
- examples/qwen_coder/_shared.py +0 -113
- examples/qwen_coder/configs/coder_lora_30b.toml +0 -61
- examples/qwen_coder/configs/coder_lora_4b.toml +0 -57
- examples/qwen_coder/configs/coder_lora_small.toml +0 -58
- examples/qwen_coder/generate_dataset.py +0 -98
- examples/qwen_coder/infer_ft_smoke.py +0 -65
- examples/qwen_coder/infer_prod_proxy.py +0 -73
- examples/qwen_coder/infer_via_synth.py +0 -87
- examples/qwen_coder/scripts/infer_coder.sh +0 -19
- examples/qwen_coder/scripts/train_coder_30b.sh +0 -22
- examples/qwen_coder/sft_full_17b.py +0 -103
- examples/qwen_coder/sft_lora_30b.py +0 -110
- examples/qwen_coder/subset_jsonl.py +0 -39
- examples/qwen_coder/todos.md +0 -38
- examples/qwen_coder/validate_jsonl.py +0 -60
- examples/rl/README.md +0 -169
- examples/rl/download_dataset.py +0 -80
- examples/run_crafter_demo.sh +0 -10
- examples/sft/README.md +0 -139
- examples/sft/configs/crafter_fft_qwen0p6b.toml +0 -44
- examples/sft/configs/crafter_lora_qwen0p6b.toml +0 -45
- examples/sft/evaluate.py +0 -119
- examples/sft/export_dataset.py +0 -117
- examples/sft/generate_traces.py +0 -164
- examples/swe/__init__.py +0 -12
- examples/swe/task_app/README.md +0 -105
- examples/swe/task_app/__init__.py +0 -2
- examples/swe/task_app/grpo_swe_mini.py +0 -601
- examples/swe/task_app/grpo_swe_mini_task_app.py +0 -136
- examples/swe/task_app/hosted/README.md +0 -173
- examples/swe/task_app/hosted/__init__.py +0 -5
- examples/swe/task_app/hosted/branching.py +0 -143
- examples/swe/task_app/hosted/environment_routes.py +0 -1289
- examples/swe/task_app/hosted/envs/__init__.py +0 -1
- examples/swe/task_app/hosted/envs/crafter/__init__.py +0 -6
- examples/swe/task_app/hosted/envs/crafter/app.py +0 -1
- examples/swe/task_app/hosted/envs/crafter/environment.py +0 -522
- examples/swe/task_app/hosted/envs/crafter/policy.py +0 -478
- examples/swe/task_app/hosted/envs/crafter/react_agent.py +0 -108
- examples/swe/task_app/hosted/envs/crafter/shared.py +0 -305
- examples/swe/task_app/hosted/envs/crafter/tools.py +0 -47
- examples/swe/task_app/hosted/envs/mini_swe/__init__.py +0 -8
- examples/swe/task_app/hosted/envs/mini_swe/environment.py +0 -1164
- examples/swe/task_app/hosted/envs/mini_swe/policy.py +0 -355
- examples/swe/task_app/hosted/envs/mini_swe/shared.py +0 -83
- examples/swe/task_app/hosted/envs/mini_swe/tools.py +0 -96
- examples/swe/task_app/hosted/hosted_app.py +0 -204
- examples/swe/task_app/hosted/inference/__init__.py +0 -5
- examples/swe/task_app/hosted/inference/openai_client.py +0 -618
- examples/swe/task_app/hosted/main.py +0 -100
- examples/swe/task_app/hosted/policy_routes.py +0 -1079
- examples/swe/task_app/hosted/registry.py +0 -195
- examples/swe/task_app/hosted/rollout.py +0 -1911
- examples/swe/task_app/hosted/storage/__init__.py +0 -5
- examples/swe/task_app/hosted/storage/volume.py +0 -211
- examples/swe/task_app/hosted/test_agents.py +0 -161
- examples/swe/task_app/hosted/test_service.py +0 -136
- examples/swe/task_app/hosted/utils.py +0 -62
- examples/task_apps/IMAGE_ONLY_EVAL_QUICKSTART.md +0 -258
- examples/task_apps/TESTING.md +0 -275
- examples/task_apps/crafter/CREATE_SFT_DATASET.md +0 -273
- examples/task_apps/crafter/EVAL_IMAGE_ONLY_RESULTS.md +0 -152
- examples/task_apps/crafter/FILTER_COMMAND_STATUS.md +0 -174
- examples/task_apps/crafter/FILTER_COMMAND_SUCCESS.md +0 -268
- examples/task_apps/crafter/QUERY_EXAMPLES.md +0 -203
- examples/task_apps/crafter/README_IMAGE_ONLY_EVAL.md +0 -316
- examples/task_apps/crafter/__init__.py +0 -0
- examples/task_apps/crafter/eval_image_only_gpt4o.toml +0 -28
- examples/task_apps/crafter/eval_text_only_groq_llama.toml +0 -36
- examples/task_apps/crafter/filter_sft_dataset.toml +0 -16
- examples/task_apps/crafter/task_app/README.md +0 -42
- examples/task_apps/crafter/task_app/__init__.py +0 -5
- examples/task_apps/crafter/task_app/grpo_crafter.py +0 -973
- examples/task_apps/crafter/task_app/grpo_crafter_task_app.py +0 -146
- examples/task_apps/crafter/task_app/synth_envs_hosted/README.md +0 -173
- examples/task_apps/crafter/task_app/synth_envs_hosted/__init__.py +0 -5
- examples/task_apps/crafter/task_app/synth_envs_hosted/branching.py +0 -143
- examples/task_apps/crafter/task_app/synth_envs_hosted/environment_routes.py +0 -1226
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/__init__.py +0 -1
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/__init__.py +0 -6
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/app.py +0 -1
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/environment.py +0 -532
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/policy.py +0 -547
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/react_agent.py +0 -123
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/shared.py +0 -305
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/tools.py +0 -47
- examples/task_apps/crafter/task_app/synth_envs_hosted/hosted_app.py +0 -204
- examples/task_apps/crafter/task_app/synth_envs_hosted/inference/__init__.py +0 -5
- examples/task_apps/crafter/task_app/synth_envs_hosted/inference/openai_client.py +0 -704
- examples/task_apps/crafter/task_app/synth_envs_hosted/main.py +0 -100
- examples/task_apps/crafter/task_app/synth_envs_hosted/policy_routes.py +0 -1152
- examples/task_apps/crafter/task_app/synth_envs_hosted/registry.py +0 -195
- examples/task_apps/crafter/task_app/synth_envs_hosted/rollout.py +0 -2160
- examples/task_apps/crafter/task_app/synth_envs_hosted/storage/__init__.py +0 -5
- examples/task_apps/crafter/task_app/synth_envs_hosted/storage/volume.py +0 -211
- examples/task_apps/crafter/task_app/synth_envs_hosted/test_agents.py +0 -161
- examples/task_apps/crafter/task_app/synth_envs_hosted/test_service.py +0 -136
- examples/task_apps/crafter/task_app/synth_envs_hosted/utils.py +0 -218
- examples/task_apps/dev/pokemon_emerald/__init__.py +0 -2
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/README.md +0 -811
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/__init__.py +0 -120
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/action.py +0 -160
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/memory.py +0 -155
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/perception.py +0 -69
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/planning.py +0 -96
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/simple.py +0 -1502
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/agent/system_prompt.py +0 -4
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/grab_map.py +0 -68
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/manual.py +0 -216
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/__init__.py +0 -35
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/emerald_utils.py +0 -631
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/emulator.py +0 -1544
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/enums.py +0 -1428
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/memory_reader.py +0 -4848
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/types.py +0 -41
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pokemon_env/utils.py +0 -298
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/pyproject.toml +0 -95
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/run.py +0 -204
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/server/__init__.py +0 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/server/app.py +0 -2152
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/server/client.py +0 -429
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/server/frame_server.py +0 -155
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/README.md +0 -78
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/__init__.py +0 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/run_tests.py +0 -122
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_agent_direct.py +0 -76
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_agent_prompts.py +0 -413
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_battle_state_formatting.py +0 -204
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_dialogue_detection.py +0 -133
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_dialogue_detection_comprehensive.py +0 -229
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_direct_agent_emulator.py +0 -300
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_fps_adjustment_pytest.py +0 -205
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_house_to_outside_direct.py +0 -200
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_house_to_outside_transition.py +0 -284
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_map_ground_truth_comparison.py +0 -468
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_memory_map.py +0 -575
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_server_map_validation.py +0 -311
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/tests/test_torchic_state.py +0 -259
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/__init__.py +0 -0
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/anticheat.py +0 -372
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/checkpoint.py +0 -296
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/error_handler.py +0 -275
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/get_local_ip.py +0 -22
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/helpers.py +0 -44
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/llm_logger.py +0 -514
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/map_formatter.py +0 -415
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/map_stitcher.py +0 -1763
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/map_stitcher_singleton.py +0 -33
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/map_trimmer.py +0 -106
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/map_visualizer.py +0 -334
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/ocr_dialogue.py +0 -1020
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/recording.py +0 -188
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/state_formatter.py +0 -1481
- examples/task_apps/dev/pokemon_emerald/external/pokeagent-speedrun/utils/vlm.py +0 -862
- examples/task_apps/dev/pokemon_emerald/modal_app.py +0 -114
- examples/task_apps/dev/pokemon_emerald/task_app/README.md +0 -81
- examples/task_apps/dev/pokemon_emerald/task_app/__init__.py +0 -6
- examples/task_apps/dev/pokemon_emerald/task_app/pokemon_emerald.py +0 -685
- examples/task_apps/enron/__init__.py +0 -1
- examples/task_apps/enron/eval_groq_qwen32.toml +0 -16
- examples/task_apps/enron/filter_sft.toml +0 -5
- examples/task_apps/enron/task_app/README.md +0 -14
- examples/task_apps/enron/task_app/__init__.py +0 -1
- examples/task_apps/enron/task_app/grpo_enron.py +0 -906
- examples/task_apps/enron/task_app/grpo_enron_task_app.py +0 -146
- examples/task_apps/enron/tests/__init__.py +0 -4
- examples/task_apps/enron/tests/conftest.py +0 -115
- examples/task_apps/enron/tests/integration/__init__.py +0 -4
- examples/task_apps/enron/tests/integration/test_enron_eval.py +0 -179
- examples/task_apps/enron/tests/integration/test_enron_rollout.py +0 -135
- examples/task_apps/enron/tests/unit/__init__.py +0 -4
- examples/task_apps/enron/tests/unit/test_enron_environment.py +0 -126
- examples/task_apps/math/README.md +0 -22
- examples/task_apps/math/__init__.py +0 -0
- examples/task_apps/math/math_single_step.py +0 -1000
- examples/task_apps/math/math_task_app.py +0 -115
- examples/task_apps/pokemon_battle/__init__.py +0 -2
- examples/task_apps/pokemon_battle/modal_app.py +0 -104
- examples/task_apps/pokemon_battle/task_app/README.md +0 -68
- examples/task_apps/pokemon_battle/task_app/__init__.py +0 -6
- examples/task_apps/pokemon_battle/task_app/pokemon_showdown.py +0 -932
- examples/task_apps/pokemon_red/EVAL_IMAGE_ONLY_COMPLETE.md +0 -283
- examples/task_apps/pokemon_red/EVAL_IMAGE_ONLY_STATUS.md +0 -155
- examples/task_apps/pokemon_red/README.md +0 -357
- examples/task_apps/pokemon_red/README_IMAGE_ONLY_EVAL.md +0 -415
- examples/task_apps/pokemon_red/__init__.py +0 -3
- examples/task_apps/pokemon_red/eval_image_only_gpt4o.toml +0 -29
- examples/task_apps/pokemon_red/eval_pokemon_red_policy.py +0 -225
- examples/task_apps/pokemon_red/pallet_town_rl_config.toml +0 -75
- examples/task_apps/pokemon_red/task_app.py +0 -799
- examples/task_apps/pokemon_red/test_pallet_town_rewards.py +0 -193
- examples/task_apps/sokoban/README.md +0 -307
- examples/task_apps/sokoban/__init__.py +0 -3
- examples/task_apps/sokoban/eval_groq_qwen32.toml +0 -16
- examples/task_apps/sokoban/eval_openai_gpt5.toml +0 -16
- examples/task_apps/sokoban/filter_sft.toml +0 -5
- examples/task_apps/sokoban/task_app.py +0 -1058
- examples/task_apps/sokoban/tests/__init__.py +0 -4
- examples/task_apps/sokoban/tests/conftest.py +0 -113
- examples/task_apps/sokoban/tests/integration/__init__.py +0 -4
- examples/task_apps/sokoban/tests/integration/test_sokoban_eval.py +0 -57
- examples/task_apps/sokoban/tests/integration/test_sokoban_rollout.py +0 -198
- examples/task_apps/sokoban/tests/unit/__init__.py +0 -4
- examples/task_apps/sokoban/tests/unit/test_sokoban_environment.py +0 -114
- examples/task_apps/verilog/__init__.py +0 -1
- examples/task_apps/verilog/eval_groq_qwen32b.toml +0 -24
- examples/task_apps/verilog/filter_sft.toml +0 -5
- examples/task_apps/verilog/task_app/README.md +0 -12
- examples/task_apps/verilog/task_app/__init__.py +0 -1
- examples/task_apps/verilog/task_app/grpo_verilog.py +0 -1166
- examples/task_apps/verilog/task_app/grpo_verilog_task_app.py +0 -145
- examples/task_apps/verilog/tests/__init__.py +0 -4
- examples/task_apps/verilog/tests/conftest.py +0 -115
- examples/task_apps/verilog/tests/integration/__init__.py +0 -4
- examples/task_apps/verilog/tests/integration/test_verilog_eval.py +0 -181
- examples/task_apps/verilog/tests/integration/test_verilog_rollout.py +0 -55
- examples/task_apps/verilog/tests/unit/__init__.py +0 -4
- examples/task_apps/verilog/tests/unit/test_verilog_scoring.py +0 -118
- examples/vlm/PROPOSAL.md +0 -53
- examples/vlm/README.md +0 -68
- examples/vlm/configs/crafter_vlm_gpt4o.toml +0 -44
- examples/vlm/crafter_image_only_agent.py +0 -207
- examples/vlm/crafter_openai_vlm_agent.py +0 -277
- examples/vlm/filter_image_rows.py +0 -63
- examples/vlm/run_crafter_vlm_benchmark.py +0 -316
- examples/warming_up_to_rl/analyze_trace_db.py +0 -422
- examples/warming_up_to_rl/configs/crafter_fft.toml +0 -48
- examples/warming_up_to_rl/configs/crafter_fft_4b.toml +0 -54
- examples/warming_up_to_rl/configs/eval_fft_qwen4b.toml +0 -20
- examples/warming_up_to_rl/configs/eval_groq_qwen32b.toml +0 -13
- examples/warming_up_to_rl/configs/eval_modal_qwen4b.toml +0 -23
- examples/warming_up_to_rl/configs/eval_stepwise_complex.toml +0 -35
- examples/warming_up_to_rl/configs/eval_stepwise_consistent.toml +0 -26
- examples/warming_up_to_rl/configs/eval_stepwise_per_achievement.toml +0 -36
- examples/warming_up_to_rl/configs/eval_stepwise_simple.toml +0 -32
- examples/warming_up_to_rl/configs/rl_from_base_qwen4b.toml +0 -83
- examples/warming_up_to_rl/configs/rl_from_ft.toml +0 -56
- examples/warming_up_to_rl/export_trace_sft.py +0 -723
- examples/warming_up_to_rl/groq_test.py +0 -97
- examples/warming_up_to_rl/manage_secrets.py +0 -131
- examples/warming_up_to_rl/old/event_rewards.md +0 -234
- examples/warming_up_to_rl/old/notes.md +0 -73
- examples/warming_up_to_rl/readme.md +0 -179
- examples/warming_up_to_rl/run_eval.py +0 -736
- examples/warming_up_to_rl/run_fft_and_save.py +0 -380
- examples/warming_up_to_rl/run_local_rollout.py +0 -239
- examples/warming_up_to_rl/run_local_rollout_modal.py +0 -248
- examples/warming_up_to_rl/run_local_rollout_parallel.py +0 -405
- examples/warming_up_to_rl/run_local_rollout_traced.py +0 -477
- examples/warming_up_to_rl/run_rl_and_save.py +0 -124
- examples/warming_up_to_rl/run_rollout_remote.py +0 -156
- examples/workflows/__init__.py +0 -0
- examples/workflows/math_rl/__init__.py +0 -0
- examples/workflows/math_rl/configs/eval_base_qwen.toml +0 -15
- examples/workflows/math_rl/configs/eval_rl_qwen.toml +0 -11
- examples/workflows/math_rl/configs/rl_from_base_qwen.toml +0 -35
- examples/workflows/math_rl/configs/rl_from_base_qwen17.toml +0 -74
- examples/workflows/math_rl/configs/rl_from_ft_qwen.toml +0 -35
- examples/workflows/math_rl/download_dataset.py +0 -80
- examples/workflows/math_rl/run_eval.py +0 -436
- examples/workflows/math_rl/run_rl_and_save.py +0 -111
- synth_ai/api/models/supported.py +0 -377
- synth_ai/api/train/__init__.py +0 -5
- synth_ai/api/train/builders.py +0 -351
- synth_ai/api/train/cli.py +0 -635
- synth_ai/api/train/config_finder.py +0 -228
- synth_ai/api/train/configs/__init__.py +0 -44
- synth_ai/api/train/configs/rl.py +0 -134
- synth_ai/api/train/configs/sft.py +0 -95
- synth_ai/api/train/configs/shared.py +0 -24
- synth_ai/api/train/env_resolver.py +0 -349
- synth_ai/api/train/pollers.py +0 -75
- synth_ai/api/train/supported_algos.py +0 -147
- synth_ai/api/train/task_app.py +0 -195
- synth_ai/api/train/utils.py +0 -225
- synth_ai/cli/_modal_wrapper.py +0 -29
- synth_ai/cli/_storage.py +0 -20
- synth_ai/cli/_typer_patch.py +0 -49
- synth_ai/cli/_validate_task_app.py +0 -11
- synth_ai/cli/balance.py +0 -216
- synth_ai/cli/calc.py +0 -84
- synth_ai/cli/demo.py +0 -165
- synth_ai/cli/legacy_root_backup.py +0 -468
- synth_ai/cli/man.py +0 -106
- synth_ai/cli/recent.py +0 -132
- synth_ai/cli/rl_demo.py +0 -254
- synth_ai/cli/status.py +0 -134
- synth_ai/cli/task_apps.py +0 -4523
- synth_ai/cli/traces.py +0 -164
- synth_ai/cli/tui.py +0 -57
- synth_ai/cli/watch.py +0 -506
- synth_ai/compound/cais.py +0 -0
- synth_ai/config/base_url.py +0 -107
- synth_ai/core/experiment.py +0 -13
- synth_ai/core/system.py +0 -15
- synth_ai/demo_registry.py +0 -295
- synth_ai/demos/core/__init__.py +0 -1
- synth_ai/demos/core/cli.py +0 -1718
- synth_ai/demos/demo_task_apps/core.py +0 -440
- synth_ai/demos/demo_task_apps/crafter/grpo_crafter_task_app.py +0 -184
- synth_ai/demos/demo_task_apps/math/config.toml +0 -74
- synth_ai/demos/demo_task_apps/math/deploy_task_app.sh +0 -22
- synth_ai/demos/demo_task_apps/math/modal_task_app.py +0 -739
- synth_ai/demos/demo_task_apps/math/task_app_entry.py +0 -37
- synth_ai/environments/__init__.py +0 -31
- synth_ai/environments/environment/__init__.py +0 -1
- synth_ai/environments/environment/artifacts/__init__.py +0 -1
- synth_ai/environments/environment/artifacts/base.py +0 -52
- synth_ai/environments/environment/core.py +0 -67
- synth_ai/environments/environment/db/__init__.py +0 -1
- synth_ai/environments/environment/db/sqlite.py +0 -45
- synth_ai/environments/environment/registry.py +0 -233
- synth_ai/environments/environment/resources/sqlite.py +0 -45
- synth_ai/environments/environment/results.py +0 -1
- synth_ai/environments/environment/rewards/__init__.py +0 -1
- synth_ai/environments/environment/rewards/core.py +0 -29
- synth_ai/environments/environment/shared_engine.py +0 -26
- synth_ai/environments/environment/tools/__init__.py +0 -200
- synth_ai/environments/examples/__init__.py +0 -1
- synth_ai/environments/examples/bandit/__init__.py +0 -33
- synth_ai/environments/examples/bandit/engine.py +0 -302
- synth_ai/environments/examples/bandit/environment.py +0 -194
- synth_ai/environments/examples/bandit/taskset.py +0 -200
- synth_ai/environments/examples/crafter_classic/__init__.py +0 -8
- synth_ai/environments/examples/crafter_classic/agent_demos/analyze_semantic_words_markdown.py +0 -250
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_comprehensive_evaluation.py +0 -59
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_evaluation_browser.py +0 -152
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_evaluation_config.toml +0 -24
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_evaluation_framework.py +0 -1194
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/crafter_synth_config.toml +0 -56
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/filter_config_modal.toml +0 -32
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/filter_traces_sft_turso.py +0 -738
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/kick_off_ft_modal.py +0 -384
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_action_results.py +0 -53
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_agent_actions.py +0 -178
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_latest_run.py +0 -222
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_lm_traces.py +0 -183
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_no_rewards.py +0 -210
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_trace_issue.py +0 -206
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/check_db_schema.py +0 -49
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/check_latest_results.py +0 -64
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/debug_agent_responses.py +0 -88
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/quick_trace_check.py +0 -77
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/compare_experiments.py +0 -324
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/filter_traces_sft_turso.py +0 -580
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/kick_off_ft_oai.py +0 -362
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/multi_model_config.toml +0 -49
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/analyze_enhanced_hooks.py +0 -332
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/analyze_hook_events.py +0 -97
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/analyze_hook_results.py +0 -217
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/check_hook_storage.py +0 -87
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/check_seeds.py +0 -88
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/compare_seed_performance.py +0 -195
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/custom_eval_pipelines.py +0 -400
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/plot_hook_frequency.py +0 -195
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/seed_analysis_summary.py +0 -56
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/run_rollouts_for_models_and_compare_v3.py +0 -858
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_quick_evaluation.py +0 -52
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_react_agent.py +0 -874
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_trace_evaluation.py +0 -1412
- synth_ai/environments/examples/crafter_classic/agent_demos/example_v3_usage.py +0 -216
- synth_ai/environments/examples/crafter_classic/agent_demos/old/compare_traces.py +0 -296
- synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_comprehensive_evaluation.py +0 -58
- synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_env_serialization.py +0 -464
- synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_evaluation_browser.py +0 -152
- synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_quick_evaluation.py +0 -51
- synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_trace_evaluation.py +0 -1412
- synth_ai/environments/examples/crafter_classic/agent_demos/old/debug_player_loss.py +0 -112
- synth_ai/environments/examples/crafter_classic/agent_demos/old/diagnose_service.py +0 -203
- synth_ai/environments/examples/crafter_classic/agent_demos/old/diagnose_slowness.py +0 -305
- synth_ai/environments/examples/crafter_classic/agent_demos/old/eval_by_difficulty.py +0 -126
- synth_ai/environments/examples/crafter_classic/agent_demos/old/eval_example.py +0 -94
- synth_ai/environments/examples/crafter_classic/agent_demos/old/explore_saved_states.py +0 -142
- synth_ai/environments/examples/crafter_classic/agent_demos/old/filter_traces_sft.py +0 -26
- synth_ai/environments/examples/crafter_classic/agent_demos/old/filter_traces_sft_OLD.py +0 -984
- synth_ai/environments/examples/crafter_classic/agent_demos/old/generate_ft_data_gemini.py +0 -724
- synth_ai/environments/examples/crafter_classic/agent_demos/old/generate_ft_data_modal.py +0 -386
- synth_ai/environments/examples/crafter_classic/agent_demos/old/generate_ft_metadata.py +0 -205
- synth_ai/environments/examples/crafter_classic/agent_demos/old/kick_off_ft_gemini.py +0 -150
- synth_ai/environments/examples/crafter_classic/agent_demos/old/kick_off_ft_modal.py +0 -283
- synth_ai/environments/examples/crafter_classic/agent_demos/old/prepare_vertex_ft.py +0 -280
- synth_ai/environments/examples/crafter_classic/agent_demos/old/profile_env_slowness.py +0 -456
- synth_ai/environments/examples/crafter_classic/agent_demos/old/replicate_issue.py +0 -166
- synth_ai/environments/examples/crafter_classic/agent_demos/old/run_and_eval.py +0 -102
- synth_ai/environments/examples/crafter_classic/agent_demos/old/run_comparison.py +0 -128
- synth_ai/environments/examples/crafter_classic/agent_demos/old/run_qwen_rollouts.py +0 -655
- synth_ai/environments/examples/crafter_classic/agent_demos/old/trace_eval_OLD.py +0 -202
- synth_ai/environments/examples/crafter_classic/agent_demos/old/validate_openai_format.py +0 -166
- synth_ai/environments/examples/crafter_classic/config_logging.py +0 -111
- synth_ai/environments/examples/crafter_classic/debug_translation.py +0 -0
- synth_ai/environments/examples/crafter_classic/engine.py +0 -579
- synth_ai/environments/examples/crafter_classic/engine_deterministic_patch.py +0 -64
- synth_ai/environments/examples/crafter_classic/engine_helpers/action_map.py +0 -6
- synth_ai/environments/examples/crafter_classic/engine_helpers/serialization.py +0 -75
- synth_ai/environments/examples/crafter_classic/engine_serialization_patch_v3.py +0 -267
- synth_ai/environments/examples/crafter_classic/environment.py +0 -495
- synth_ai/environments/examples/crafter_classic/taskset.py +0 -233
- synth_ai/environments/examples/crafter_classic/trace_hooks_v3.py +0 -228
- synth_ai/environments/examples/crafter_classic/world_config_patch_simple.py +0 -299
- synth_ai/environments/examples/crafter_custom/__init__.py +0 -4
- synth_ai/environments/examples/crafter_custom/agent_demos/__init__.py +0 -1
- synth_ai/environments/examples/crafter_custom/agent_demos/trace_eval.py +0 -202
- synth_ai/environments/examples/crafter_custom/crafter/__init__.py +0 -7
- synth_ai/environments/examples/crafter_custom/crafter/config.py +0 -182
- synth_ai/environments/examples/crafter_custom/crafter/constants.py +0 -8
- synth_ai/environments/examples/crafter_custom/crafter/engine.py +0 -269
- synth_ai/environments/examples/crafter_custom/crafter/env.py +0 -262
- synth_ai/environments/examples/crafter_custom/crafter/objects.py +0 -417
- synth_ai/environments/examples/crafter_custom/crafter/recorder.py +0 -187
- synth_ai/environments/examples/crafter_custom/crafter/worldgen.py +0 -118
- synth_ai/environments/examples/crafter_custom/dataset_builder.py +0 -373
- synth_ai/environments/examples/crafter_custom/environment.py +0 -312
- synth_ai/environments/examples/crafter_custom/old/analyze_diamond_issue.py +0 -159
- synth_ai/environments/examples/crafter_custom/old/analyze_diamond_spawning.py +0 -158
- synth_ai/environments/examples/crafter_custom/old/compare_worlds.py +0 -71
- synth_ai/environments/examples/crafter_custom/old/dataset_stats.py +0 -105
- synth_ai/environments/examples/crafter_custom/old/diamond_spawning_summary.py +0 -119
- synth_ai/environments/examples/crafter_custom/old/example_dataset_usage.py +0 -52
- synth_ai/environments/examples/crafter_custom/run_dataset.py +0 -305
- synth_ai/environments/examples/enron/art_helpers/email_search_tools.py +0 -156
- synth_ai/environments/examples/enron/art_helpers/local_email_db.py +0 -281
- synth_ai/environments/examples/enron/art_helpers/types_enron.py +0 -25
- synth_ai/environments/examples/enron/engine.py +0 -300
- synth_ai/environments/examples/enron/environment.py +0 -234
- synth_ai/environments/examples/enron/taskset.py +0 -112
- synth_ai/environments/examples/enron/units/keyword_stats.py +0 -112
- synth_ai/environments/examples/minigrid/__init__.py +0 -48
- synth_ai/environments/examples/minigrid/agent_demos/minigrid_evaluation_framework.py +0 -1188
- synth_ai/environments/examples/minigrid/agent_demos/minigrid_quick_evaluation.py +0 -48
- synth_ai/environments/examples/minigrid/agent_demos/minigrid_react_agent.py +0 -562
- synth_ai/environments/examples/minigrid/agent_demos/minigrid_trace_evaluation.py +0 -221
- synth_ai/environments/examples/minigrid/engine.py +0 -589
- synth_ai/environments/examples/minigrid/environment.py +0 -274
- synth_ai/environments/examples/minigrid/environment_mapping.py +0 -242
- synth_ai/environments/examples/minigrid/puzzle_loader.py +0 -417
- synth_ai/environments/examples/minigrid/taskset.py +0 -583
- synth_ai/environments/examples/nethack/__init__.py +0 -7
- synth_ai/environments/examples/nethack/achievements.py +0 -337
- synth_ai/environments/examples/nethack/agent_demos/nethack_evaluation_framework.py +0 -981
- synth_ai/environments/examples/nethack/agent_demos/nethack_quick_evaluation.py +0 -74
- synth_ai/environments/examples/nethack/agent_demos/nethack_react_agent.py +0 -831
- synth_ai/environments/examples/nethack/engine.py +0 -739
- synth_ai/environments/examples/nethack/environment.py +0 -256
- synth_ai/environments/examples/nethack/helpers/__init__.py +0 -41
- synth_ai/environments/examples/nethack/helpers/action_mapping.py +0 -301
- synth_ai/environments/examples/nethack/helpers/nle_wrapper.py +0 -402
- synth_ai/environments/examples/nethack/helpers/observation_utils.py +0 -433
- synth_ai/environments/examples/nethack/helpers/recording_wrapper.py +0 -200
- synth_ai/environments/examples/nethack/helpers/trajectory_recorder.py +0 -269
- synth_ai/environments/examples/nethack/helpers/visualization/replay_viewer.py +0 -308
- synth_ai/environments/examples/nethack/helpers/visualization/visualizer.py +0 -431
- synth_ai/environments/examples/nethack/taskset.py +0 -323
- synth_ai/environments/examples/red/__init__.py +0 -7
- synth_ai/environments/examples/red/agent_demos/__init__.py +0 -1
- synth_ai/environments/examples/red/config_logging.py +0 -110
- synth_ai/environments/examples/red/engine.py +0 -721
- synth_ai/environments/examples/red/engine_helpers/__init__.py +0 -1
- synth_ai/environments/examples/red/engine_helpers/memory_map.py +0 -35
- synth_ai/environments/examples/red/engine_helpers/reward_components.py +0 -276
- synth_ai/environments/examples/red/engine_helpers/reward_library/__init__.py +0 -142
- synth_ai/environments/examples/red/engine_helpers/reward_library/adaptive_rewards.py +0 -57
- synth_ai/environments/examples/red/engine_helpers/reward_library/battle_rewards.py +0 -284
- synth_ai/environments/examples/red/engine_helpers/reward_library/composite_rewards.py +0 -150
- synth_ai/environments/examples/red/engine_helpers/reward_library/economy_rewards.py +0 -138
- synth_ai/environments/examples/red/engine_helpers/reward_library/efficiency_rewards.py +0 -57
- synth_ai/environments/examples/red/engine_helpers/reward_library/exploration_rewards.py +0 -331
- synth_ai/environments/examples/red/engine_helpers/reward_library/novelty_rewards.py +0 -121
- synth_ai/environments/examples/red/engine_helpers/reward_library/pallet_town_progression.py +0 -477
- synth_ai/environments/examples/red/engine_helpers/reward_library/pallet_town_rewards.py +0 -559
- synth_ai/environments/examples/red/engine_helpers/reward_library/pokemon_rewards.py +0 -313
- synth_ai/environments/examples/red/engine_helpers/reward_library/social_rewards.py +0 -148
- synth_ai/environments/examples/red/engine_helpers/reward_library/story_rewards.py +0 -247
- synth_ai/environments/examples/red/engine_helpers/screen_analysis.py +0 -368
- synth_ai/environments/examples/red/engine_helpers/state_extraction.py +0 -172
- synth_ai/environments/examples/red/environment.py +0 -298
- synth_ai/environments/examples/red/taskset.py +0 -79
- synth_ai/environments/examples/red/units/__init__.py +0 -1
- synth_ai/environments/examples/sokoban/__init__.py +0 -1
- synth_ai/environments/examples/sokoban/agent_demos/sokoban_full_eval.py +0 -899
- synth_ai/environments/examples/sokoban/engine.py +0 -678
- synth_ai/environments/examples/sokoban/engine_helpers/__init__.py +0 -1
- synth_ai/environments/examples/sokoban/engine_helpers/room_utils.py +0 -657
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/__init__.py +0 -18
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/__init__.py +0 -3
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/boxoban_env.py +0 -131
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/render_utils.py +0 -370
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/room_utils.py +0 -332
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env.py +0 -306
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_fixed_targets.py +0 -67
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_pull.py +0 -115
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_two_player.py +0 -123
- synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_variations.py +0 -394
- synth_ai/environments/examples/sokoban/environment.py +0 -229
- synth_ai/environments/examples/sokoban/generate_verified_puzzles.py +0 -440
- synth_ai/environments/examples/sokoban/puzzle_loader.py +0 -312
- synth_ai/environments/examples/sokoban/taskset.py +0 -544
- synth_ai/environments/examples/tictactoe/__init__.py +0 -1
- synth_ai/environments/examples/tictactoe/engine.py +0 -368
- synth_ai/environments/examples/tictactoe/environment.py +0 -240
- synth_ai/environments/examples/tictactoe/taskset.py +0 -215
- synth_ai/environments/examples/verilog/__init__.py +0 -10
- synth_ai/environments/examples/verilog/engine.py +0 -421
- synth_ai/environments/examples/verilog/environment.py +0 -350
- synth_ai/environments/examples/verilog/taskset.py +0 -420
- synth_ai/environments/examples/wordle/__init__.py +0 -29
- synth_ai/environments/examples/wordle/engine.py +0 -398
- synth_ai/environments/examples/wordle/environment.py +0 -159
- synth_ai/environments/examples/wordle/helpers/generate_instances_wordfreq.py +0 -75
- synth_ai/environments/examples/wordle/taskset.py +0 -230
- synth_ai/environments/reproducibility/core.py +0 -42
- synth_ai/environments/reproducibility/helpers.py +0 -0
- synth_ai/environments/reproducibility/tree.py +0 -363
- synth_ai/environments/service/app.py +0 -97
- synth_ai/environments/service/core_routes.py +0 -1021
- synth_ai/environments/service/external_registry.py +0 -56
- synth_ai/environments/service/registry.py +0 -9
- synth_ai/environments/stateful/__init__.py +0 -1
- synth_ai/environments/stateful/core.py +0 -163
- synth_ai/environments/stateful/engine.py +0 -21
- synth_ai/environments/stateful/state.py +0 -7
- synth_ai/environments/tasks/api.py +0 -19
- synth_ai/environments/tasks/core.py +0 -81
- synth_ai/environments/tasks/filters.py +0 -40
- synth_ai/environments/tasks/utils.py +0 -90
- synth_ai/environments/v0_observability/history.py +0 -3
- synth_ai/environments/v0_observability/log.py +0 -2
- synth_ai/evals/__init__.py +0 -15
- synth_ai/evals/base.py +0 -13
- synth_ai/evals/client.py +0 -82
- synth_ai/evals/types.py +0 -42
- synth_ai/handshake.py +0 -109
- synth_ai/http.py +0 -26
- synth_ai/http_client.py +0 -136
- synth_ai/inference/__init__.py +0 -5
- synth_ai/inference/client.py +0 -34
- synth_ai/jobs/client.py +0 -295
- synth_ai/judge_schemas.py +0 -127
- synth_ai/learning/__init__.py +0 -59
- synth_ai/learning/client.py +0 -241
- synth_ai/learning/ft_client.py +0 -7
- synth_ai/learning/health.py +0 -49
- synth_ai/learning/jobs.py +0 -201
- synth_ai/learning/rl/__init__.py +0 -39
- synth_ai/learning/rl/client.py +0 -267
- synth_ai/learning/rl/contracts.py +0 -27
- synth_ai/learning/rl/env_keys.py +0 -166
- synth_ai/learning/rl/secrets.py +0 -13
- synth_ai/learning/sft/client.py +0 -68
- synth_ai/learning/sft/config.py +0 -270
- synth_ai/learning/sft/data.py +0 -295
- synth_ai/learning/validators.py +0 -49
- synth_ai/lm/__init__.py +0 -25
- synth_ai/task/__init__.py +0 -121
- synth_ai/task/apps/__init__.py +0 -129
- synth_ai/task/client.py +0 -167
- synth_ai/task/config.py +0 -257
- synth_ai/task/contracts.py +0 -236
- synth_ai/task/datasets.py +0 -108
- synth_ai/task/proxy.py +0 -251
- synth_ai/task/rubrics/__init__.py +0 -56
- synth_ai/task/rubrics/loaders.py +0 -152
- synth_ai/task/rubrics/strict.py +0 -149
- synth_ai/task/server.py +0 -432
- synth_ai/task/trace_correlation_helpers.py +0 -315
- synth_ai/task/tracing_utils.py +0 -84
- synth_ai/task/validators.py +0 -418
- synth_ai/tracing_v3/__init__.py +0 -97
- synth_ai/tracing_v3/abstractions.py +0 -302
- synth_ai/tracing_v3/config.py +0 -84
- synth_ai/tracing_v3/db_config.py +0 -194
- synth_ai/tracing_v3/decorators.py +0 -398
- synth_ai/tracing_v3/llm_call_record_helpers.py +0 -391
- synth_ai/tracing_v3/migration_helper.py +0 -120
- synth_ai/tracing_v3/session_tracer.py +0 -540
- synth_ai/tracing_v3/storage/base.py +0 -210
- synth_ai/tracing_v3/storage/config.py +0 -75
- synth_ai/tracing_v3/storage/factory.py +0 -39
- synth_ai/tracing_v3/trace_utils.py +0 -317
- synth_ai/tracing_v3/turso/daemon.py +0 -151
- synth_ai/tracing_v3/turso/models.py +0 -469
- synth_ai/tracing_v3/turso/native_manager.py +0 -1209
- synth_ai/tracing_v3/utils.py +0 -108
- synth_ai/tui/__init__.py +0 -5
- synth_ai/tui/__main__.py +0 -13
- synth_ai/tui/cli/__init__.py +0 -1
- synth_ai/tui/cli/query_experiments.py +0 -164
- synth_ai/tui/cli/query_experiments_v3.py +0 -164
- synth_ai/tui/dashboard.py +0 -906
- synth_ai/v0/api/__init__.py +0 -8
- synth_ai/v0/api/models/__init__.py +0 -8
- synth_ai/v0/api/models/supported.py +0 -8
- synth_ai/v0/config/__init__.py +0 -15
- synth_ai/v0/config/base_url.py +0 -12
- synth_ai/v0/lm/__init__.py +0 -51
- synth_ai/v0/lm/caching/__init__.py +0 -0
- synth_ai/v0/lm/caching/constants.py +0 -6
- synth_ai/v0/lm/caching/dbs.py +0 -0
- synth_ai/v0/lm/caching/ephemeral.py +0 -100
- synth_ai/v0/lm/caching/handler.py +0 -137
- synth_ai/v0/lm/caching/initialize.py +0 -11
- synth_ai/v0/lm/caching/persistent.py +0 -114
- synth_ai/v0/lm/config.py +0 -115
- synth_ai/v0/lm/constants.py +0 -32
- synth_ai/v0/lm/core/__init__.py +0 -8
- synth_ai/v0/lm/core/all.py +0 -73
- synth_ai/v0/lm/core/exceptions.py +0 -5
- synth_ai/v0/lm/core/main.py +0 -331
- synth_ai/v0/lm/core/main_v3.py +0 -594
- synth_ai/v0/lm/core/synth_models.py +0 -35
- synth_ai/v0/lm/core/vendor_clients.py +0 -190
- synth_ai/v0/lm/cost/__init__.py +0 -0
- synth_ai/v0/lm/cost/monitor.py +0 -1
- synth_ai/v0/lm/cost/statefulness.py +0 -1
- synth_ai/v0/lm/injection.py +0 -80
- synth_ai/v0/lm/overrides.py +0 -206
- synth_ai/v0/lm/provider_support/__init__.py +0 -8
- synth_ai/v0/lm/provider_support/anthropic.py +0 -972
- synth_ai/v0/lm/provider_support/openai.py +0 -1139
- synth_ai/v0/lm/provider_support/suppress_logging.py +0 -31
- synth_ai/v0/lm/structured_outputs/__init__.py +0 -0
- synth_ai/v0/lm/structured_outputs/handler.py +0 -440
- synth_ai/v0/lm/structured_outputs/inject.py +0 -297
- synth_ai/v0/lm/structured_outputs/rehabilitate.py +0 -185
- synth_ai/v0/lm/tools/__init__.py +0 -3
- synth_ai/v0/lm/tools/base.py +0 -172
- synth_ai/v0/lm/unified_interface.py +0 -202
- synth_ai/v0/lm/vendors/__init__.py +0 -0
- synth_ai/v0/lm/vendors/base.py +0 -81
- synth_ai/v0/lm/vendors/core/__init__.py +0 -0
- synth_ai/v0/lm/vendors/core/anthropic_api.py +0 -387
- synth_ai/v0/lm/vendors/core/gemini_api.py +0 -292
- synth_ai/v0/lm/vendors/core/mistral_api.py +0 -322
- synth_ai/v0/lm/vendors/core/openai_api.py +0 -227
- synth_ai/v0/lm/vendors/core/synth_dev_api.py +0 -0
- synth_ai/v0/lm/vendors/local/__init__.py +0 -0
- synth_ai/v0/lm/vendors/local/ollama.py +0 -0
- synth_ai/v0/lm/vendors/openai_standard.py +0 -782
- synth_ai/v0/lm/vendors/openai_standard_responses.py +0 -259
- synth_ai/v0/lm/vendors/retries.py +0 -22
- synth_ai/v0/lm/vendors/supported/__init__.py +0 -0
- synth_ai/v0/lm/vendors/supported/custom_endpoint.py +0 -415
- synth_ai/v0/lm/vendors/supported/deepseek.py +0 -69
- synth_ai/v0/lm/vendors/supported/grok.py +0 -75
- synth_ai/v0/lm/vendors/supported/groq.py +0 -16
- synth_ai/v0/lm/vendors/supported/ollama.py +0 -15
- synth_ai/v0/lm/vendors/supported/openrouter.py +0 -74
- synth_ai/v0/lm/vendors/supported/together.py +0 -11
- synth_ai/v0/lm/vendors/synth_client.py +0 -835
- synth_ai/v0/lm/warmup.py +0 -186
- synth_ai/v0/tracing/__init__.py +0 -0
- 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 -409
- 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/v0/tracing_v3/__init__.py +0 -10
- synth_ai/v0/tracing_v3/abstractions.py +0 -3
- synth_ai/v0/tracing_v3/decorators.py +0 -3
- synth_ai/v0/tracing_v3/llm_call_record_helpers.py +0 -3
- synth_ai/v0/tracing_v3/session_tracer.py +0 -3
- synth_ai-0.2.14.dist-info/METADATA +0 -139
- synth_ai-0.2.14.dist-info/RECORD +0 -762
- synth_ai-0.2.14.dist-info/top_level.txt +0 -2
- /synth_ai/{demos/demo_task_apps → cli/demo_apps}/crafter/__init__.py +0 -0
- /synth_ai/{demos → cli/demo_apps}/demo_task_apps/__init__.py +0 -0
- /synth_ai/{demos → cli/demo_apps}/demo_task_apps/crafter/configs/crafter_fft_4b.toml +0 -0
- /synth_ai/{demos → cli/demo_apps}/demo_task_apps/crafter/configs/rl_from_base_qwen4b.toml +0 -0
- /synth_ai/{demos → cli/demo_apps}/demo_task_apps/math/__init__.py +0 -0
- /synth_ai/{demos → cli/demo_apps}/demo_task_apps/math/_common.py +0 -0
- /synth_ai/{demos → cli/demo_apps}/demo_task_apps/math/app.py +0 -0
- /synth_ai/{demos → cli/demo_apps}/demo_task_apps/math/deploy_modal.py +0 -0
- {examples/task_apps → synth_ai/core/apps}/__init__.py +0 -0
- /synth_ai/{tracing_v3 → core/tracing_v3}/examples/basic_usage.py +0 -0
- /synth_ai/{tracing_v3 → core/tracing_v3}/hooks.py +0 -0
- /synth_ai/{tracing_v3 → core/tracing_v3}/lm_call_record_abstractions.py +0 -0
- /synth_ai/{tracing_v3 → core/tracing_v3}/replica_sync.py +0 -0
- /synth_ai/{tracing_v3 → core/tracing_v3}/serialization.py +0 -0
- /synth_ai/{tracing_v3 → core/tracing_v3}/storage/__init__.py +0 -0
- /synth_ai/{tracing_v3 → core/tracing_v3}/storage/exceptions.py +0 -0
- /synth_ai/{tracing_v3 → core/tracing_v3}/storage/types.py +0 -0
- /synth_ai/{tracing_v3 → core/tracing_v3}/storage/utils.py +0 -0
- /synth_ai/{tracing_v3 → core/tracing_v3}/turso/__init__.py +0 -0
- /synth_ai/{learning → sdk/learning}/algorithms.py +0 -0
- /synth_ai/{learning → sdk/learning}/config.py +0 -0
- /synth_ai/{learning → sdk/learning}/constants.py +0 -0
- /synth_ai/{learning → sdk/learning}/core.py +0 -0
- /synth_ai/{learning → sdk/learning}/gateway.py +0 -0
- /synth_ai/{learning → sdk/learning}/rl/config.py +0 -0
- /synth_ai/{learning → sdk/learning}/rl_client.py +0 -0
- /synth_ai/{learning → sdk/learning}/sft/__init__.py +0 -0
- /synth_ai/{learning → sdk/learning}/sse.py +0 -0
- /synth_ai/{task → sdk/task}/auth.py +0 -0
- /synth_ai/{task → sdk/task}/errors.py +0 -0
- /synth_ai/{task → sdk/task}/health.py +0 -0
- /synth_ai/{task → sdk/task}/json.py +0 -0
- /synth_ai/{task → sdk/task}/rubrics/models.py +0 -0
- /synth_ai/{task → sdk/task}/rubrics/scoring.py +0 -0
- /synth_ai/{task → sdk/task}/vendors.py +0 -0
- {synth_ai-0.2.14.dist-info → synth_ai-0.4.4.dist-info}/WHEEL +0 -0
- {synth_ai-0.2.14.dist-info → synth_ai-0.4.4.dist-info}/entry_points.txt +0 -0
- {synth_ai-0.2.14.dist-info → synth_ai-0.4.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,800 @@
|
|
|
1
|
+
"""First-class SDK API for prompt learning (MIPRO and GEPA).
|
|
2
|
+
|
|
3
|
+
**Status:** Alpha
|
|
4
|
+
|
|
5
|
+
Note: MIPRO is Experimental, GEPA is Alpha.
|
|
6
|
+
|
|
7
|
+
This module provides high-level abstractions for running prompt optimization jobs
|
|
8
|
+
both via CLI (`uvx synth-ai train`) and programmatically in Python scripts.
|
|
9
|
+
|
|
10
|
+
Example CLI usage:
|
|
11
|
+
uvx synth-ai train --type prompt_learning --config my_config.toml --poll
|
|
12
|
+
|
|
13
|
+
Example SDK usage:
|
|
14
|
+
from synth_ai.sdk.api.train.prompt_learning import PromptLearningJob
|
|
15
|
+
|
|
16
|
+
job = PromptLearningJob.from_dict(config_dict, api_key="sk_live_...")
|
|
17
|
+
job.submit()
|
|
18
|
+
result = job.poll_until_complete(progress=True) # Built-in progress printing
|
|
19
|
+
|
|
20
|
+
if result.succeeded:
|
|
21
|
+
print(f"Best score: {result.best_score}")
|
|
22
|
+
else:
|
|
23
|
+
print(f"Failed: {result.error}")
|
|
24
|
+
|
|
25
|
+
For domain-specific verification, you can use **Verifier Graphs**. See `PromptLearningVerifierConfig`
|
|
26
|
+
in `synth_ai.sdk.api.train.configs.prompt_learning` for configuration details.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from __future__ import annotations
|
|
30
|
+
|
|
31
|
+
import asyncio
|
|
32
|
+
import os
|
|
33
|
+
import time
|
|
34
|
+
from dataclasses import dataclass, field
|
|
35
|
+
from enum import Enum
|
|
36
|
+
from pathlib import Path
|
|
37
|
+
from typing import Any, Callable, Dict, List, Optional
|
|
38
|
+
|
|
39
|
+
from synth_ai.core.telemetry import log_info
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class JobStatus(str, Enum):
|
|
43
|
+
"""Status of a prompt learning job."""
|
|
44
|
+
|
|
45
|
+
PENDING = "pending"
|
|
46
|
+
QUEUED = "queued"
|
|
47
|
+
RUNNING = "running"
|
|
48
|
+
SUCCEEDED = "succeeded"
|
|
49
|
+
FAILED = "failed"
|
|
50
|
+
CANCELLED = "cancelled"
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def from_string(cls, status: str) -> "JobStatus":
|
|
54
|
+
"""Convert string to JobStatus, defaulting to PENDING for unknown values."""
|
|
55
|
+
try:
|
|
56
|
+
return cls(status.lower())
|
|
57
|
+
except ValueError:
|
|
58
|
+
return cls.PENDING
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def is_terminal(self) -> bool:
|
|
62
|
+
"""Whether this status is terminal (job won't change further)."""
|
|
63
|
+
return self in (JobStatus.SUCCEEDED, JobStatus.FAILED, JobStatus.CANCELLED)
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def is_success(self) -> bool:
|
|
67
|
+
"""Whether this status indicates success."""
|
|
68
|
+
return self == JobStatus.SUCCEEDED
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass
|
|
72
|
+
class PromptLearningResult:
|
|
73
|
+
"""Typed result from a prompt learning job.
|
|
74
|
+
|
|
75
|
+
Provides clean accessors for common fields instead of raw dict access.
|
|
76
|
+
|
|
77
|
+
Example:
|
|
78
|
+
>>> result = job.poll_until_complete()
|
|
79
|
+
>>> if result.succeeded:
|
|
80
|
+
... print(f"Best score: {result.best_score}")
|
|
81
|
+
... print(f"Best prompt: {result.best_prompt[:100]}...")
|
|
82
|
+
>>> else:
|
|
83
|
+
... print(f"Failed: {result.error}")
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
job_id: str
|
|
87
|
+
status: JobStatus
|
|
88
|
+
best_score: Optional[float] = None
|
|
89
|
+
best_prompt: Optional[str] = None
|
|
90
|
+
error: Optional[str] = None
|
|
91
|
+
raw: Dict[str, Any] = field(default_factory=dict)
|
|
92
|
+
|
|
93
|
+
@classmethod
|
|
94
|
+
def from_response(cls, job_id: str, data: Dict[str, Any]) -> "PromptLearningResult":
|
|
95
|
+
"""Create result from API response dict."""
|
|
96
|
+
status_str = data.get("status", "pending")
|
|
97
|
+
status = JobStatus.from_string(status_str)
|
|
98
|
+
|
|
99
|
+
# Extract best score from various field names (backward compat)
|
|
100
|
+
best_score = (
|
|
101
|
+
data.get("best_score")
|
|
102
|
+
or data.get("best_reward")
|
|
103
|
+
or data.get("best_train_score")
|
|
104
|
+
or data.get("best_train_reward")
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
return cls(
|
|
108
|
+
job_id=job_id,
|
|
109
|
+
status=status,
|
|
110
|
+
best_score=best_score,
|
|
111
|
+
best_prompt=data.get("best_prompt"),
|
|
112
|
+
error=data.get("error"),
|
|
113
|
+
raw=data,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def succeeded(self) -> bool:
|
|
118
|
+
"""Whether the job succeeded."""
|
|
119
|
+
return self.status.is_success
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def failed(self) -> bool:
|
|
123
|
+
"""Whether the job failed."""
|
|
124
|
+
return self.status == JobStatus.FAILED
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def is_terminal(self) -> bool:
|
|
128
|
+
"""Whether the job has reached a terminal state."""
|
|
129
|
+
return self.status.is_terminal
|
|
130
|
+
|
|
131
|
+
from .builders import (
|
|
132
|
+
PromptLearningBuildResult,
|
|
133
|
+
build_prompt_learning_payload,
|
|
134
|
+
build_prompt_learning_payload_from_mapping,
|
|
135
|
+
)
|
|
136
|
+
from .pollers import JobPoller, PollOutcome
|
|
137
|
+
from .local_api import check_local_api_health
|
|
138
|
+
from .utils import ensure_api_base, http_get, http_post
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@dataclass
|
|
142
|
+
class PromptLearningJobConfig:
|
|
143
|
+
"""Configuration for a prompt learning job.
|
|
144
|
+
|
|
145
|
+
This dataclass holds all the configuration needed to submit and run
|
|
146
|
+
a prompt learning job (MIPRO or GEPA optimization).
|
|
147
|
+
|
|
148
|
+
Supports two modes:
|
|
149
|
+
1. **File-based**: Provide `config_path` pointing to a TOML file
|
|
150
|
+
2. **Programmatic**: Provide `config_dict` with the configuration directly
|
|
151
|
+
|
|
152
|
+
Both modes go through the same `PromptLearningConfig` Pydantic validation.
|
|
153
|
+
|
|
154
|
+
Attributes:
|
|
155
|
+
config_path: Path to the TOML configuration file. Mutually exclusive with config_dict.
|
|
156
|
+
config_dict: Dictionary with prompt learning configuration. Mutually exclusive with config_path.
|
|
157
|
+
Should have the same structure as the TOML file (with 'prompt_learning' section).
|
|
158
|
+
backend_url: Base URL of the Synth API backend (e.g., "https://api.usesynth.ai").
|
|
159
|
+
api_key: Synth API key for authentication.
|
|
160
|
+
task_app_api_key: API key for authenticating with the Local API.
|
|
161
|
+
allow_experimental: If True, allows use of experimental models.
|
|
162
|
+
overrides: Dictionary of config overrides.
|
|
163
|
+
|
|
164
|
+
Example (file-based):
|
|
165
|
+
>>> config = PromptLearningJobConfig(
|
|
166
|
+
... config_path=Path("my_config.toml"),
|
|
167
|
+
... backend_url="https://api.usesynth.ai",
|
|
168
|
+
... api_key="sk_live_...",
|
|
169
|
+
... )
|
|
170
|
+
|
|
171
|
+
Example (programmatic):
|
|
172
|
+
>>> config = PromptLearningJobConfig(
|
|
173
|
+
... config_dict={
|
|
174
|
+
... "prompt_learning": {
|
|
175
|
+
... "algorithm": "gepa",
|
|
176
|
+
... "task_app_url": "https://tunnel.example.com",
|
|
177
|
+
... "policy": {"model": "gpt-4o-mini", "provider": "openai"},
|
|
178
|
+
... "gepa": {...},
|
|
179
|
+
... }
|
|
180
|
+
... },
|
|
181
|
+
... backend_url="https://api.usesynth.ai",
|
|
182
|
+
... api_key="sk_live_...",
|
|
183
|
+
... )
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
backend_url: str
|
|
187
|
+
api_key: str
|
|
188
|
+
config_path: Optional[Path] = None
|
|
189
|
+
config_dict: Optional[Dict[str, Any]] = None
|
|
190
|
+
task_app_api_key: Optional[str] = None
|
|
191
|
+
allow_experimental: Optional[bool] = None
|
|
192
|
+
overrides: Optional[Dict[str, Any]] = None
|
|
193
|
+
|
|
194
|
+
def __post_init__(self) -> None:
|
|
195
|
+
"""Validate configuration."""
|
|
196
|
+
# Must provide exactly one of config_path or config_dict
|
|
197
|
+
has_path = self.config_path is not None
|
|
198
|
+
has_dict = self.config_dict is not None
|
|
199
|
+
|
|
200
|
+
if has_path and has_dict:
|
|
201
|
+
raise ValueError("Provide either config_path OR config_dict, not both")
|
|
202
|
+
if not has_path and not has_dict:
|
|
203
|
+
raise ValueError("Either config_path or config_dict is required")
|
|
204
|
+
|
|
205
|
+
if has_path and not self.config_path.exists():
|
|
206
|
+
raise FileNotFoundError(f"Config file not found: {self.config_path}")
|
|
207
|
+
|
|
208
|
+
if not self.backend_url:
|
|
209
|
+
raise ValueError("backend_url is required")
|
|
210
|
+
if not self.api_key:
|
|
211
|
+
raise ValueError("api_key is required")
|
|
212
|
+
|
|
213
|
+
# Get task_app_api_key from environment if not provided
|
|
214
|
+
if not self.task_app_api_key:
|
|
215
|
+
self.task_app_api_key = os.environ.get("ENVIRONMENT_API_KEY")
|
|
216
|
+
if not self.task_app_api_key:
|
|
217
|
+
raise ValueError(
|
|
218
|
+
"task_app_api_key is required (provide explicitly or set ENVIRONMENT_API_KEY env var)"
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
class PromptLearningJobPoller(JobPoller):
|
|
223
|
+
"""Poller for prompt learning jobs."""
|
|
224
|
+
|
|
225
|
+
def poll_job(self, job_id: str) -> PollOutcome:
|
|
226
|
+
"""Poll a prompt learning job by ID.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
job_id: Job ID (e.g., "pl_9c58b711c2644083")
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
PollOutcome with status and payload
|
|
233
|
+
"""
|
|
234
|
+
return super().poll(f"/api/prompt-learning/online/jobs/{job_id}")
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
class PromptLearningJob:
|
|
238
|
+
"""High-level SDK class for running prompt learning jobs (MIPRO or GEPA).
|
|
239
|
+
|
|
240
|
+
This class provides a clean API for:
|
|
241
|
+
1. Submitting prompt learning jobs
|
|
242
|
+
2. Polling job status
|
|
243
|
+
3. Retrieving results
|
|
244
|
+
|
|
245
|
+
Example:
|
|
246
|
+
>>> from synth_ai.sdk.api.train.prompt_learning import PromptLearningJob
|
|
247
|
+
>>>
|
|
248
|
+
>>> # Create job from config
|
|
249
|
+
>>> job = PromptLearningJob.from_config(
|
|
250
|
+
... config_path="my_config.toml",
|
|
251
|
+
... backend_url="https://api.usesynth.ai",
|
|
252
|
+
... api_key=os.environ["SYNTH_API_KEY"]
|
|
253
|
+
... )
|
|
254
|
+
>>>
|
|
255
|
+
>>> # Submit job
|
|
256
|
+
>>> job_id = job.submit()
|
|
257
|
+
>>> print(f"Job submitted: {job_id}")
|
|
258
|
+
>>>
|
|
259
|
+
>>> # Poll until complete
|
|
260
|
+
>>> result = job.poll_until_complete(timeout=3600.0)
|
|
261
|
+
>>> print(f"Best score: {result['best_score']}")
|
|
262
|
+
>>>
|
|
263
|
+
>>> # Or poll manually
|
|
264
|
+
>>> status = job.get_status()
|
|
265
|
+
>>> print(f"Status: {status['status']}")
|
|
266
|
+
"""
|
|
267
|
+
|
|
268
|
+
def __init__(
|
|
269
|
+
self,
|
|
270
|
+
config: PromptLearningJobConfig,
|
|
271
|
+
job_id: Optional[str] = None,
|
|
272
|
+
skip_health_check: bool = False,
|
|
273
|
+
) -> None:
|
|
274
|
+
"""Initialize a prompt learning job.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
config: Job configuration
|
|
278
|
+
job_id: Existing job ID (if resuming a previous job)
|
|
279
|
+
skip_health_check: If True, skip task app health check before submission.
|
|
280
|
+
Useful when using tunnels where DNS may not have propagated yet.
|
|
281
|
+
"""
|
|
282
|
+
self.config = config
|
|
283
|
+
self._job_id = job_id
|
|
284
|
+
self._build_result: Optional[PromptLearningBuildResult] = None
|
|
285
|
+
self._skip_health_check = skip_health_check
|
|
286
|
+
|
|
287
|
+
@classmethod
|
|
288
|
+
def from_config(
|
|
289
|
+
cls,
|
|
290
|
+
config_path: str | Path,
|
|
291
|
+
backend_url: Optional[str] = None,
|
|
292
|
+
api_key: Optional[str] = None,
|
|
293
|
+
task_app_api_key: Optional[str] = None,
|
|
294
|
+
allow_experimental: Optional[bool] = None,
|
|
295
|
+
overrides: Optional[Dict[str, Any]] = None,
|
|
296
|
+
) -> PromptLearningJob:
|
|
297
|
+
"""Create a job from a TOML config file.
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
config_path: Path to TOML config file
|
|
301
|
+
backend_url: Backend API URL (defaults to env or production)
|
|
302
|
+
api_key: API key (defaults to SYNTH_API_KEY env var)
|
|
303
|
+
task_app_api_key: Task app API key (defaults to ENVIRONMENT_API_KEY env var)
|
|
304
|
+
allow_experimental: Allow experimental models
|
|
305
|
+
overrides: Config overrides
|
|
306
|
+
|
|
307
|
+
Returns:
|
|
308
|
+
PromptLearningJob instance
|
|
309
|
+
|
|
310
|
+
Raises:
|
|
311
|
+
ValueError: If required config is missing
|
|
312
|
+
FileNotFoundError: If config file doesn't exist
|
|
313
|
+
"""
|
|
314
|
+
import os
|
|
315
|
+
|
|
316
|
+
from synth_ai.core.env import get_backend_from_env
|
|
317
|
+
|
|
318
|
+
config_path_obj = Path(config_path)
|
|
319
|
+
|
|
320
|
+
# Resolve backend URL
|
|
321
|
+
if not backend_url:
|
|
322
|
+
backend_url = os.environ.get("BACKEND_BASE_URL", "").strip()
|
|
323
|
+
if not backend_url:
|
|
324
|
+
base, _ = get_backend_from_env()
|
|
325
|
+
backend_url = f"{base}/api" if not base.endswith("/api") else base
|
|
326
|
+
|
|
327
|
+
# Resolve API key
|
|
328
|
+
if not api_key:
|
|
329
|
+
api_key = os.environ.get("SYNTH_API_KEY")
|
|
330
|
+
if not api_key:
|
|
331
|
+
raise ValueError(
|
|
332
|
+
"api_key is required (provide explicitly or set SYNTH_API_KEY env var)"
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
config = PromptLearningJobConfig(
|
|
336
|
+
config_path=config_path_obj,
|
|
337
|
+
backend_url=backend_url,
|
|
338
|
+
api_key=api_key,
|
|
339
|
+
task_app_api_key=task_app_api_key,
|
|
340
|
+
allow_experimental=allow_experimental,
|
|
341
|
+
overrides=overrides or {},
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
return cls(config)
|
|
345
|
+
|
|
346
|
+
@classmethod
|
|
347
|
+
def from_dict(
|
|
348
|
+
cls,
|
|
349
|
+
config_dict: Dict[str, Any],
|
|
350
|
+
backend_url: Optional[str] = None,
|
|
351
|
+
api_key: Optional[str] = None,
|
|
352
|
+
task_app_api_key: Optional[str] = None,
|
|
353
|
+
allow_experimental: Optional[bool] = None,
|
|
354
|
+
overrides: Optional[Dict[str, Any]] = None,
|
|
355
|
+
skip_health_check: bool = False,
|
|
356
|
+
) -> PromptLearningJob:
|
|
357
|
+
"""Create a job from a configuration dictionary (programmatic use).
|
|
358
|
+
|
|
359
|
+
This allows creating prompt learning jobs without a TOML file, enabling
|
|
360
|
+
programmatic use in notebooks, scripts, and applications.
|
|
361
|
+
|
|
362
|
+
The config_dict should have the same structure as a TOML file:
|
|
363
|
+
```python
|
|
364
|
+
{
|
|
365
|
+
"prompt_learning": {
|
|
366
|
+
"algorithm": "gepa",
|
|
367
|
+
"task_app_url": "https://...",
|
|
368
|
+
"policy": {"model": "gpt-4o-mini", "provider": "openai"},
|
|
369
|
+
"gepa": {...},
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
Args:
|
|
375
|
+
config_dict: Configuration dictionary with 'prompt_learning' section
|
|
376
|
+
backend_url: Backend API URL (defaults to env or production)
|
|
377
|
+
api_key: API key (defaults to SYNTH_API_KEY env var)
|
|
378
|
+
task_app_api_key: Task app API key (defaults to ENVIRONMENT_API_KEY env var)
|
|
379
|
+
allow_experimental: Allow experimental models
|
|
380
|
+
overrides: Config overrides
|
|
381
|
+
skip_health_check: If True, skip task app health check before submission
|
|
382
|
+
|
|
383
|
+
Returns:
|
|
384
|
+
PromptLearningJob instance
|
|
385
|
+
|
|
386
|
+
Raises:
|
|
387
|
+
ValueError: If required config is missing or invalid
|
|
388
|
+
|
|
389
|
+
Example:
|
|
390
|
+
>>> job = PromptLearningJob.from_dict(
|
|
391
|
+
... config_dict={
|
|
392
|
+
... "prompt_learning": {
|
|
393
|
+
... "algorithm": "gepa",
|
|
394
|
+
... "task_app_url": "https://tunnel.example.com",
|
|
395
|
+
... "policy": {"model": "gpt-4o-mini", "provider": "openai"},
|
|
396
|
+
... "gepa": {
|
|
397
|
+
... "rollout": {"budget": 50, "max_concurrent": 5},
|
|
398
|
+
... "evaluation": {"train_seeds": [1, 2, 3], "val_seeds": [4, 5]},
|
|
399
|
+
... "population": {"num_generations": 2, "children_per_generation": 2},
|
|
400
|
+
... },
|
|
401
|
+
... }
|
|
402
|
+
... },
|
|
403
|
+
... api_key="sk_live_...",
|
|
404
|
+
... )
|
|
405
|
+
>>> job_id = job.submit()
|
|
406
|
+
"""
|
|
407
|
+
import os
|
|
408
|
+
|
|
409
|
+
from synth_ai.core.env import get_backend_from_env
|
|
410
|
+
|
|
411
|
+
# Resolve backend URL
|
|
412
|
+
if not backend_url:
|
|
413
|
+
backend_url = os.environ.get("BACKEND_BASE_URL", "").strip()
|
|
414
|
+
if not backend_url:
|
|
415
|
+
base, _ = get_backend_from_env()
|
|
416
|
+
backend_url = f"{base}/api" if not base.endswith("/api") else base
|
|
417
|
+
|
|
418
|
+
# Resolve API key
|
|
419
|
+
if not api_key:
|
|
420
|
+
api_key = os.environ.get("SYNTH_API_KEY")
|
|
421
|
+
if not api_key:
|
|
422
|
+
raise ValueError(
|
|
423
|
+
"api_key is required (provide explicitly or set SYNTH_API_KEY env var)"
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
config = PromptLearningJobConfig(
|
|
427
|
+
config_dict=config_dict,
|
|
428
|
+
backend_url=backend_url,
|
|
429
|
+
api_key=api_key,
|
|
430
|
+
task_app_api_key=task_app_api_key,
|
|
431
|
+
allow_experimental=allow_experimental,
|
|
432
|
+
overrides=overrides or {},
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
return cls(config, skip_health_check=skip_health_check)
|
|
436
|
+
|
|
437
|
+
@classmethod
|
|
438
|
+
def from_job_id(
|
|
439
|
+
cls,
|
|
440
|
+
job_id: str,
|
|
441
|
+
backend_url: Optional[str] = None,
|
|
442
|
+
api_key: Optional[str] = None,
|
|
443
|
+
) -> PromptLearningJob:
|
|
444
|
+
"""Resume an existing job by ID.
|
|
445
|
+
|
|
446
|
+
Args:
|
|
447
|
+
job_id: Existing job ID
|
|
448
|
+
backend_url: Backend API URL (defaults to env or production)
|
|
449
|
+
api_key: API key (defaults to SYNTH_API_KEY env var)
|
|
450
|
+
|
|
451
|
+
Returns:
|
|
452
|
+
PromptLearningJob instance for the existing job
|
|
453
|
+
"""
|
|
454
|
+
import os
|
|
455
|
+
|
|
456
|
+
from synth_ai.core.env import get_backend_from_env
|
|
457
|
+
|
|
458
|
+
# Resolve backend URL
|
|
459
|
+
if not backend_url:
|
|
460
|
+
backend_url = os.environ.get("BACKEND_BASE_URL", "").strip()
|
|
461
|
+
if not backend_url:
|
|
462
|
+
base, _ = get_backend_from_env()
|
|
463
|
+
backend_url = f"{base}/api" if not base.endswith("/api") else base
|
|
464
|
+
|
|
465
|
+
# Resolve API key
|
|
466
|
+
if not api_key:
|
|
467
|
+
api_key = os.environ.get("SYNTH_API_KEY")
|
|
468
|
+
if not api_key:
|
|
469
|
+
raise ValueError(
|
|
470
|
+
"api_key is required (provide explicitly or set SYNTH_API_KEY env var)"
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
# Create minimal config (we don't need the config for resuming - use empty dict)
|
|
474
|
+
# The config_dict is never used when resuming since we have the job_id
|
|
475
|
+
config = PromptLearningJobConfig(
|
|
476
|
+
config_dict={"prompt_learning": {"_resumed": True}}, # Placeholder for resume mode
|
|
477
|
+
backend_url=backend_url,
|
|
478
|
+
api_key=api_key,
|
|
479
|
+
)
|
|
480
|
+
|
|
481
|
+
return cls(config, job_id=job_id)
|
|
482
|
+
|
|
483
|
+
def _build_payload(self) -> PromptLearningBuildResult:
|
|
484
|
+
"""Build the job payload from config.
|
|
485
|
+
|
|
486
|
+
Supports both file-based (config_path) and programmatic (config_dict) modes.
|
|
487
|
+
Both modes route through the same PromptLearningConfig Pydantic validation.
|
|
488
|
+
"""
|
|
489
|
+
if self._build_result is None:
|
|
490
|
+
overrides = self.config.overrides or {}
|
|
491
|
+
overrides["backend"] = self.config.backend_url
|
|
492
|
+
# Pass task_app_api_key to builder via overrides
|
|
493
|
+
if self.config.task_app_api_key:
|
|
494
|
+
overrides["task_app_api_key"] = self.config.task_app_api_key
|
|
495
|
+
|
|
496
|
+
# Route to appropriate builder based on config mode
|
|
497
|
+
if self.config.config_dict is not None:
|
|
498
|
+
# Programmatic mode: use dict-based builder
|
|
499
|
+
self._build_result = build_prompt_learning_payload_from_mapping(
|
|
500
|
+
raw_config=self.config.config_dict,
|
|
501
|
+
task_url=None,
|
|
502
|
+
overrides=overrides,
|
|
503
|
+
allow_experimental=self.config.allow_experimental,
|
|
504
|
+
source_label="PromptLearningJob.from_dict",
|
|
505
|
+
)
|
|
506
|
+
elif self.config.config_path is not None:
|
|
507
|
+
# File-based mode: use path-based builder
|
|
508
|
+
if not self.config.config_path.exists():
|
|
509
|
+
raise RuntimeError(
|
|
510
|
+
f"Config file not found: {self.config.config_path}. "
|
|
511
|
+
"Use from_dict() for programmatic config or from_job_id() to resume."
|
|
512
|
+
)
|
|
513
|
+
|
|
514
|
+
self._build_result = build_prompt_learning_payload(
|
|
515
|
+
config_path=self.config.config_path,
|
|
516
|
+
task_url=None,
|
|
517
|
+
overrides=overrides,
|
|
518
|
+
allow_experimental=self.config.allow_experimental,
|
|
519
|
+
)
|
|
520
|
+
else:
|
|
521
|
+
raise RuntimeError(
|
|
522
|
+
"Cannot build payload: either config_path or config_dict is required. "
|
|
523
|
+
"Use from_config() for file-based config, from_dict() for programmatic config, "
|
|
524
|
+
"or from_job_id() to resume an existing job."
|
|
525
|
+
)
|
|
526
|
+
return self._build_result
|
|
527
|
+
|
|
528
|
+
def submit(self) -> str:
|
|
529
|
+
"""Submit the job to the backend.
|
|
530
|
+
|
|
531
|
+
Returns:
|
|
532
|
+
Job ID
|
|
533
|
+
|
|
534
|
+
Raises:
|
|
535
|
+
RuntimeError: If job submission fails
|
|
536
|
+
ValueError: If task app health check fails
|
|
537
|
+
"""
|
|
538
|
+
# Log context based on config mode
|
|
539
|
+
if self.config.config_path is not None:
|
|
540
|
+
ctx: Dict[str, Any] = {"config_path": str(self.config.config_path)}
|
|
541
|
+
else:
|
|
542
|
+
ctx = {"config_mode": "programmatic"}
|
|
543
|
+
log_info("PromptLearningJob.submit invoked", ctx=ctx)
|
|
544
|
+
if self._job_id:
|
|
545
|
+
raise RuntimeError(f"Job already submitted: {self._job_id}")
|
|
546
|
+
|
|
547
|
+
build = self._build_payload()
|
|
548
|
+
|
|
549
|
+
# Health check (skip if _skip_health_check is set - useful for tunnels with DNS delay)
|
|
550
|
+
if not self._skip_health_check:
|
|
551
|
+
health = check_local_api_health(build.task_url, self.config.task_app_api_key or "")
|
|
552
|
+
if not health.ok:
|
|
553
|
+
raise ValueError(f"Task app health check failed: {health.detail}")
|
|
554
|
+
|
|
555
|
+
# Submit job
|
|
556
|
+
create_url = f"{ensure_api_base(self.config.backend_url)}/prompt-learning/online/jobs"
|
|
557
|
+
headers = {
|
|
558
|
+
"X-API-Key": self.config.api_key,
|
|
559
|
+
"Content-Type": "application/json",
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
# Debug: log the URL being called
|
|
563
|
+
import logging
|
|
564
|
+
logger = logging.getLogger(__name__)
|
|
565
|
+
logger.debug(f"Submitting job to: {create_url}")
|
|
566
|
+
|
|
567
|
+
resp = http_post(create_url, headers=headers, json_body=build.payload)
|
|
568
|
+
|
|
569
|
+
if resp.status_code not in (200, 201):
|
|
570
|
+
error_msg = f"Job submission failed with status {resp.status_code}: {resp.text[:500]}"
|
|
571
|
+
if resp.status_code == 404:
|
|
572
|
+
error_msg += (
|
|
573
|
+
f"\n\nPossible causes:"
|
|
574
|
+
f"\n1. Backend route /api/prompt-learning/online/jobs not registered"
|
|
575
|
+
f"\n2. Backend server needs restart (lazy import may have failed)"
|
|
576
|
+
f"\n3. Check backend logs for: 'Failed to import prompt_learning_online_router'"
|
|
577
|
+
f"\n4. Verify backend is running at: {self.config.backend_url}"
|
|
578
|
+
)
|
|
579
|
+
raise RuntimeError(error_msg)
|
|
580
|
+
|
|
581
|
+
try:
|
|
582
|
+
js = resp.json()
|
|
583
|
+
except Exception as e:
|
|
584
|
+
raise RuntimeError(f"Failed to parse response: {e}") from e
|
|
585
|
+
|
|
586
|
+
job_id = js.get("job_id") or js.get("id")
|
|
587
|
+
if not job_id:
|
|
588
|
+
raise RuntimeError("Response missing job ID")
|
|
589
|
+
|
|
590
|
+
self._job_id = job_id
|
|
591
|
+
ctx["job_id"] = job_id
|
|
592
|
+
log_info("PromptLearningJob.submit completed", ctx=ctx)
|
|
593
|
+
return job_id
|
|
594
|
+
|
|
595
|
+
@property
|
|
596
|
+
def job_id(self) -> Optional[str]:
|
|
597
|
+
"""Get the job ID (None if not yet submitted)."""
|
|
598
|
+
return self._job_id
|
|
599
|
+
|
|
600
|
+
def get_status(self) -> Dict[str, Any]:
|
|
601
|
+
"""Get current job status.
|
|
602
|
+
|
|
603
|
+
Returns:
|
|
604
|
+
Job status dictionary
|
|
605
|
+
|
|
606
|
+
Raises:
|
|
607
|
+
RuntimeError: If job hasn't been submitted yet
|
|
608
|
+
ValueError: If job ID format is invalid
|
|
609
|
+
"""
|
|
610
|
+
if not self._job_id:
|
|
611
|
+
raise RuntimeError("Job not yet submitted. Call submit() first.")
|
|
612
|
+
|
|
613
|
+
from synth_ai.sdk.learning.prompt_learning_client import PromptLearningClient
|
|
614
|
+
|
|
615
|
+
async def _fetch() -> Dict[str, Any]:
|
|
616
|
+
client = PromptLearningClient(
|
|
617
|
+
ensure_api_base(self.config.backend_url),
|
|
618
|
+
self.config.api_key,
|
|
619
|
+
timeout=30.0,
|
|
620
|
+
)
|
|
621
|
+
result = await client.get_job(self._job_id) # type: ignore[arg-type] # We check None above
|
|
622
|
+
return dict(result) if isinstance(result, dict) else {}
|
|
623
|
+
|
|
624
|
+
return asyncio.run(_fetch())
|
|
625
|
+
|
|
626
|
+
def poll_until_complete(
|
|
627
|
+
self,
|
|
628
|
+
*,
|
|
629
|
+
timeout: float = 3600.0,
|
|
630
|
+
interval: float = 5.0,
|
|
631
|
+
progress: bool = False,
|
|
632
|
+
on_status: Optional[Callable[[Dict[str, Any]], None]] = None,
|
|
633
|
+
) -> PromptLearningResult:
|
|
634
|
+
"""Poll job until it reaches a terminal state.
|
|
635
|
+
|
|
636
|
+
Args:
|
|
637
|
+
timeout: Maximum seconds to wait
|
|
638
|
+
interval: Seconds between poll attempts
|
|
639
|
+
progress: If True, print status updates during polling (useful for notebooks)
|
|
640
|
+
on_status: Optional callback called on each status update (for custom progress handling)
|
|
641
|
+
|
|
642
|
+
Returns:
|
|
643
|
+
PromptLearningResult with typed status, best_score, etc.
|
|
644
|
+
|
|
645
|
+
Raises:
|
|
646
|
+
RuntimeError: If job hasn't been submitted yet
|
|
647
|
+
TimeoutError: If timeout is exceeded
|
|
648
|
+
|
|
649
|
+
Example:
|
|
650
|
+
>>> result = job.poll_until_complete(progress=True)
|
|
651
|
+
[00:15] running | score: 0.72
|
|
652
|
+
[00:30] running | score: 0.78
|
|
653
|
+
[00:45] succeeded | score: 0.85
|
|
654
|
+
>>> result.succeeded
|
|
655
|
+
True
|
|
656
|
+
>>> result.best_score
|
|
657
|
+
0.85
|
|
658
|
+
"""
|
|
659
|
+
if not self._job_id:
|
|
660
|
+
raise RuntimeError("Job not yet submitted. Call submit() first.")
|
|
661
|
+
|
|
662
|
+
job_id = self._job_id
|
|
663
|
+
base_url = ensure_api_base(self.config.backend_url)
|
|
664
|
+
headers = {
|
|
665
|
+
"Authorization": f"Bearer {self.config.api_key}",
|
|
666
|
+
"Content-Type": "application/json",
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
start_time = time.time()
|
|
670
|
+
elapsed = 0.0
|
|
671
|
+
last_data: Dict[str, Any] = {}
|
|
672
|
+
|
|
673
|
+
while elapsed <= timeout:
|
|
674
|
+
try:
|
|
675
|
+
# Fetch job status
|
|
676
|
+
url = f"{base_url}/prompt-learning/online/jobs/{job_id}"
|
|
677
|
+
resp = http_get(url, headers=headers)
|
|
678
|
+
data = resp.json() if resp.headers.get("content-type", "").startswith("application/json") else {}
|
|
679
|
+
last_data = dict(data) if isinstance(data, dict) else {}
|
|
680
|
+
|
|
681
|
+
status = JobStatus.from_string(last_data.get("status", "pending"))
|
|
682
|
+
best_score = (
|
|
683
|
+
last_data.get("best_score")
|
|
684
|
+
or last_data.get("best_reward")
|
|
685
|
+
or last_data.get("best_train_score")
|
|
686
|
+
or last_data.get("best_train_reward")
|
|
687
|
+
)
|
|
688
|
+
|
|
689
|
+
# Progress output
|
|
690
|
+
if progress:
|
|
691
|
+
mins, secs = divmod(int(elapsed), 60)
|
|
692
|
+
score_str = f"score: {best_score:.2f}" if best_score is not None else "score: --"
|
|
693
|
+
print(f"[{mins:02d}:{secs:02d}] {status.value} | {score_str}")
|
|
694
|
+
|
|
695
|
+
# Callback for custom handling
|
|
696
|
+
if on_status:
|
|
697
|
+
on_status(last_data)
|
|
698
|
+
|
|
699
|
+
# Check terminal state
|
|
700
|
+
if status.is_terminal:
|
|
701
|
+
return PromptLearningResult.from_response(job_id, last_data)
|
|
702
|
+
|
|
703
|
+
except Exception as exc:
|
|
704
|
+
if progress:
|
|
705
|
+
print(f"[poll] error: {exc}")
|
|
706
|
+
log_info("poll request failed", ctx={"error": str(exc), "job_id": job_id})
|
|
707
|
+
|
|
708
|
+
time.sleep(interval)
|
|
709
|
+
elapsed = time.time() - start_time
|
|
710
|
+
|
|
711
|
+
# Timeout reached
|
|
712
|
+
if progress:
|
|
713
|
+
print(f"[poll] timeout after {timeout:.0f}s")
|
|
714
|
+
|
|
715
|
+
# Return with whatever data we have, status will indicate not complete
|
|
716
|
+
return PromptLearningResult.from_response(job_id, last_data)
|
|
717
|
+
|
|
718
|
+
def get_results(self) -> Dict[str, Any]:
|
|
719
|
+
"""Get job results (prompts, scores, etc.).
|
|
720
|
+
|
|
721
|
+
Returns:
|
|
722
|
+
Results dictionary with best_prompt, best_score, etc.
|
|
723
|
+
|
|
724
|
+
Raises:
|
|
725
|
+
RuntimeError: If job hasn't been submitted yet
|
|
726
|
+
"""
|
|
727
|
+
if not self._job_id:
|
|
728
|
+
raise RuntimeError("Job not yet submitted. Call submit() first.")
|
|
729
|
+
|
|
730
|
+
from synth_ai.sdk.learning.prompt_learning_client import PromptLearningClient
|
|
731
|
+
|
|
732
|
+
async def _fetch() -> Dict[str, Any]:
|
|
733
|
+
client = PromptLearningClient(
|
|
734
|
+
ensure_api_base(self.config.backend_url),
|
|
735
|
+
self.config.api_key,
|
|
736
|
+
)
|
|
737
|
+
results = await client.get_prompts(self._job_id) # type: ignore[arg-type] # We check None above
|
|
738
|
+
|
|
739
|
+
# Convert PromptResults dataclass to dict
|
|
740
|
+
return {
|
|
741
|
+
"best_prompt": results.best_prompt,
|
|
742
|
+
"best_score": results.best_score,
|
|
743
|
+
"top_prompts": results.top_prompts,
|
|
744
|
+
"optimized_candidates": results.optimized_candidates,
|
|
745
|
+
"attempted_candidates": results.attempted_candidates,
|
|
746
|
+
"validation_results": results.validation_results,
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
# Check if we're already in an event loop
|
|
750
|
+
try:
|
|
751
|
+
asyncio.get_running_loop()
|
|
752
|
+
# We're in an event loop - can't use asyncio.run()
|
|
753
|
+
# Use nest_asyncio to allow nested event loops if available
|
|
754
|
+
try:
|
|
755
|
+
import nest_asyncio # type: ignore[unresolved-import]
|
|
756
|
+
nest_asyncio.apply()
|
|
757
|
+
return asyncio.run(_fetch())
|
|
758
|
+
except ImportError:
|
|
759
|
+
# Fallback: run the coroutine in the existing loop
|
|
760
|
+
# This requires the caller to be in an async context
|
|
761
|
+
raise RuntimeError(
|
|
762
|
+
"get_results() cannot be called from an async context. "
|
|
763
|
+
"Either install nest_asyncio (pip install nest-asyncio) or "
|
|
764
|
+
"use await get_results_async() instead."
|
|
765
|
+
) from None
|
|
766
|
+
except RuntimeError:
|
|
767
|
+
# No event loop running - safe to use asyncio.run()
|
|
768
|
+
return asyncio.run(_fetch())
|
|
769
|
+
|
|
770
|
+
def get_best_prompt_text(self, rank: int = 1) -> Optional[str]:
|
|
771
|
+
"""Get the text of the best prompt by rank.
|
|
772
|
+
|
|
773
|
+
Args:
|
|
774
|
+
rank: Prompt rank (1 = best, 2 = second best, etc.)
|
|
775
|
+
|
|
776
|
+
Returns:
|
|
777
|
+
Prompt text or None if not found
|
|
778
|
+
"""
|
|
779
|
+
if not self._job_id:
|
|
780
|
+
raise RuntimeError("Job not yet submitted. Call submit() first.")
|
|
781
|
+
|
|
782
|
+
from synth_ai.sdk.learning.prompt_learning_client import PromptLearningClient
|
|
783
|
+
|
|
784
|
+
async def _fetch() -> Optional[str]:
|
|
785
|
+
client = PromptLearningClient(
|
|
786
|
+
ensure_api_base(self.config.backend_url),
|
|
787
|
+
self.config.api_key,
|
|
788
|
+
)
|
|
789
|
+
return await client.get_prompt_text(self._job_id, rank=rank) # type: ignore[arg-type] # We check None above
|
|
790
|
+
|
|
791
|
+
return asyncio.run(_fetch())
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
__all__ = [
|
|
795
|
+
"JobStatus",
|
|
796
|
+
"PromptLearningJob",
|
|
797
|
+
"PromptLearningJobConfig",
|
|
798
|
+
"PromptLearningJobPoller",
|
|
799
|
+
"PromptLearningResult",
|
|
800
|
+
]
|