synth-ai 0.2.14__py3-none-any.whl ā 0.4.1__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 +19 -40
- synth_ai/__main__.py +30 -3
- synth_ai/cli/__init__.py +105 -70
- 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/baseline/__init__.py +12 -0
- synth_ai/cli/commands/baseline/core.py +636 -0
- synth_ai/cli/commands/baseline/list.py +94 -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 +19 -0
- synth_ai/cli/commands/eval/core.py +1113 -0
- synth_ai/cli/commands/eval/errors.py +81 -0
- synth_ai/cli/commands/eval/validation.py +133 -0
- synth_ai/cli/commands/filter/__init__.py +12 -0
- synth_ai/cli/commands/filter/core.py +424 -0
- synth_ai/cli/commands/filter/errors.py +55 -0
- synth_ai/cli/commands/filter/validation.py +77 -0
- synth_ai/cli/commands/help/__init__.py +185 -0
- synth_ai/cli/commands/help/core.py +72 -0
- synth_ai/cli/commands/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 +1438 -0
- synth_ai/cli/commands/status/__init__.py +66 -0
- synth_ai/cli/commands/status/client.py +192 -0
- synth_ai/cli/commands/status/config.py +92 -0
- synth_ai/cli/commands/status/errors.py +20 -0
- synth_ai/cli/commands/status/formatters.py +164 -0
- synth_ai/cli/commands/status/subcommands/__init__.py +9 -0
- synth_ai/cli/commands/status/subcommands/files.py +79 -0
- synth_ai/cli/commands/status/subcommands/jobs.py +334 -0
- synth_ai/cli/commands/status/subcommands/models.py +79 -0
- synth_ai/cli/commands/status/subcommands/pricing.py +23 -0
- synth_ai/cli/commands/status/subcommands/runs.py +81 -0
- synth_ai/cli/commands/status/subcommands/session.py +182 -0
- synth_ai/cli/commands/status/subcommands/summary.py +47 -0
- synth_ai/cli/commands/status/subcommands/usage.py +203 -0
- synth_ai/cli/commands/status/utils.py +114 -0
- synth_ai/cli/commands/train/__init__.py +53 -0
- synth_ai/cli/commands/train/core.py +22 -0
- synth_ai/cli/commands/train/errors.py +117 -0
- synth_ai/cli/commands/train/judge_schemas.py +201 -0
- synth_ai/cli/commands/train/judge_validation.py +305 -0
- synth_ai/cli/commands/train/prompt_learning_validation.py +633 -0
- synth_ai/cli/commands/train/validation.py +392 -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/modal_task_app.py +742 -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 +76 -0
- synth_ai/cli/demo_apps/math/deploy_modal.py +54 -0
- synth_ai/cli/demo_apps/math/modal_task_app.py +702 -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 +933 -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 +643 -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 +26 -0
- synth_ai/cli/task_apps/commands.py +3153 -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/usage.py +159 -0
- 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 +220 -0
- synth_ai/core/errors.py +126 -0
- synth_ai/core/http.py +230 -0
- synth_ai/core/integrations/__init__.py +11 -0
- synth_ai/core/integrations/cloudflare.py +1710 -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 +302 -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 +110 -0
- synth_ai/data/enums.py +141 -0
- synth_ai/data/rewards.py +152 -0
- synth_ai/data/specs.py +36 -0
- synth_ai/data/traces.py +35 -0
- synth_ai/products/__init__.py +6 -0
- synth_ai/products/graph_evolve/__init__.py +46 -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/sdk/__init__.py +119 -0
- synth_ai/sdk/api/__init__.py +1 -0
- synth_ai/sdk/api/models/supported.py +514 -0
- synth_ai/sdk/api/research_agent/__init__.py +86 -0
- synth_ai/sdk/api/research_agent/cli.py +428 -0
- synth_ai/sdk/api/research_agent/config.py +357 -0
- synth_ai/sdk/api/research_agent/job.py +717 -0
- synth_ai/sdk/api/train/__init__.py +85 -0
- synth_ai/sdk/api/train/builders.py +895 -0
- synth_ai/sdk/api/train/cli.py +2188 -0
- synth_ai/sdk/api/train/config_finder.py +267 -0
- synth_ai/sdk/api/train/configs/__init__.py +65 -0
- synth_ai/sdk/api/train/configs/prompt_learning.py +1706 -0
- synth_ai/sdk/api/train/configs/rl.py +188 -0
- synth_ai/sdk/api/train/configs/sft.py +99 -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 +984 -0
- synth_ai/sdk/api/train/graphgen_models.py +823 -0
- synth_ai/sdk/api/train/graphgen_validators.py +109 -0
- synth_ai/sdk/api/train/pollers.py +124 -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 +470 -0
- synth_ai/sdk/api/train/rl.py +442 -0
- synth_ai/sdk/api/train/sft.py +396 -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 +331 -0
- synth_ai/sdk/api/train/utils.py +279 -0
- synth_ai/sdk/api/train/validators.py +2424 -0
- synth_ai/sdk/baseline/__init__.py +25 -0
- synth_ai/sdk/baseline/config.py +209 -0
- synth_ai/sdk/baseline/discovery.py +216 -0
- synth_ai/sdk/baseline/execution.py +154 -0
- synth_ai/sdk/graphs/__init__.py +15 -0
- synth_ai/sdk/graphs/completions.py +570 -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/judging/__init__.py +15 -0
- synth_ai/sdk/judging/base.py +24 -0
- synth_ai/sdk/judging/client.py +191 -0
- synth_ai/sdk/judging/schemas.py +222 -0
- synth_ai/sdk/learning/__init__.py +69 -0
- synth_ai/sdk/learning/client.py +240 -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 +185 -0
- synth_ai/sdk/learning/rl/client.py +268 -0
- synth_ai/sdk/learning/rl/contracts.py +27 -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/research_agent/__init__.py +34 -0
- synth_ai/sdk/research_agent/container_builder.py +328 -0
- synth_ai/sdk/research_agent/container_spec.py +198 -0
- synth_ai/sdk/research_agent/defaults.py +34 -0
- synth_ai/sdk/research_agent/results_collector.py +69 -0
- synth_ai/sdk/specs/__init__.py +46 -0
- synth_ai/sdk/specs/dataclasses.py +149 -0
- synth_ai/sdk/specs/loader.py +144 -0
- synth_ai/sdk/specs/serializer.py +199 -0
- synth_ai/sdk/specs/validation.py +250 -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 +704 -0
- synth_ai/sdk/streaming/types.py +112 -0
- synth_ai/sdk/task/__init__.py +151 -0
- synth_ai/sdk/task/apps/__init__.py +133 -0
- synth_ai/sdk/task/config.py +261 -0
- synth_ai/sdk/task/contracts.py +298 -0
- synth_ai/sdk/task/datasets.py +108 -0
- synth_ai/sdk/task/in_process.py +1190 -0
- synth_ai/sdk/task/in_process_runner.py +309 -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 +55 -0
- synth_ai/sdk/task/rubrics/loaders.py +156 -0
- synth_ai/sdk/task/rubrics.py +219 -0
- synth_ai/sdk/task/server.py +580 -0
- synth_ai/sdk/task/trace_correlation_helpers.py +506 -0
- synth_ai/sdk/task/tracing_utils.py +95 -0
- synth_ai/sdk/task/validators.py +456 -0
- synth_ai/sdk/tracing/__init__.py +39 -0
- synth_ai/sdk/training/__init__.py +102 -0
- synth_ai/sdk/usage/__init__.py +37 -0
- synth_ai/sdk/usage/client.py +171 -0
- synth_ai/sdk/usage/models.py +261 -0
- synth_ai/utils/__init__.py +213 -0
- synth_ai-0.4.1.dist-info/METADATA +195 -0
- synth_ai-0.4.1.dist-info/RECORD +379 -0
- synth_ai-0.4.1.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/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/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/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/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/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/config.toml +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/{evals ā sdk/judging}/types.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/__init__.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}/client.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}/rubrics/strict.py +0 -0
- /synth_ai/{task ā sdk/task}/vendors.py +0 -0
- {synth_ai-0.2.14.dist-info ā synth_ai-0.4.1.dist-info}/WHEEL +0 -0
- {synth_ai-0.2.14.dist-info ā synth_ai-0.4.1.dist-info}/entry_points.txt +0 -0
- {synth_ai-0.2.14.dist-info ā synth_ai-0.4.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,895 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import importlib
|
|
4
|
+
import os
|
|
5
|
+
from collections.abc import Callable
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Any, cast
|
|
9
|
+
|
|
10
|
+
import click
|
|
11
|
+
from pydantic import ValidationError
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
_models_module = cast(
|
|
15
|
+
Any, importlib.import_module("synth_ai.sdk.api.models.supported")
|
|
16
|
+
)
|
|
17
|
+
UnsupportedModelError = cast(type[Exception], _models_module.UnsupportedModelError)
|
|
18
|
+
ensure_allowed_model = cast(
|
|
19
|
+
Callable[..., None], _models_module.ensure_allowed_model
|
|
20
|
+
)
|
|
21
|
+
normalize_model_identifier = cast(
|
|
22
|
+
Callable[[str], str], _models_module.normalize_model_identifier
|
|
23
|
+
)
|
|
24
|
+
except Exception as exc: # pragma: no cover - critical dependency
|
|
25
|
+
raise RuntimeError("Unable to load supported model helpers") from exc
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
_sft_module = cast(
|
|
29
|
+
Any, importlib.import_module("synth_ai.sdk.learning.sft.config")
|
|
30
|
+
)
|
|
31
|
+
prepare_sft_job_payload = cast(
|
|
32
|
+
Callable[..., dict[str, Any]], _sft_module.prepare_sft_job_payload
|
|
33
|
+
)
|
|
34
|
+
except Exception as exc: # pragma: no cover - critical dependency
|
|
35
|
+
raise RuntimeError("Unable to load SFT payload helpers") from exc
|
|
36
|
+
|
|
37
|
+
from synth_ai.core.config.resolver import ConfigResolver
|
|
38
|
+
from synth_ai.core.telemetry import log_info
|
|
39
|
+
|
|
40
|
+
from .configs import PromptLearningConfig, RLConfig, SFTConfig
|
|
41
|
+
from .supported_algos import (
|
|
42
|
+
AlgorithmValidationError,
|
|
43
|
+
ensure_model_supported_for_algorithm,
|
|
44
|
+
validate_algorithm_config,
|
|
45
|
+
)
|
|
46
|
+
from .utils import TrainError, ensure_api_base
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@dataclass(slots=True)
|
|
50
|
+
class RLBuildResult:
|
|
51
|
+
payload: dict[str, Any]
|
|
52
|
+
task_url: str
|
|
53
|
+
idempotency: str | None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass(slots=True)
|
|
57
|
+
class SFTBuildResult:
|
|
58
|
+
payload: dict[str, Any]
|
|
59
|
+
train_file: Path
|
|
60
|
+
validation_file: Path | None
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass(slots=True)
|
|
64
|
+
class PromptLearningBuildResult:
|
|
65
|
+
payload: dict[str, Any]
|
|
66
|
+
task_url: str
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _format_validation_error(path: Path, exc: ValidationError) -> str:
|
|
70
|
+
lines: list[str] = []
|
|
71
|
+
for error in exc.errors():
|
|
72
|
+
loc = ".".join(str(part) for part in error.get("loc", ()))
|
|
73
|
+
msg = error.get("msg", "invalid value")
|
|
74
|
+
lines.append(f"{loc or '<root>'}: {msg}")
|
|
75
|
+
details = "\n".join(f" - {line}" for line in lines) or " - Invalid configuration"
|
|
76
|
+
return f"Config validation failed ({path}):\n{details}"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def build_rl_payload(
|
|
80
|
+
*,
|
|
81
|
+
config_path: Path,
|
|
82
|
+
task_url: str,
|
|
83
|
+
overrides: dict[str, Any],
|
|
84
|
+
idempotency: str | None,
|
|
85
|
+
allow_experimental: bool | None = None,
|
|
86
|
+
) -> RLBuildResult:
|
|
87
|
+
ctx: dict[str, Any] = {"config_path": str(config_path), "task_url": task_url}
|
|
88
|
+
log_info("build_rl_payload invoked", ctx=ctx)
|
|
89
|
+
# Load and validate config with SDK-level checks
|
|
90
|
+
from synth_ai.cli.commands.train.validation import validate_rl_config
|
|
91
|
+
from synth_ai.sdk.api.train.utils import load_toml
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
raw_config = load_toml(config_path)
|
|
95
|
+
validated_config = validate_rl_config(raw_config) # Adds defaults & validates
|
|
96
|
+
rl_cfg = RLConfig.from_mapping(validated_config)
|
|
97
|
+
except ValidationError as exc:
|
|
98
|
+
raise click.ClickException(_format_validation_error(config_path, exc)) from exc
|
|
99
|
+
|
|
100
|
+
data = rl_cfg.to_dict()
|
|
101
|
+
|
|
102
|
+
# Remove smoke section - it's CLI-only and should not be sent to the trainer
|
|
103
|
+
if "smoke" in data:
|
|
104
|
+
del data["smoke"]
|
|
105
|
+
|
|
106
|
+
# Ensure required [reference] section for backend validators
|
|
107
|
+
try:
|
|
108
|
+
ref_cfg = data.get("reference") if isinstance(data, dict) else None
|
|
109
|
+
if not isinstance(ref_cfg, dict):
|
|
110
|
+
data["reference"] = {"placement": "none"}
|
|
111
|
+
else:
|
|
112
|
+
ref_cfg.setdefault("placement", "none")
|
|
113
|
+
except Exception:
|
|
114
|
+
# Defensive: never fail builder due to optional defaults
|
|
115
|
+
data["reference"] = {"placement": "none"}
|
|
116
|
+
try:
|
|
117
|
+
spec = validate_algorithm_config(
|
|
118
|
+
rl_cfg.algorithm.model_dump(), expected_family="rl"
|
|
119
|
+
)
|
|
120
|
+
except AlgorithmValidationError as exc:
|
|
121
|
+
raise click.ClickException(str(exc)) from exc
|
|
122
|
+
services = data.get("services") if isinstance(data.get("services"), dict) else {}
|
|
123
|
+
model_cfg = rl_cfg.model
|
|
124
|
+
|
|
125
|
+
cli_task_url = overrides.get("task_url")
|
|
126
|
+
env_task_url = task_url or os.environ.get("TASK_APP_URL")
|
|
127
|
+
config_task_url = services.get("task_url") if isinstance(services, dict) else None
|
|
128
|
+
final_task_url = ConfigResolver.resolve(
|
|
129
|
+
"task_app_url",
|
|
130
|
+
cli_value=cli_task_url,
|
|
131
|
+
env_value=env_task_url,
|
|
132
|
+
config_value=config_task_url,
|
|
133
|
+
required=True,
|
|
134
|
+
)
|
|
135
|
+
assert final_task_url is not None # required=True guarantees non-None
|
|
136
|
+
|
|
137
|
+
model_source = (model_cfg.source or "").strip() if model_cfg else ""
|
|
138
|
+
model_base = (model_cfg.base or "").strip() if model_cfg else ""
|
|
139
|
+
override_model = (overrides.get("model") or "").strip()
|
|
140
|
+
if override_model:
|
|
141
|
+
model_source = override_model
|
|
142
|
+
model_base = ""
|
|
143
|
+
if bool(model_source) == bool(model_base):
|
|
144
|
+
details = (
|
|
145
|
+
f"Config: {config_path}\n"
|
|
146
|
+
f"[model].source={model_source!r} | [model].base={model_base!r}"
|
|
147
|
+
)
|
|
148
|
+
hint = (
|
|
149
|
+
"Set exactly one: [model].base for a base model (e.g. 'Qwen/Qwen3-1.7B') "
|
|
150
|
+
"or [model].source for a fine-tuned model id. Also remove any conflicting "
|
|
151
|
+
"'[policy].model' entries."
|
|
152
|
+
)
|
|
153
|
+
raise click.ClickException(
|
|
154
|
+
"Invalid model config: exactly one of [model].source or [model].base is required.\n"
|
|
155
|
+
+ details
|
|
156
|
+
+ "\nHint: "
|
|
157
|
+
+ hint
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
try:
|
|
161
|
+
if model_source:
|
|
162
|
+
model_source = normalize_model_identifier(model_source)
|
|
163
|
+
if model_base:
|
|
164
|
+
model_base = normalize_model_identifier(model_base)
|
|
165
|
+
except UnsupportedModelError as exc:
|
|
166
|
+
raise click.ClickException(str(exc)) from exc
|
|
167
|
+
|
|
168
|
+
base_model_for_training: str | None = None
|
|
169
|
+
if model_source:
|
|
170
|
+
base_model_for_training = ensure_allowed_model(
|
|
171
|
+
model_source,
|
|
172
|
+
allow_finetuned_prefixes=True,
|
|
173
|
+
allow_experimental=allow_experimental,
|
|
174
|
+
)
|
|
175
|
+
elif model_base:
|
|
176
|
+
base_model_for_training = ensure_allowed_model(
|
|
177
|
+
model_base,
|
|
178
|
+
allow_finetuned_prefixes=False,
|
|
179
|
+
allow_experimental=allow_experimental,
|
|
180
|
+
)
|
|
181
|
+
if base_model_for_training:
|
|
182
|
+
try:
|
|
183
|
+
ensure_model_supported_for_algorithm(base_model_for_training, spec)
|
|
184
|
+
except AlgorithmValidationError as exc:
|
|
185
|
+
raise click.ClickException(str(exc)) from exc
|
|
186
|
+
|
|
187
|
+
# Force TOML services.task_url to the effective endpoint to avoid split URLs
|
|
188
|
+
try:
|
|
189
|
+
if isinstance(data.get("services"), dict):
|
|
190
|
+
data["services"]["task_url"] = final_task_url
|
|
191
|
+
else:
|
|
192
|
+
data["services"] = {"task_url": final_task_url}
|
|
193
|
+
except Exception:
|
|
194
|
+
pass
|
|
195
|
+
|
|
196
|
+
payload_data: dict[str, Any] = {
|
|
197
|
+
"endpoint_base_url": final_task_url.rstrip("/"),
|
|
198
|
+
"config": data,
|
|
199
|
+
}
|
|
200
|
+
payload: dict[str, Any] = {
|
|
201
|
+
"job_type": "rl",
|
|
202
|
+
"compute": data.get("compute", {}),
|
|
203
|
+
"data": payload_data,
|
|
204
|
+
"tags": {"source": "train-cli"},
|
|
205
|
+
}
|
|
206
|
+
if model_source:
|
|
207
|
+
payload_data["model"] = model_source
|
|
208
|
+
if model_base:
|
|
209
|
+
payload_data["base_model"] = model_base
|
|
210
|
+
|
|
211
|
+
backend = overrides.get("backend")
|
|
212
|
+
if backend:
|
|
213
|
+
metadata_default: dict[str, Any] = {}
|
|
214
|
+
metadata = cast(dict[str, Any], payload.setdefault("metadata", metadata_default))
|
|
215
|
+
metadata["backend_base_url"] = ensure_api_base(str(backend))
|
|
216
|
+
|
|
217
|
+
return RLBuildResult(payload=payload, task_url=final_task_url, idempotency=idempotency)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def build_sft_payload(
|
|
221
|
+
*,
|
|
222
|
+
config_path: Path,
|
|
223
|
+
dataset_override: Path | None,
|
|
224
|
+
allow_experimental: bool | None,
|
|
225
|
+
) -> SFTBuildResult:
|
|
226
|
+
ctx: dict[str, Any] = {"config_path": str(config_path), "dataset_override": str(dataset_override) if dataset_override else None}
|
|
227
|
+
log_info("build_sft_payload invoked", ctx=ctx)
|
|
228
|
+
try:
|
|
229
|
+
sft_cfg = SFTConfig.from_path(config_path)
|
|
230
|
+
except ValidationError as exc:
|
|
231
|
+
raise TrainError(_format_validation_error(config_path, exc)) from exc
|
|
232
|
+
|
|
233
|
+
data = sft_cfg.to_dict()
|
|
234
|
+
try:
|
|
235
|
+
algo_mapping = sft_cfg.algorithm.model_dump() if sft_cfg.algorithm else None
|
|
236
|
+
spec = validate_algorithm_config(algo_mapping, expected_family="sft")
|
|
237
|
+
except AlgorithmValidationError as exc:
|
|
238
|
+
raise TrainError(str(exc)) from exc
|
|
239
|
+
data_cfg = data.get("data") if isinstance(data.get("data"), dict) else {}
|
|
240
|
+
hp_cfg = data.get("hyperparameters") if isinstance(data.get("hyperparameters"), dict) else {}
|
|
241
|
+
train_cfg = data.get("training") if isinstance(data.get("training"), dict) else {}
|
|
242
|
+
compute_cfg = data.get("compute") if isinstance(data.get("compute"), dict) else {}
|
|
243
|
+
|
|
244
|
+
raw_dataset = dataset_override or sft_cfg.job.data or sft_cfg.job.data_path
|
|
245
|
+
if not raw_dataset:
|
|
246
|
+
raise TrainError("Dataset not specified; pass --dataset or set [job].data")
|
|
247
|
+
dataset_path = Path(raw_dataset)
|
|
248
|
+
# Resolve relative paths from current working directory, not config directory
|
|
249
|
+
dataset_path = (
|
|
250
|
+
dataset_path if dataset_path.is_absolute() else (Path.cwd() / dataset_path)
|
|
251
|
+
).resolve()
|
|
252
|
+
if not dataset_path.exists():
|
|
253
|
+
raise TrainError(f"Dataset not found: {dataset_path}")
|
|
254
|
+
|
|
255
|
+
validation_path = (
|
|
256
|
+
data_cfg.get("validation_path")
|
|
257
|
+
if isinstance(data_cfg, dict)
|
|
258
|
+
else None
|
|
259
|
+
if isinstance(data_cfg, dict) and isinstance(data_cfg.get("validation_path"), str)
|
|
260
|
+
else None
|
|
261
|
+
)
|
|
262
|
+
validation_file = None
|
|
263
|
+
if validation_path:
|
|
264
|
+
vpath = Path(validation_path)
|
|
265
|
+
# Resolve relative paths from current working directory, not config directory
|
|
266
|
+
vpath = (vpath if vpath.is_absolute() else (Path.cwd() / vpath)).resolve()
|
|
267
|
+
if not vpath.exists():
|
|
268
|
+
click.echo(f"[WARN] Validation dataset {vpath} missing; continuing without validation")
|
|
269
|
+
else:
|
|
270
|
+
validation_file = vpath
|
|
271
|
+
|
|
272
|
+
hp_block: dict[str, Any] = {
|
|
273
|
+
"n_epochs": int(hp_cfg.get("n_epochs", 1) if isinstance(hp_cfg, dict) else 1),
|
|
274
|
+
}
|
|
275
|
+
for key in (
|
|
276
|
+
"batch_size",
|
|
277
|
+
"global_batch",
|
|
278
|
+
"per_device_batch",
|
|
279
|
+
"gradient_accumulation_steps",
|
|
280
|
+
"sequence_length",
|
|
281
|
+
"learning_rate",
|
|
282
|
+
"warmup_ratio",
|
|
283
|
+
"train_kind",
|
|
284
|
+
):
|
|
285
|
+
if isinstance(hp_cfg, dict) and key in hp_cfg:
|
|
286
|
+
hp_block[key] = hp_cfg[key]
|
|
287
|
+
if isinstance(hp_cfg, dict) and isinstance(hp_cfg.get("parallelism"), dict):
|
|
288
|
+
hp_block["parallelism"] = hp_cfg["parallelism"]
|
|
289
|
+
|
|
290
|
+
compute_block = {
|
|
291
|
+
k: compute_cfg[k]
|
|
292
|
+
for k in ("gpu_type", "gpu_count", "nodes")
|
|
293
|
+
if isinstance(compute_cfg, dict) and k in compute_cfg
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
effective = {
|
|
297
|
+
"compute": compute_block,
|
|
298
|
+
"data": {
|
|
299
|
+
"topology": data_cfg.get("topology", {})
|
|
300
|
+
if isinstance(data_cfg, dict) and isinstance(data_cfg.get("topology"), dict)
|
|
301
|
+
else {}
|
|
302
|
+
},
|
|
303
|
+
"training": {
|
|
304
|
+
k: v
|
|
305
|
+
for k, v in (train_cfg.items() if isinstance(train_cfg, dict) else [])
|
|
306
|
+
if k in ("mode", "use_qlora")
|
|
307
|
+
},
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
validation_cfg = (
|
|
311
|
+
train_cfg.get("validation")
|
|
312
|
+
if isinstance(train_cfg, dict) and isinstance(train_cfg.get("validation"), dict)
|
|
313
|
+
else None
|
|
314
|
+
)
|
|
315
|
+
if isinstance(validation_cfg, dict):
|
|
316
|
+
hp_block.update(
|
|
317
|
+
{
|
|
318
|
+
"evaluation_strategy": validation_cfg.get("evaluation_strategy", "steps"),
|
|
319
|
+
"eval_steps": int(validation_cfg.get("eval_steps", 0) or 0),
|
|
320
|
+
"save_best_model_at_end": bool(validation_cfg.get("save_best_model_at_end", True)),
|
|
321
|
+
"metric_for_best_model": validation_cfg.get("metric_for_best_model", "val.loss"),
|
|
322
|
+
"greater_is_better": bool(validation_cfg.get("greater_is_better", False)),
|
|
323
|
+
}
|
|
324
|
+
)
|
|
325
|
+
effective.setdefault("training", {})["validation"] = {
|
|
326
|
+
"enabled": bool(validation_cfg.get("enabled", True))
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
raw_model = (sft_cfg.job.model or "").strip()
|
|
330
|
+
if not raw_model:
|
|
331
|
+
model_block = data.get("model")
|
|
332
|
+
if isinstance(model_block, str):
|
|
333
|
+
raw_model = model_block.strip()
|
|
334
|
+
if not raw_model:
|
|
335
|
+
raise TrainError("Model not specified; set [job].model or [model].base in the config")
|
|
336
|
+
|
|
337
|
+
try:
|
|
338
|
+
base_model = ensure_allowed_model(
|
|
339
|
+
raw_model,
|
|
340
|
+
allow_finetuned_prefixes=False,
|
|
341
|
+
allow_experimental=allow_experimental,
|
|
342
|
+
)
|
|
343
|
+
except UnsupportedModelError as exc:
|
|
344
|
+
raise TrainError(str(exc)) from exc
|
|
345
|
+
|
|
346
|
+
if base_model:
|
|
347
|
+
try:
|
|
348
|
+
ensure_model_supported_for_algorithm(base_model, spec)
|
|
349
|
+
except AlgorithmValidationError as exc:
|
|
350
|
+
raise TrainError(str(exc)) from exc
|
|
351
|
+
|
|
352
|
+
try:
|
|
353
|
+
payload = prepare_sft_job_payload(
|
|
354
|
+
model=raw_model,
|
|
355
|
+
training_file=None,
|
|
356
|
+
hyperparameters=hp_block,
|
|
357
|
+
metadata={"effective_config": effective},
|
|
358
|
+
training_type="sft_offline",
|
|
359
|
+
training_file_field="training_file_id",
|
|
360
|
+
require_training_file=False,
|
|
361
|
+
include_training_file_when_none=True,
|
|
362
|
+
allow_finetuned_prefixes=False,
|
|
363
|
+
)
|
|
364
|
+
except UnsupportedModelError as exc:
|
|
365
|
+
raise TrainError(str(exc)) from exc
|
|
366
|
+
except ValueError as exc:
|
|
367
|
+
raise TrainError(str(exc)) from exc
|
|
368
|
+
|
|
369
|
+
return SFTBuildResult(payload=payload, train_file=dataset_path, validation_file=validation_file)
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def build_prompt_learning_payload(
|
|
373
|
+
*,
|
|
374
|
+
config_path: Path,
|
|
375
|
+
task_url: str | None,
|
|
376
|
+
overrides: dict[str, Any],
|
|
377
|
+
allow_experimental: bool | None = None,
|
|
378
|
+
) -> PromptLearningBuildResult:
|
|
379
|
+
"""Build payload for prompt learning job (MIPRO or GEPA)."""
|
|
380
|
+
ctx: dict[str, Any] = {"config_path": str(config_path), "task_url": task_url}
|
|
381
|
+
log_info("build_prompt_learning_payload invoked", ctx=ctx)
|
|
382
|
+
from pydantic import ValidationError
|
|
383
|
+
|
|
384
|
+
from .configs.prompt_learning import load_toml
|
|
385
|
+
|
|
386
|
+
# SDK-SIDE VALIDATION: Catch errors BEFORE sending to backend
|
|
387
|
+
from .validators import validate_prompt_learning_config
|
|
388
|
+
|
|
389
|
+
raw_config = load_toml(config_path)
|
|
390
|
+
validate_prompt_learning_config(raw_config, config_path)
|
|
391
|
+
|
|
392
|
+
try:
|
|
393
|
+
pl_cfg = PromptLearningConfig.from_path(config_path)
|
|
394
|
+
except ValidationError as exc:
|
|
395
|
+
raise click.ClickException(_format_validation_error(config_path, exc)) from exc
|
|
396
|
+
|
|
397
|
+
# Early validation: Check required fields for GEPA
|
|
398
|
+
if pl_cfg.algorithm == "gepa":
|
|
399
|
+
if not pl_cfg.gepa:
|
|
400
|
+
raise click.ClickException(
|
|
401
|
+
"GEPA config missing: [prompt_learning.gepa] section is required"
|
|
402
|
+
)
|
|
403
|
+
if not pl_cfg.gepa.evaluation:
|
|
404
|
+
raise click.ClickException(
|
|
405
|
+
"GEPA config missing: [prompt_learning.gepa.evaluation] section is required"
|
|
406
|
+
)
|
|
407
|
+
train_seeds = getattr(pl_cfg.gepa.evaluation, "train_seeds", None) or getattr(pl_cfg.gepa.evaluation, "seeds", None)
|
|
408
|
+
if not train_seeds:
|
|
409
|
+
raise click.ClickException(
|
|
410
|
+
"GEPA config missing train_seeds: [prompt_learning.gepa.evaluation] must have 'train_seeds' or 'seeds' field"
|
|
411
|
+
)
|
|
412
|
+
val_seeds = getattr(pl_cfg.gepa.evaluation, "val_seeds", None) or getattr(pl_cfg.gepa.evaluation, "validation_seeds", None)
|
|
413
|
+
if not val_seeds:
|
|
414
|
+
raise click.ClickException(
|
|
415
|
+
"GEPA config missing val_seeds: [prompt_learning.gepa.evaluation] must have 'val_seeds' or 'validation_seeds' field"
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
cli_task_url = overrides.get("task_url") or task_url
|
|
419
|
+
env_task_url = os.environ.get("TASK_APP_URL")
|
|
420
|
+
config_task_url = (pl_cfg.task_app_url or "").strip() or None
|
|
421
|
+
|
|
422
|
+
# For prompt learning, prefer config value over env if config is explicitly set
|
|
423
|
+
# This allows TOML files to specify task_app_url without env var interference
|
|
424
|
+
# But CLI override always wins
|
|
425
|
+
if cli_task_url:
|
|
426
|
+
# CLI override takes precedence
|
|
427
|
+
final_task_url = ConfigResolver.resolve(
|
|
428
|
+
"task_app_url",
|
|
429
|
+
cli_value=cli_task_url,
|
|
430
|
+
env_value=None, # Don't check env when CLI is set
|
|
431
|
+
config_value=config_task_url,
|
|
432
|
+
required=True,
|
|
433
|
+
)
|
|
434
|
+
elif config_task_url:
|
|
435
|
+
# Config explicitly set - use it (ignore env var to avoid conflicts)
|
|
436
|
+
final_task_url = config_task_url
|
|
437
|
+
else:
|
|
438
|
+
# No config, fall back to env or error
|
|
439
|
+
final_task_url = ConfigResolver.resolve(
|
|
440
|
+
"task_app_url",
|
|
441
|
+
cli_value=None,
|
|
442
|
+
env_value=env_task_url,
|
|
443
|
+
config_value=None,
|
|
444
|
+
required=True,
|
|
445
|
+
)
|
|
446
|
+
assert final_task_url is not None # required=True guarantees non-None
|
|
447
|
+
|
|
448
|
+
# Get task_app_api_key from config or environment
|
|
449
|
+
config_api_key = (pl_cfg.task_app_api_key or "").strip() or None
|
|
450
|
+
cli_api_key = overrides.get("task_app_api_key")
|
|
451
|
+
env_api_key = os.environ.get("ENVIRONMENT_API_KEY")
|
|
452
|
+
task_app_api_key = ConfigResolver.resolve(
|
|
453
|
+
"task_app_api_key",
|
|
454
|
+
cli_value=cli_api_key,
|
|
455
|
+
env_value=env_api_key,
|
|
456
|
+
config_value=config_api_key,
|
|
457
|
+
required=True,
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
# Build config dict for backend
|
|
461
|
+
config_dict = pl_cfg.to_dict()
|
|
462
|
+
|
|
463
|
+
# ASSERT: MIPRO fields exist in Pydantic model
|
|
464
|
+
if pl_cfg.algorithm == "mipro":
|
|
465
|
+
assert pl_cfg.mipro is not None, "pl_cfg.mipro is None for MIPRO algorithm"
|
|
466
|
+
bootstrap_in_model = getattr(pl_cfg.mipro, "bootstrap_train_seeds", None)
|
|
467
|
+
online_in_model = getattr(pl_cfg.mipro, "online_pool", None)
|
|
468
|
+
assert bootstrap_in_model is not None, f"pl_cfg.mipro.bootstrap_train_seeds is None! pl_cfg.mipro keys: {dir(pl_cfg.mipro) if pl_cfg.mipro else 'N/A'}"
|
|
469
|
+
assert online_in_model is not None, f"pl_cfg.mipro.online_pool is None! pl_cfg.mipro keys: {dir(pl_cfg.mipro) if pl_cfg.mipro else 'N/A'}"
|
|
470
|
+
|
|
471
|
+
# Ensure task_app_url and task_app_api_key are set
|
|
472
|
+
pl_section = config_dict.get("prompt_learning", {})
|
|
473
|
+
if isinstance(pl_section, dict):
|
|
474
|
+
pl_section["task_app_url"] = final_task_url
|
|
475
|
+
pl_section["task_app_api_key"] = task_app_api_key
|
|
476
|
+
|
|
477
|
+
# GEPA: Extract train_seeds from nested structure for backwards compatibility
|
|
478
|
+
# Backend checks for train_seeds at top level before parsing nested structure
|
|
479
|
+
if pl_cfg.algorithm == "gepa" and pl_cfg.gepa:
|
|
480
|
+
# Try to get train_seeds directly from the gepa config object first
|
|
481
|
+
train_seeds = None
|
|
482
|
+
if pl_cfg.gepa.evaluation:
|
|
483
|
+
train_seeds = getattr(pl_cfg.gepa.evaluation, "train_seeds", None) or getattr(pl_cfg.gepa.evaluation, "seeds", None)
|
|
484
|
+
|
|
485
|
+
# If not found, try from serialized dict
|
|
486
|
+
if not train_seeds:
|
|
487
|
+
gepa_section = pl_section.get("gepa", {})
|
|
488
|
+
# Handle case where gepa_section might still be a Pydantic model
|
|
489
|
+
if hasattr(gepa_section, "model_dump"):
|
|
490
|
+
gepa_section = gepa_section.model_dump(mode="python")
|
|
491
|
+
elif hasattr(gepa_section, "dict"):
|
|
492
|
+
gepa_section = gepa_section.dict()
|
|
493
|
+
|
|
494
|
+
if isinstance(gepa_section, dict):
|
|
495
|
+
eval_section = gepa_section.get("evaluation", {})
|
|
496
|
+
# Handle case where eval_section might still be a Pydantic model
|
|
497
|
+
if hasattr(eval_section, "model_dump"):
|
|
498
|
+
eval_section = eval_section.model_dump(mode="python")
|
|
499
|
+
elif hasattr(eval_section, "dict"):
|
|
500
|
+
eval_section = eval_section.dict()
|
|
501
|
+
|
|
502
|
+
if isinstance(eval_section, dict):
|
|
503
|
+
train_seeds = eval_section.get("train_seeds") or eval_section.get("seeds")
|
|
504
|
+
|
|
505
|
+
# Update gepa_section back to pl_section in case we converted it
|
|
506
|
+
pl_section["gepa"] = gepa_section
|
|
507
|
+
|
|
508
|
+
# Add train_seeds to top level for backwards compatibility
|
|
509
|
+
if train_seeds and not pl_section.get("train_seeds"):
|
|
510
|
+
pl_section["train_seeds"] = train_seeds
|
|
511
|
+
if train_seeds and not pl_section.get("evaluation_seeds"):
|
|
512
|
+
pl_section["evaluation_seeds"] = train_seeds
|
|
513
|
+
|
|
514
|
+
# MIPRO: CRITICAL - Ensure bootstrap_train_seeds and online_pool are ALWAYS in mipro section
|
|
515
|
+
# Handle Pydantic model serialization - mipro might be a model object, not a dict
|
|
516
|
+
if pl_cfg.algorithm == "mipro":
|
|
517
|
+
mipro_section = pl_section.get("mipro", {})
|
|
518
|
+
|
|
519
|
+
# ASSERT: Check what we got from to_dict()
|
|
520
|
+
assert pl_cfg.mipro is not None, "pl_cfg.mipro is None"
|
|
521
|
+
bootstrap_before_convert = getattr(pl_cfg.mipro, "bootstrap_train_seeds", None)
|
|
522
|
+
online_before_convert = getattr(pl_cfg.mipro, "online_pool", None)
|
|
523
|
+
assert bootstrap_before_convert is not None, f"bootstrap_train_seeds is None in model! mipro_section type: {type(mipro_section)}, keys: {list(mipro_section.keys()) if isinstance(mipro_section, dict) else 'N/A'}"
|
|
524
|
+
assert online_before_convert is not None, f"online_pool is None in model! mipro_section type: {type(mipro_section)}, keys: {list(mipro_section.keys()) if isinstance(mipro_section, dict) else 'N/A'}"
|
|
525
|
+
|
|
526
|
+
# Convert Pydantic model to dict if needed
|
|
527
|
+
if hasattr(mipro_section, "model_dump"):
|
|
528
|
+
mipro_section = mipro_section.model_dump(mode="python")
|
|
529
|
+
elif hasattr(mipro_section, "dict"):
|
|
530
|
+
mipro_section = mipro_section.dict()
|
|
531
|
+
|
|
532
|
+
if not isinstance(mipro_section, dict):
|
|
533
|
+
mipro_section = {}
|
|
534
|
+
|
|
535
|
+
# ASSERT: After conversion, check if fields are present
|
|
536
|
+
bootstrap_after_convert = mipro_section.get("bootstrap_train_seeds")
|
|
537
|
+
online_after_convert = mipro_section.get("online_pool")
|
|
538
|
+
if bootstrap_after_convert is None:
|
|
539
|
+
raise AssertionError(f"bootstrap_train_seeds missing after conversion! mipro_section keys: {list(mipro_section.keys())}, bootstrap_before_convert: {bootstrap_before_convert}")
|
|
540
|
+
if online_after_convert is None:
|
|
541
|
+
raise AssertionError(f"online_pool missing after conversion! mipro_section keys: {list(mipro_section.keys())}, online_before_convert: {online_before_convert}")
|
|
542
|
+
|
|
543
|
+
# CRITICAL: Get fields from Pydantic model FIRST (most reliable)
|
|
544
|
+
# These fields MUST be present - get them from the source of truth
|
|
545
|
+
if not pl_cfg.mipro:
|
|
546
|
+
raise ValueError(
|
|
547
|
+
"MIPRO config missing: pl_cfg.mipro is None. "
|
|
548
|
+
"Ensure [prompt_learning.mipro] section exists in TOML."
|
|
549
|
+
)
|
|
550
|
+
|
|
551
|
+
bootstrap_from_model = getattr(pl_cfg.mipro, "bootstrap_train_seeds", None)
|
|
552
|
+
online_from_model = getattr(pl_cfg.mipro, "online_pool", None)
|
|
553
|
+
test_from_model = getattr(pl_cfg.mipro, "test_pool", None)
|
|
554
|
+
reference_from_model = getattr(pl_cfg.mipro, "reference_pool", None)
|
|
555
|
+
|
|
556
|
+
# FORCE these fields into mipro_section (model is source of truth)
|
|
557
|
+
# Use model values if present, otherwise keep existing dict values
|
|
558
|
+
assert bootstrap_from_model is not None, f"bootstrap_from_model is None! pl_cfg.mipro: {pl_cfg.mipro}"
|
|
559
|
+
assert online_from_model is not None, f"online_from_model is None! pl_cfg.mipro: {pl_cfg.mipro}"
|
|
560
|
+
|
|
561
|
+
mipro_section["bootstrap_train_seeds"] = bootstrap_from_model
|
|
562
|
+
mipro_section["online_pool"] = online_from_model
|
|
563
|
+
|
|
564
|
+
if test_from_model is not None:
|
|
565
|
+
mipro_section["test_pool"] = test_from_model
|
|
566
|
+
elif not mipro_section.get("test_pool") and pl_section.get("test_pool"):
|
|
567
|
+
mipro_section["test_pool"] = pl_section["test_pool"]
|
|
568
|
+
|
|
569
|
+
if reference_from_model is not None:
|
|
570
|
+
mipro_section["reference_pool"] = reference_from_model
|
|
571
|
+
elif not mipro_section.get("reference_pool") and pl_section.get("reference_pool"):
|
|
572
|
+
mipro_section["reference_pool"] = pl_section["reference_pool"]
|
|
573
|
+
|
|
574
|
+
# ASSERT: Fields are now in mipro_section
|
|
575
|
+
assert mipro_section.get("bootstrap_train_seeds") is not None, f"bootstrap_train_seeds STILL missing after forcing! mipro_section keys: {list(mipro_section.keys())}"
|
|
576
|
+
assert mipro_section.get("online_pool") is not None, f"online_pool STILL missing after forcing! mipro_section keys: {list(mipro_section.keys())}"
|
|
577
|
+
|
|
578
|
+
# CRITICAL: Validate fields are present BEFORE override merge
|
|
579
|
+
# If they're missing here, we'll check overrides after they're extracted
|
|
580
|
+
# For now, just ensure they're in mipro_section from TOML
|
|
581
|
+
if not mipro_section.get("bootstrap_train_seeds") and bootstrap_from_model is None:
|
|
582
|
+
raise ValueError(
|
|
583
|
+
f"MIPRO config missing bootstrap_train_seeds in TOML. "
|
|
584
|
+
f"pl_cfg.mipro.bootstrap_train_seeds={bootstrap_from_model}, "
|
|
585
|
+
f"mipro_section keys={list(mipro_section.keys())}, "
|
|
586
|
+
f"pl_section keys={list(pl_section.keys())[:10]}. "
|
|
587
|
+
f"Ensure [prompt_learning.mipro] has bootstrap_train_seeds or provide override."
|
|
588
|
+
)
|
|
589
|
+
if not mipro_section.get("online_pool") and online_from_model is None:
|
|
590
|
+
raise ValueError(
|
|
591
|
+
f"MIPRO config missing online_pool in TOML. "
|
|
592
|
+
f"pl_cfg.mipro.online_pool={online_from_model}, "
|
|
593
|
+
f"mipro_section keys={list(mipro_section.keys())}, "
|
|
594
|
+
f"pl_section keys={list(pl_section.keys())[:10]}. "
|
|
595
|
+
f"Ensure [prompt_learning.mipro] has online_pool or provide override."
|
|
596
|
+
)
|
|
597
|
+
|
|
598
|
+
# Extract env_name from mipro section to top-level (backend expects it there)
|
|
599
|
+
mipro_env_name = mipro_section.get("env_name")
|
|
600
|
+
if mipro_env_name and not pl_section.get("env_name") and not pl_section.get("task_app_id"):
|
|
601
|
+
pl_section["env_name"] = mipro_env_name
|
|
602
|
+
|
|
603
|
+
# CRITICAL: Update mipro section back to config_dict IMMEDIATELY
|
|
604
|
+
# This ensures fields are present before override merge
|
|
605
|
+
pl_section["mipro"] = mipro_section
|
|
606
|
+
config_dict["prompt_learning"] = pl_section
|
|
607
|
+
|
|
608
|
+
# ASSERT: Fields are in config_dict before override merge
|
|
609
|
+
assert config_dict.get("prompt_learning", {}).get("mipro", {}).get("bootstrap_train_seeds") is not None, \
|
|
610
|
+
f"bootstrap_train_seeds missing from config_dict before override merge! config_dict keys: {list(config_dict.keys())}"
|
|
611
|
+
assert config_dict.get("prompt_learning", {}).get("mipro", {}).get("online_pool") is not None, \
|
|
612
|
+
f"online_pool missing from config_dict before override merge! config_dict keys: {list(config_dict.keys())}"
|
|
613
|
+
else:
|
|
614
|
+
config_dict["prompt_learning"] = {
|
|
615
|
+
"task_app_url": final_task_url,
|
|
616
|
+
"task_app_api_key": task_app_api_key,
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
# Build payload matching backend API format
|
|
620
|
+
# Extract nested overrides if present, otherwise use flat overrides directly
|
|
621
|
+
# The experiment queue passes flat overrides like {"prompt_learning.policy.model": "..."}
|
|
622
|
+
# But some SDK code passes nested like {"overrides": {"prompt_learning.policy.model": "..."}}
|
|
623
|
+
config_overrides = overrides.get("overrides", {}) if "overrides" in overrides else overrides
|
|
624
|
+
# Remove non-override keys (backend, task_url, metadata, auto_start)
|
|
625
|
+
config_overrides = {
|
|
626
|
+
k: v for k, v in config_overrides.items()
|
|
627
|
+
if k not in ("backend", "task_url", "metadata", "auto_start")
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
# ASSERT: Check MIPRO fields BEFORE override merge
|
|
631
|
+
if pl_cfg.algorithm == "mipro":
|
|
632
|
+
pre_merge_mipro = config_dict.get("prompt_learning", {}).get("mipro", {})
|
|
633
|
+
assert pre_merge_mipro.get("bootstrap_train_seeds") is not None, \
|
|
634
|
+
f"bootstrap_train_seeds missing BEFORE override merge! pre_merge_mipro keys: {list(pre_merge_mipro.keys()) if isinstance(pre_merge_mipro, dict) else 'NOT DICT'}"
|
|
635
|
+
assert pre_merge_mipro.get("online_pool") is not None, \
|
|
636
|
+
f"online_pool missing BEFORE override merge! pre_merge_mipro keys: {list(pre_merge_mipro.keys()) if isinstance(pre_merge_mipro, dict) else 'NOT DICT'}"
|
|
637
|
+
|
|
638
|
+
# CRITICAL: Merge overrides into config_dict BEFORE sending to backend
|
|
639
|
+
# This ensures early validation in backend sees merged values
|
|
640
|
+
# Use the same _deep_update logic from experiment_queue/config_utils.py
|
|
641
|
+
if config_overrides:
|
|
642
|
+
from synth_ai.cli.local.experiment_queue.config_utils import _deep_update
|
|
643
|
+
_deep_update(config_dict, config_overrides)
|
|
644
|
+
|
|
645
|
+
# ASSERT: Check MIPRO fields AFTER override merge
|
|
646
|
+
if pl_cfg.algorithm == "mipro":
|
|
647
|
+
post_merge_mipro = config_dict.get("prompt_learning", {}).get("mipro", {})
|
|
648
|
+
assert post_merge_mipro.get("bootstrap_train_seeds") is not None, \
|
|
649
|
+
f"bootstrap_train_seeds missing AFTER override merge! post_merge_mipro keys: {list(post_merge_mipro.keys()) if isinstance(post_merge_mipro, dict) else 'NOT DICT'}, overrides: {list(config_overrides.keys())[:5]}"
|
|
650
|
+
assert post_merge_mipro.get("online_pool") is not None, \
|
|
651
|
+
f"online_pool missing AFTER override merge! post_merge_mipro keys: {list(post_merge_mipro.keys()) if isinstance(post_merge_mipro, dict) else 'NOT DICT'}, overrides: {list(config_overrides.keys())[:5]}"
|
|
652
|
+
|
|
653
|
+
# After merging overrides (or if no overrides), re-run MIPRO reorganization to ensure
|
|
654
|
+
# fields like bootstrap_train_seeds and online_pool are in the right place
|
|
655
|
+
# This must run AFTER override merge so we catch fields from overrides
|
|
656
|
+
pl_section_in_dict = config_dict.get("prompt_learning", {})
|
|
657
|
+
if pl_cfg.algorithm == "mipro" and isinstance(pl_section_in_dict, dict):
|
|
658
|
+
mipro_section = pl_section_in_dict.get("mipro", {})
|
|
659
|
+
if not isinstance(mipro_section, dict):
|
|
660
|
+
mipro_section = {}
|
|
661
|
+
|
|
662
|
+
# CRITICAL: After override merge, ensure fields are in mipro section
|
|
663
|
+
# Check both top-level and nested locations (overrides may have added them anywhere)
|
|
664
|
+
if not mipro_section.get("bootstrap_train_seeds") and pl_section_in_dict.get("bootstrap_train_seeds"):
|
|
665
|
+
mipro_section["bootstrap_train_seeds"] = pl_section_in_dict["bootstrap_train_seeds"]
|
|
666
|
+
|
|
667
|
+
if not mipro_section.get("online_pool") and pl_section_in_dict.get("online_pool"):
|
|
668
|
+
mipro_section["online_pool"] = pl_section_in_dict["online_pool"]
|
|
669
|
+
|
|
670
|
+
if not mipro_section.get("test_pool") and pl_section_in_dict.get("test_pool"):
|
|
671
|
+
mipro_section["test_pool"] = pl_section_in_dict["test_pool"]
|
|
672
|
+
|
|
673
|
+
if not mipro_section.get("reference_pool") and pl_section_in_dict.get("reference_pool"):
|
|
674
|
+
mipro_section["reference_pool"] = pl_section_in_dict["reference_pool"]
|
|
675
|
+
|
|
676
|
+
# ASSERT: Fields should be in mipro_section after reorganization
|
|
677
|
+
assert mipro_section.get("bootstrap_train_seeds") is not None, \
|
|
678
|
+
f"bootstrap_train_seeds missing after reorganization! mipro_section keys: {list(mipro_section.keys())}, pl_section keys: {list(pl_section_in_dict.keys())[:10]}"
|
|
679
|
+
assert mipro_section.get("online_pool") is not None, \
|
|
680
|
+
f"online_pool missing after reorganization! mipro_section keys: {list(mipro_section.keys())}, pl_section keys: {list(pl_section_in_dict.keys())[:10]}"
|
|
681
|
+
|
|
682
|
+
# Update mipro section back to config_dict
|
|
683
|
+
pl_section_in_dict["mipro"] = mipro_section
|
|
684
|
+
config_dict["prompt_learning"] = pl_section_in_dict
|
|
685
|
+
|
|
686
|
+
# ASSERT: Fields are in config_dict after reorganization
|
|
687
|
+
assert config_dict.get("prompt_learning", {}).get("mipro", {}).get("bootstrap_train_seeds") is not None, \
|
|
688
|
+
"bootstrap_train_seeds missing from config_dict after reorganization!"
|
|
689
|
+
assert config_dict.get("prompt_learning", {}).get("mipro", {}).get("online_pool") is not None, \
|
|
690
|
+
"online_pool missing from config_dict after reorganization!"
|
|
691
|
+
|
|
692
|
+
# CRITICAL: Verify MIPRO required fields are present after merge
|
|
693
|
+
# This is the final check before sending to backend (runs whether or not overrides were applied)
|
|
694
|
+
final_mipro_section = pl_section_in_dict.get("mipro", {})
|
|
695
|
+
|
|
696
|
+
# DEBUG: Log what we found for troubleshooting
|
|
697
|
+
bootstrap_seeds = final_mipro_section.get("bootstrap_train_seeds")
|
|
698
|
+
online_pool_val = final_mipro_section.get("online_pool")
|
|
699
|
+
|
|
700
|
+
if not bootstrap_seeds or not online_pool_val:
|
|
701
|
+
# Log debug info before raising error
|
|
702
|
+
import logging
|
|
703
|
+
logger = logging.getLogger(__name__)
|
|
704
|
+
logger.error(
|
|
705
|
+
"MIPRO config validation failed:\n"
|
|
706
|
+
f" bootstrap_train_seeds in mipro section: {bootstrap_seeds is not None}\n"
|
|
707
|
+
f" online_pool in mipro section: {online_pool_val is not None}\n"
|
|
708
|
+
f" mipro_section keys: {list(final_mipro_section.keys()) if isinstance(final_mipro_section, dict) else 'NOT A DICT'}\n"
|
|
709
|
+
f" pl_section keys: {list(pl_section_in_dict.keys()) if isinstance(pl_section_in_dict, dict) else 'NOT A DICT'}\n"
|
|
710
|
+
f" config_overrides keys: {list(config_overrides.keys()) if config_overrides else 'NO OVERRIDES'}"
|
|
711
|
+
)
|
|
712
|
+
|
|
713
|
+
if not bootstrap_seeds:
|
|
714
|
+
raise ValueError(
|
|
715
|
+
"MIPRO config missing bootstrap_train_seeds after applying overrides. "
|
|
716
|
+
"Ensure it's set in TOML at [prompt_learning.mipro] or [prompt_learning] level, "
|
|
717
|
+
"or provided via override 'prompt_learning.mipro.bootstrap_train_seeds'. "
|
|
718
|
+
f"Current mipro_section keys: {list(final_mipro_section.keys()) if isinstance(final_mipro_section, dict) else 'NOT A DICT'}"
|
|
719
|
+
)
|
|
720
|
+
if not online_pool_val:
|
|
721
|
+
raise ValueError(
|
|
722
|
+
"MIPRO config missing online_pool after applying overrides. "
|
|
723
|
+
"Ensure it's set in TOML at [prompt_learning.mipro] or [prompt_learning] level, "
|
|
724
|
+
"or provided via override 'prompt_learning.mipro.online_pool'. "
|
|
725
|
+
f"Current mipro_section keys: {list(final_mipro_section.keys()) if isinstance(final_mipro_section, dict) else 'NOT A DICT'}"
|
|
726
|
+
)
|
|
727
|
+
|
|
728
|
+
# CRITICAL: Final validation - ensure MIPRO fields are in config_body before sending
|
|
729
|
+
pl_section_final = config_dict.get("prompt_learning", {})
|
|
730
|
+
if pl_cfg.algorithm == "mipro":
|
|
731
|
+
mipro_final = pl_section_final.get("mipro", {})
|
|
732
|
+
if not isinstance(mipro_final, dict):
|
|
733
|
+
mipro_final = {}
|
|
734
|
+
|
|
735
|
+
# If fields are still missing, FORCE them from the Pydantic model one last time
|
|
736
|
+
if pl_cfg.mipro:
|
|
737
|
+
if not mipro_final.get("bootstrap_train_seeds"):
|
|
738
|
+
bootstrap_val = getattr(pl_cfg.mipro, "bootstrap_train_seeds", None)
|
|
739
|
+
if bootstrap_val is not None:
|
|
740
|
+
mipro_final["bootstrap_train_seeds"] = bootstrap_val
|
|
741
|
+
|
|
742
|
+
if not mipro_final.get("online_pool"):
|
|
743
|
+
online_val = getattr(pl_cfg.mipro, "online_pool", None)
|
|
744
|
+
if online_val is not None:
|
|
745
|
+
mipro_final["online_pool"] = online_val
|
|
746
|
+
|
|
747
|
+
if not mipro_final.get("test_pool"):
|
|
748
|
+
test_val = getattr(pl_cfg.mipro, "test_pool", None)
|
|
749
|
+
if test_val is not None:
|
|
750
|
+
mipro_final["test_pool"] = test_val
|
|
751
|
+
|
|
752
|
+
if not mipro_final.get("reference_pool"):
|
|
753
|
+
ref_val = getattr(pl_cfg.mipro, "reference_pool", None)
|
|
754
|
+
if ref_val is not None:
|
|
755
|
+
mipro_final["reference_pool"] = ref_val
|
|
756
|
+
|
|
757
|
+
# Update back to config_dict
|
|
758
|
+
pl_section_final["mipro"] = mipro_final
|
|
759
|
+
config_dict["prompt_learning"] = pl_section_final
|
|
760
|
+
|
|
761
|
+
# ASSERT: Fields are in config_dict after final check
|
|
762
|
+
assert config_dict.get("prompt_learning", {}).get("mipro", {}).get("bootstrap_train_seeds") is not None, \
|
|
763
|
+
f"bootstrap_train_seeds missing from config_dict after final check! mipro_final keys: {list(mipro_final.keys())}"
|
|
764
|
+
assert config_dict.get("prompt_learning", {}).get("mipro", {}).get("online_pool") is not None, \
|
|
765
|
+
f"online_pool missing from config_dict after final check! mipro_final keys: {list(mipro_final.keys())}"
|
|
766
|
+
|
|
767
|
+
# FINAL ASSERTION: These fields MUST be present
|
|
768
|
+
assert mipro_final.get("bootstrap_train_seeds") is not None, \
|
|
769
|
+
f"CRITICAL: bootstrap_train_seeds missing from config_body! mipro_final keys: {list(mipro_final.keys())}, pl_cfg.mipro.bootstrap_train_seeds: {getattr(pl_cfg.mipro, 'bootstrap_train_seeds', None) if pl_cfg.mipro else 'N/A'}"
|
|
770
|
+
assert mipro_final.get("online_pool") is not None, \
|
|
771
|
+
f"CRITICAL: online_pool missing from config_body! mipro_final keys: {list(mipro_final.keys())}, pl_cfg.mipro.online_pool: {getattr(pl_cfg.mipro, 'online_pool', None) if pl_cfg.mipro else 'N/A'}"
|
|
772
|
+
|
|
773
|
+
# ASSERT: Verify critical overrides are reflected in config_body
|
|
774
|
+
pl_section_in_dict = config_dict.get("prompt_learning", {})
|
|
775
|
+
if config_overrides:
|
|
776
|
+
# Check rollout budget override
|
|
777
|
+
rollout_budget_key = "prompt_learning.gepa.rollout.budget"
|
|
778
|
+
if rollout_budget_key in config_overrides:
|
|
779
|
+
expected_budget = config_overrides[rollout_budget_key]
|
|
780
|
+
gepa_section = pl_section_in_dict.get("gepa", {})
|
|
781
|
+
actual_budget = gepa_section.get("rollout", {}).get("budget") if isinstance(gepa_section, dict) else None
|
|
782
|
+
if actual_budget is not None:
|
|
783
|
+
assert actual_budget == expected_budget, (
|
|
784
|
+
f"Rollout budget mismatch: config_body has {actual_budget} but override specifies {expected_budget}. "
|
|
785
|
+
f"This indicates the override wasn't applied correctly."
|
|
786
|
+
)
|
|
787
|
+
|
|
788
|
+
# Check model override
|
|
789
|
+
model_key = "prompt_learning.policy.model"
|
|
790
|
+
if model_key in config_overrides:
|
|
791
|
+
expected_model = config_overrides[model_key]
|
|
792
|
+
policy_section = pl_section_in_dict.get("policy", {})
|
|
793
|
+
actual_model = policy_section.get("model") if isinstance(policy_section, dict) else None
|
|
794
|
+
if actual_model is not None:
|
|
795
|
+
assert actual_model == expected_model, (
|
|
796
|
+
f"Model mismatch: config_body has {actual_model} but override specifies {expected_model}. "
|
|
797
|
+
f"This indicates the override wasn't applied correctly."
|
|
798
|
+
)
|
|
799
|
+
|
|
800
|
+
# Check provider override
|
|
801
|
+
provider_key = "prompt_learning.policy.provider"
|
|
802
|
+
if provider_key in config_overrides:
|
|
803
|
+
expected_provider = config_overrides[provider_key]
|
|
804
|
+
policy_section = pl_section_in_dict.get("policy", {})
|
|
805
|
+
actual_provider = policy_section.get("provider") if isinstance(policy_section, dict) else None
|
|
806
|
+
if actual_provider is not None:
|
|
807
|
+
assert actual_provider == expected_provider, (
|
|
808
|
+
f"Provider mismatch: config_body has {actual_provider} but override specifies {expected_provider}. "
|
|
809
|
+
f"This indicates the override wasn't applied correctly."
|
|
810
|
+
)
|
|
811
|
+
|
|
812
|
+
# FINAL CHECK: Ensure config_body has correct structure for backend
|
|
813
|
+
# Backend expects: {"prompt_learning": {...}} (full TOML structure)
|
|
814
|
+
if "prompt_learning" not in config_dict:
|
|
815
|
+
raise ValueError(
|
|
816
|
+
"config_dict must have 'prompt_learning' key. "
|
|
817
|
+
f"Found keys: {list(config_dict.keys())}"
|
|
818
|
+
)
|
|
819
|
+
|
|
820
|
+
# CRITICAL: Final validation - check MIPRO fields are in config_body before sending
|
|
821
|
+
if pl_cfg.algorithm == "mipro":
|
|
822
|
+
pl_section_final = config_dict.get("prompt_learning", {})
|
|
823
|
+
mipro_section_final = pl_section_final.get("mipro", {}) if isinstance(pl_section_final, dict) else {}
|
|
824
|
+
|
|
825
|
+
# ASSERT: Fields MUST be present before building payload
|
|
826
|
+
assert mipro_section_final.get("bootstrap_train_seeds") is not None, \
|
|
827
|
+
f"CRITICAL ASSERTION FAILED: bootstrap_train_seeds missing from config_body before sending to backend! " \
|
|
828
|
+
f"mipro_section keys: {list(mipro_section_final.keys()) if isinstance(mipro_section_final, dict) else 'NOT A DICT'}, " \
|
|
829
|
+
f"pl_section keys: {list(pl_section_final.keys()) if isinstance(pl_section_final, dict) else 'NOT A DICT'}, " \
|
|
830
|
+
f"pl_cfg.mipro.bootstrap_train_seeds: {getattr(pl_cfg.mipro, 'bootstrap_train_seeds', None) if pl_cfg.mipro else 'N/A'}"
|
|
831
|
+
assert mipro_section_final.get("online_pool") is not None, \
|
|
832
|
+
f"CRITICAL ASSERTION FAILED: online_pool missing from config_body before sending to backend! " \
|
|
833
|
+
f"mipro_section keys: {list(mipro_section_final.keys()) if isinstance(mipro_section_final, dict) else 'NOT A DICT'}, " \
|
|
834
|
+
f"pl_section keys: {list(pl_section_final.keys()) if isinstance(pl_section_final, dict) else 'NOT A DICT'}, " \
|
|
835
|
+
f"pl_cfg.mipro.online_pool: {getattr(pl_cfg.mipro, 'online_pool', None) if pl_cfg.mipro else 'N/A'}"
|
|
836
|
+
|
|
837
|
+
if not mipro_section_final.get("bootstrap_train_seeds"):
|
|
838
|
+
import json
|
|
839
|
+
raise ValueError(
|
|
840
|
+
"CRITICAL: bootstrap_train_seeds missing from config_body before sending to backend. "
|
|
841
|
+
f"mipro_section keys: {list(mipro_section_final.keys()) if isinstance(mipro_section_final, dict) else 'NOT A DICT'}, "
|
|
842
|
+
f"pl_section keys: {list(pl_section_final.keys()) if isinstance(pl_section_final, dict) else 'NOT A DICT'}, "
|
|
843
|
+
f"config_overrides: {json.dumps(list(config_overrides.keys()) if config_overrides else [])}"
|
|
844
|
+
)
|
|
845
|
+
if not mipro_section_final.get("online_pool"):
|
|
846
|
+
import json
|
|
847
|
+
raise ValueError(
|
|
848
|
+
"CRITICAL: online_pool missing from config_body before sending to backend. "
|
|
849
|
+
f"mipro_section keys: {list(mipro_section_final.keys()) if isinstance(mipro_section_final, dict) else 'NOT A DICT'}, "
|
|
850
|
+
f"pl_section keys: {list(pl_section_final.keys()) if isinstance(pl_section_final, dict) else 'NOT A DICT'}, "
|
|
851
|
+
f"config_overrides: {json.dumps(list(config_overrides.keys()) if config_overrides else [])}"
|
|
852
|
+
)
|
|
853
|
+
|
|
854
|
+
payload: dict[str, Any] = {
|
|
855
|
+
"algorithm": pl_cfg.algorithm,
|
|
856
|
+
"config_body": config_dict,
|
|
857
|
+
"overrides": config_overrides,
|
|
858
|
+
"metadata": overrides.get("metadata", {}),
|
|
859
|
+
"auto_start": overrides.get("auto_start", True),
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
# CRITICAL DEBUG: Print MIPRO section structure before sending
|
|
863
|
+
if pl_cfg.algorithm == "mipro":
|
|
864
|
+
import json
|
|
865
|
+
mipro_debug = config_dict.get("prompt_learning", {}).get("mipro", {})
|
|
866
|
+
print("\nš DEBUG: MIPRO section in config_body before sending:")
|
|
867
|
+
print(f" Type: {type(mipro_debug)}")
|
|
868
|
+
print(f" Keys: {list(mipro_debug.keys()) if isinstance(mipro_debug, dict) else 'NOT A DICT'}")
|
|
869
|
+
print(f" bootstrap_train_seeds present: {mipro_debug.get('bootstrap_train_seeds') is not None}")
|
|
870
|
+
print(f" online_pool present: {mipro_debug.get('online_pool') is not None}")
|
|
871
|
+
if isinstance(mipro_debug, dict):
|
|
872
|
+
print(f" bootstrap_train_seeds value: {mipro_debug.get('bootstrap_train_seeds')}")
|
|
873
|
+
print(f" online_pool value: {mipro_debug.get('online_pool')}")
|
|
874
|
+
# Print full mipro section (truncated)
|
|
875
|
+
mipro_json = json.dumps(mipro_debug, indent=2, default=str)
|
|
876
|
+
print(f" Full mipro section (first 500 chars):\n{mipro_json[:500]}")
|
|
877
|
+
print("š END DEBUG\n")
|
|
878
|
+
|
|
879
|
+
backend = overrides.get("backend")
|
|
880
|
+
if backend:
|
|
881
|
+
metadata_default: dict[str, Any] = {}
|
|
882
|
+
metadata = cast(dict[str, Any], payload.setdefault("metadata", metadata_default))
|
|
883
|
+
metadata["backend_base_url"] = ensure_api_base(str(backend))
|
|
884
|
+
|
|
885
|
+
return PromptLearningBuildResult(payload=payload, task_url=final_task_url)
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
__all__ = [
|
|
889
|
+
"PromptLearningBuildResult",
|
|
890
|
+
"RLBuildResult",
|
|
891
|
+
"SFTBuildResult",
|
|
892
|
+
"build_prompt_learning_payload",
|
|
893
|
+
"build_rl_payload",
|
|
894
|
+
"build_sft_payload",
|
|
895
|
+
]
|