synth-ai 0.2.9.dev11__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 +44 -45
- synth_ai/__main__.py +30 -3
- synth_ai/cli/__init__.py +104 -78
- 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 -103
- 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/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/examples/basic_usage.py +194 -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/replica_sync.py +262 -0
- synth_ai/core/tracing_v3/serialization.py +130 -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/storage/utils.py +206 -0
- synth_ai/core/tracing_v3/trace_utils.py +326 -0
- synth_ai/core/tracing_v3/turso/__init__.py +12 -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/judging/types.py +42 -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/models.py +57 -0
- synth_ai/sdk/task/rubrics/scoring.py +116 -0
- synth_ai/sdk/task/rubrics/strict.py +149 -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/entry_points.txt +2 -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/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 -64
- 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 -18
- examples/qwen_coder/scripts/train_coder_30b.sh +0 -21
- 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 -38
- examples/qwen_coder/validate_jsonl.py +0 -59
- examples/rl/README.md +0 -169
- examples/rl/configs/eval_base_qwen.toml +0 -15
- examples/rl/configs/eval_rl_qwen.toml +0 -11
- examples/rl/configs/rl_from_base_qwen.toml +0 -35
- examples/rl/configs/rl_from_base_qwen17.toml +0 -74
- examples/rl/configs/rl_from_ft_qwen.toml +0 -35
- examples/rl/download_dataset.py +0 -80
- examples/rl/run_eval.py +0 -436
- examples/rl/run_rl_and_save.py +0 -111
- examples/rl/task_app/README.md +0 -22
- examples/rl/task_app/math_single_step.py +0 -991
- examples/rl/task_app/math_task_app.py +0 -115
- 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 -117
- examples/sft/export_dataset.py +0 -117
- examples/sft/generate_traces.py +0 -162
- 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 -571
- 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 -1869
- 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 -137
- examples/swe/task_app/hosted/utils.py +0 -62
- 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/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 -95
- examples/warming_up_to_rl/manage_secrets.py +0 -131
- examples/warming_up_to_rl/readme.md +0 -179
- examples/warming_up_to_rl/run_eval.py +0 -510
- examples/warming_up_to_rl/run_fft_and_save.py +0 -380
- examples/warming_up_to_rl/run_local_rollout.py +0 -237
- examples/warming_up_to_rl/run_local_rollout_modal.py +0 -246
- examples/warming_up_to_rl/run_local_rollout_parallel.py +0 -403
- examples/warming_up_to_rl/run_local_rollout_traced.py +0 -475
- examples/warming_up_to_rl/run_rl_and_save.py +0 -124
- examples/warming_up_to_rl/run_rollout_remote.py +0 -154
- examples/warming_up_to_rl/task_app/README.md +0 -42
- examples/warming_up_to_rl/task_app/grpo_crafter.py +0 -700
- examples/warming_up_to_rl/task_app/grpo_crafter_task_app.py +0 -146
- examples/warming_up_to_rl/task_app/synth_envs_hosted/README.md +0 -173
- examples/warming_up_to_rl/task_app/synth_envs_hosted/__init__.py +0 -5
- examples/warming_up_to_rl/task_app/synth_envs_hosted/branching.py +0 -143
- examples/warming_up_to_rl/task_app/synth_envs_hosted/environment_routes.py +0 -1226
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/__init__.py +0 -1
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/__init__.py +0 -6
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/app.py +0 -1
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/environment.py +0 -522
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/policy.py +0 -478
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/react_agent.py +0 -108
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/shared.py +0 -305
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/tools.py +0 -47
- examples/warming_up_to_rl/task_app/synth_envs_hosted/hosted_app.py +0 -204
- examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/__init__.py +0 -5
- examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/openai_client.py +0 -618
- examples/warming_up_to_rl/task_app/synth_envs_hosted/main.py +0 -100
- examples/warming_up_to_rl/task_app/synth_envs_hosted/policy_routes.py +0 -1083
- examples/warming_up_to_rl/task_app/synth_envs_hosted/registry.py +0 -195
- examples/warming_up_to_rl/task_app/synth_envs_hosted/rollout.py +0 -1869
- examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/__init__.py +0 -5
- examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/volume.py +0 -211
- examples/warming_up_to_rl/task_app/synth_envs_hosted/test_agents.py +0 -161
- examples/warming_up_to_rl/task_app/synth_envs_hosted/test_service.py +0 -137
- examples/warming_up_to_rl/task_app/synth_envs_hosted/utils.py +0 -62
- synth/__init__.py +0 -14
- synth_ai/api/models/supported.py +0 -376
- synth_ai/api/train/__init__.py +0 -5
- synth_ai/api/train/builders.py +0 -296
- synth_ai/api/train/cli.py +0 -606
- synth_ai/api/train/config_finder.py +0 -228
- synth_ai/api/train/env_resolver.py +0 -347
- synth_ai/api/train/pollers.py +0 -75
- synth_ai/api/train/supported_algos.py +0 -139
- synth_ai/api/train/task_app.py +0 -195
- synth_ai/api/train/utils.py +0 -217
- synth_ai/cli/_modal_wrapper.py +0 -28
- synth_ai/cli/_typer_patch.py +0 -49
- synth_ai/cli/balance.py +0 -203
- synth_ai/cli/calc.py +0 -69
- synth_ai/cli/demo.py +0 -159
- synth_ai/cli/legacy_root_backup.py +0 -470
- synth_ai/cli/man.py +0 -106
- synth_ai/cli/recent.py +0 -127
- synth_ai/cli/rl_demo.py +0 -274
- synth_ai/cli/status.py +0 -133
- synth_ai/cli/task_apps.py +0 -2782
- synth_ai/cli/traces.py +0 -163
- synth_ai/cli/watch.py +0 -505
- 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 -1756
- synth_ai/demos/demo_task_apps/core.py +0 -440
- synth_ai/demos/demo_task_apps/crafter/grpo_crafter_task_app.py +0 -172
- 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/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/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 -479
- 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 -295
- synth_ai/environments/examples/enron/environment.py +0 -166
- 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 -694
- synth_ai/environments/examples/red/engine_helpers/__init__.py +0 -1
- synth_ai/environments/examples/red/engine_helpers/memory_map.py +0 -28
- 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_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 -140
- synth_ai/environments/examples/red/environment.py +0 -238
- 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 -428
- 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 -329
- 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/base.py +0 -13
- 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 -271
- 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/main.py +0 -6
- synth_ai/task/__init__.py +0 -102
- synth_ai/task/apps/__init__.py +0 -128
- synth_ai/task/contracts.py +0 -137
- synth_ai/task/datasets.py +0 -108
- synth_ai/task/proxy.py +0 -259
- synth_ai/task/server.py +0 -424
- synth_ai/task/tracing_utils.py +0 -84
- synth_ai/task/validators.py +0 -11
- synth_ai/tracing_v3/__init__.py +0 -97
- synth_ai/tracing_v3/config.py +0 -84
- synth_ai/tracing_v3/db_config.py +0 -194
- synth_ai/tracing_v3/decorators.py +0 -369
- synth_ai/tracing_v3/examples/basic_usage.py +0 -189
- synth_ai/tracing_v3/llm_call_record_helpers.py +0 -337
- synth_ai/tracing_v3/migration_helper.py +0 -120
- synth_ai/tracing_v3/replica_sync.py +0 -258
- synth_ai/tracing_v3/session_tracer.py +0 -530
- 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/storage/utils.py +0 -204
- synth_ai/tracing_v3/turso/daemon.py +0 -149
- synth_ai/tracing_v3/turso/models.py +0 -469
- synth_ai/tracing_v3/turso/native_manager.py +0 -1173
- synth_ai/tracing_v3/utils.py +0 -108
- 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/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.9.dev11.dist-info/METADATA +0 -191
- synth_ai-0.2.9.dev11.dist-info/RECORD +0 -571
- synth_ai-0.2.9.dev11.dist-info/entry_points.txt +0 -3
- synth_ai-0.2.9.dev11.dist-info/top_level.txt +0 -3
- /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
- /synth_ai/{v0/lm/caching → core/apps}/__init__.py +0 -0
- /synth_ai/{tracing_v3 → core/tracing_v3}/abstractions.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}/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/{compound/cais.py → py.typed} +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.py +0 -0
- /synth_ai/{task → sdk/task}/vendors.py +0 -0
- {synth_ai-0.2.9.dev11.dist-info → synth_ai-0.4.1.dist-info}/WHEEL +0 -0
- {synth_ai-0.2.9.dev11.dist-info → synth_ai-0.4.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"""Celery application configuration for the experiment queue."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
# ALWAYS clear config cache to ensure fresh config on worker startup
|
|
11
|
+
# This is critical for workers that may have cached config from previous runs
|
|
12
|
+
from . import config as queue_config
|
|
13
|
+
|
|
14
|
+
queue_config.reset_config_cache()
|
|
15
|
+
|
|
16
|
+
# Log the database path that will be used (before any imports that might cache it)
|
|
17
|
+
db_path_env = os.getenv("EXPERIMENT_QUEUE_DB_PATH")
|
|
18
|
+
if db_path_env:
|
|
19
|
+
db_path_resolved = Path(db_path_env).expanduser().resolve()
|
|
20
|
+
print(f"[celery_app] EXPERIMENT_QUEUE_DB_PATH={db_path_resolved}", file=sys.stderr, flush=True)
|
|
21
|
+
# Verify the path exists or can be created
|
|
22
|
+
db_path_resolved.parent.mkdir(parents=True, exist_ok=True)
|
|
23
|
+
print(f"[celery_app] Database file will be: {db_path_resolved}", file=sys.stderr, flush=True)
|
|
24
|
+
else:
|
|
25
|
+
# Will use default path from config (~/.synth_ai/experiment_queue.db)
|
|
26
|
+
print("[celery_app] EXPERIMENT_QUEUE_DB_PATH not set, will use default path", file=sys.stderr, flush=True)
|
|
27
|
+
|
|
28
|
+
from celery import Celery # noqa: E402
|
|
29
|
+
|
|
30
|
+
from .config import load_config, reset_config_cache # noqa: E402
|
|
31
|
+
from .database import init_db # noqa: E402
|
|
32
|
+
|
|
33
|
+
logger = logging.getLogger(__name__)
|
|
34
|
+
|
|
35
|
+
# Module-level celery app instance and its config (for change detection)
|
|
36
|
+
_celery_app_instance: Celery | None = None
|
|
37
|
+
_celery_app_broker_url: str | None = None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _create_celery_app() -> Celery:
|
|
41
|
+
"""Instantiate the Celery application with shared configuration."""
|
|
42
|
+
# Load config (will use EXPERIMENT_QUEUE_DB_PATH if set, otherwise default path)
|
|
43
|
+
reset_config_cache()
|
|
44
|
+
config = load_config()
|
|
45
|
+
|
|
46
|
+
# Log which database path is being used
|
|
47
|
+
env_db_path = os.getenv("EXPERIMENT_QUEUE_DB_PATH")
|
|
48
|
+
if env_db_path:
|
|
49
|
+
env_db_path_resolved = Path(env_db_path).expanduser().resolve()
|
|
50
|
+
config_db_path_resolved = config.sqlite_path.resolve()
|
|
51
|
+
|
|
52
|
+
# Verify database path matches environment variable if env var is set
|
|
53
|
+
if config_db_path_resolved != env_db_path_resolved:
|
|
54
|
+
error_msg = (
|
|
55
|
+
f"Database path mismatch! "
|
|
56
|
+
f"ENV: {env_db_path_resolved} != CONFIG: {config_db_path_resolved}. "
|
|
57
|
+
f"This will cause workers to use different databases. "
|
|
58
|
+
f"Clear config cache and restart worker."
|
|
59
|
+
)
|
|
60
|
+
print(f"[celery_app] ERROR: {error_msg}", file=sys.stderr, flush=True)
|
|
61
|
+
raise RuntimeError(error_msg)
|
|
62
|
+
print(
|
|
63
|
+
f"[celery_app] Using database from EXPERIMENT_QUEUE_DB_PATH: {config.sqlite_path}",
|
|
64
|
+
file=sys.stderr,
|
|
65
|
+
flush=True,
|
|
66
|
+
)
|
|
67
|
+
else:
|
|
68
|
+
print(
|
|
69
|
+
f"[celery_app] Using default database path: {config.sqlite_path}",
|
|
70
|
+
file=sys.stderr,
|
|
71
|
+
flush=True,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# CRITICAL: Ensure database path is unique and enforce single instance
|
|
75
|
+
# Verify no other process is using a different database path
|
|
76
|
+
db_file = str(config.sqlite_path)
|
|
77
|
+
Path(db_file).parent.mkdir(parents=True, exist_ok=True)
|
|
78
|
+
|
|
79
|
+
# Initialize database (for our application DB only - Celery uses Redis broker)
|
|
80
|
+
init_db()
|
|
81
|
+
|
|
82
|
+
# Log database path for debugging (especially in worker subprocess)
|
|
83
|
+
# Use print to stderr to ensure it's visible even if logging isn't configured
|
|
84
|
+
print(
|
|
85
|
+
f"[celery_app] Initializing with database: {config.sqlite_path} (broker: {config.broker_url})",
|
|
86
|
+
file=sys.stderr,
|
|
87
|
+
flush=True,
|
|
88
|
+
)
|
|
89
|
+
logger.info(
|
|
90
|
+
"Celery app initializing with database: %s (broker: %s)",
|
|
91
|
+
config.sqlite_path,
|
|
92
|
+
config.broker_url,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
app = Celery(
|
|
96
|
+
"synth_ai.experiment_queue",
|
|
97
|
+
broker=config.broker_url,
|
|
98
|
+
backend=config.result_backend_url,
|
|
99
|
+
include=["synth_ai.cli.local.experiment_queue.tasks"],
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
app.conf.update(
|
|
103
|
+
task_serializer="json",
|
|
104
|
+
accept_content=["json"],
|
|
105
|
+
result_serializer="json",
|
|
106
|
+
timezone="UTC",
|
|
107
|
+
enable_utc=True,
|
|
108
|
+
task_track_started=True,
|
|
109
|
+
worker_prefetch_multiplier=1,
|
|
110
|
+
worker_max_tasks_per_child=25,
|
|
111
|
+
task_acks_late=True,
|
|
112
|
+
broker_pool_limit=4,
|
|
113
|
+
# Celery Beat schedule for periodic queue processing
|
|
114
|
+
beat_schedule={
|
|
115
|
+
"process-experiment-queue": {
|
|
116
|
+
"task": "synth_ai.cli.local.experiment_queue.process_experiment_queue",
|
|
117
|
+
"schedule": 5.0, # Run every 5 seconds
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
# Redis broker - no need to pre-create tables or configure WAL mode
|
|
123
|
+
# Redis handles concurrency natively, no SQLite locking issues
|
|
124
|
+
|
|
125
|
+
return app
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def get_celery_app() -> Celery:
|
|
129
|
+
"""Return the shared Celery app, recreating it if config has changed.
|
|
130
|
+
|
|
131
|
+
This function checks if the config cache was cleared (by comparing
|
|
132
|
+
current broker URL to cached one) and recreates the app if needed.
|
|
133
|
+
This ensures CLI and worker use the same database when env vars change.
|
|
134
|
+
|
|
135
|
+
Uses EXPERIMENT_QUEUE_DB_PATH if set, otherwise defaults to ~/.synth_ai/experiment_queue.db
|
|
136
|
+
"""
|
|
137
|
+
global _celery_app_instance, _celery_app_broker_url
|
|
138
|
+
|
|
139
|
+
# Check if config has changed by comparing broker URLs
|
|
140
|
+
# load_config() will use EXPERIMENT_QUEUE_DB_PATH if set, otherwise default path
|
|
141
|
+
current_config = load_config()
|
|
142
|
+
current_broker_url = current_config.broker_url
|
|
143
|
+
|
|
144
|
+
if _celery_app_instance is None or _celery_app_broker_url != current_broker_url:
|
|
145
|
+
# Config changed or app not initialized - recreate it
|
|
146
|
+
logger.debug(
|
|
147
|
+
"Recreating Celery app: broker URL changed from %s to %s",
|
|
148
|
+
_celery_app_broker_url,
|
|
149
|
+
current_broker_url,
|
|
150
|
+
)
|
|
151
|
+
_celery_app_instance = _create_celery_app()
|
|
152
|
+
_celery_app_broker_url = current_broker_url
|
|
153
|
+
|
|
154
|
+
return _celery_app_instance
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
# Create app at module import time (for worker entrypoints and decorators)
|
|
158
|
+
# This ensures workers get the correct config at startup
|
|
159
|
+
# Uses default path (~/.synth_ai/experiment_queue.db) if EXPERIMENT_QUEUE_DB_PATH is not set
|
|
160
|
+
try:
|
|
161
|
+
celery_app = get_celery_app()
|
|
162
|
+
except RuntimeError as e:
|
|
163
|
+
# If config loading fails for any reason, create a placeholder that will fail on use
|
|
164
|
+
# This allows the module to be imported but will fail when celery_app is actually used
|
|
165
|
+
class _LazyCeleryApp:
|
|
166
|
+
"""Placeholder that raises error when Celery app initialization fails."""
|
|
167
|
+
def __init__(self, original_error: RuntimeError):
|
|
168
|
+
self._original_error = original_error
|
|
169
|
+
|
|
170
|
+
def __getattr__(self, name):
|
|
171
|
+
# Special handling for 'task' attribute used in decorators
|
|
172
|
+
# This allows @celery_app.task decorators to be defined without immediate error
|
|
173
|
+
if name == "task":
|
|
174
|
+
# Return a decorator factory that will raise error when task is actually called
|
|
175
|
+
def task_decorator(*args, **kwargs):
|
|
176
|
+
def decorator(func):
|
|
177
|
+
# Store the function, but wrap it to check env var on call
|
|
178
|
+
def wrapper(*func_args, **func_kwargs):
|
|
179
|
+
# Try to get real celery app now
|
|
180
|
+
try:
|
|
181
|
+
real_app = get_celery_app()
|
|
182
|
+
# Re-register the task with the real app
|
|
183
|
+
real_task = real_app.task(*args, **kwargs)(func)
|
|
184
|
+
return real_task(*func_args, **func_kwargs)
|
|
185
|
+
except RuntimeError as runtime_err:
|
|
186
|
+
raise RuntimeError(
|
|
187
|
+
f"Failed to initialize Celery app. "
|
|
188
|
+
f"Original error: {self._original_error}, "
|
|
189
|
+
f"Runtime error: {runtime_err}"
|
|
190
|
+
) from runtime_err
|
|
191
|
+
return wrapper
|
|
192
|
+
return decorator
|
|
193
|
+
return task_decorator
|
|
194
|
+
raise RuntimeError(
|
|
195
|
+
f"Failed to initialize Celery app. "
|
|
196
|
+
f"Original error: {self._original_error}"
|
|
197
|
+
)
|
|
198
|
+
def __call__(self, *args, **kwargs):
|
|
199
|
+
raise RuntimeError(
|
|
200
|
+
f"Failed to initialize Celery app. "
|
|
201
|
+
f"Original error: {self._original_error}"
|
|
202
|
+
)
|
|
203
|
+
def __getitem__(self, key):
|
|
204
|
+
raise RuntimeError(
|
|
205
|
+
f"Failed to initialize Celery app. "
|
|
206
|
+
f"Original error: {self._original_error}"
|
|
207
|
+
)
|
|
208
|
+
celery_app = _LazyCeleryApp(e) # type: ignore[assignment]
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""Configuration helpers for the experiment queue service."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from functools import lru_cache
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
# Default database path in user's home directory
|
|
11
|
+
# Can be overridden via EXPERIMENT_QUEUE_DB_PATH environment variable
|
|
12
|
+
DEFAULT_DB_PATH = Path.home() / ".synth_ai" / "experiment_queue.db"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _candidate_db_paths() -> list[Path]:
|
|
16
|
+
"""Build candidate paths using env overrides."""
|
|
17
|
+
env_vars = (
|
|
18
|
+
"EXPERIMENT_QUEUE_DB_PATH",
|
|
19
|
+
"EXPERIMENT_QUEUE_SQLITE_PATH",
|
|
20
|
+
"SYNTH_AI_EXPERIMENT_DB_PATH",
|
|
21
|
+
"SQLD_DB_PATH",
|
|
22
|
+
)
|
|
23
|
+
candidates: list[Path] = []
|
|
24
|
+
for name in env_vars:
|
|
25
|
+
value = os.getenv(name)
|
|
26
|
+
if value:
|
|
27
|
+
candidates.append(Path(value).expanduser())
|
|
28
|
+
candidates.append(DEFAULT_DB_PATH)
|
|
29
|
+
return candidates
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _resolve_sqlite_file(base_path: Path) -> Path:
|
|
33
|
+
"""
|
|
34
|
+
Resolve the actual SQLite file path managed by sqld.
|
|
35
|
+
|
|
36
|
+
sqld typically creates `{db_path}/dbs/default/data`. If the directory
|
|
37
|
+
does not exist yet (e.g., sqld not started), fall back to the provided path.
|
|
38
|
+
"""
|
|
39
|
+
base_path = base_path.expanduser()
|
|
40
|
+
if base_path.is_dir():
|
|
41
|
+
sqld_candidate = (base_path / "dbs" / "default" / "data").resolve()
|
|
42
|
+
if sqld_candidate.exists():
|
|
43
|
+
return sqld_candidate
|
|
44
|
+
|
|
45
|
+
resolved = base_path.resolve()
|
|
46
|
+
resolved.parent.mkdir(parents=True, exist_ok=True)
|
|
47
|
+
return resolved
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@dataclass(frozen=True)
|
|
51
|
+
class ExperimentQueueConfig:
|
|
52
|
+
"""Resolved configuration for the experiment queue runtime."""
|
|
53
|
+
|
|
54
|
+
sqlite_path: Path
|
|
55
|
+
broker_url: str
|
|
56
|
+
result_backend_url: str
|
|
57
|
+
backend_url: str
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def sqlalchemy_url(self) -> str:
|
|
61
|
+
"""Return SQLAlchemy connection string for ORM usage."""
|
|
62
|
+
return f"sqlite:///{self.sqlite_path}"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@lru_cache(maxsize=1)
|
|
66
|
+
def load_config() -> ExperimentQueueConfig:
|
|
67
|
+
"""Resolve configuration once per process.
|
|
68
|
+
|
|
69
|
+
Backend URL Resolution:
|
|
70
|
+
- Default: Production backend (https://api.usesynth.ai/api)
|
|
71
|
+
- Set EXPERIMENT_QUEUE_LOCAL=true to use local backend (http://localhost:8000/api)
|
|
72
|
+
- Override with EXPERIMENT_QUEUE_BACKEND_URL env var for custom URL
|
|
73
|
+
- Falls back to DEV_BACKEND_URL if set (for compatibility)
|
|
74
|
+
|
|
75
|
+
Examples:
|
|
76
|
+
# Use production (default)
|
|
77
|
+
load_config() # Uses https://api.usesynth.ai/api
|
|
78
|
+
|
|
79
|
+
# Use local backend
|
|
80
|
+
os.environ["EXPERIMENT_QUEUE_LOCAL"] = "true"
|
|
81
|
+
load_config() # Uses http://localhost:8000/api
|
|
82
|
+
|
|
83
|
+
# Use custom backend
|
|
84
|
+
os.environ["EXPERIMENT_QUEUE_BACKEND_URL"] = "http://custom:9000/api"
|
|
85
|
+
load_config() # Uses http://custom:9000/api
|
|
86
|
+
"""
|
|
87
|
+
sqlite_path: Path | None = None
|
|
88
|
+
for candidate in _candidate_db_paths():
|
|
89
|
+
sqlite_path = _resolve_sqlite_file(candidate)
|
|
90
|
+
if sqlite_path:
|
|
91
|
+
break
|
|
92
|
+
|
|
93
|
+
if sqlite_path is None:
|
|
94
|
+
sqlite_path = _resolve_sqlite_file(DEFAULT_DB_PATH)
|
|
95
|
+
|
|
96
|
+
# Redis broker and backend (no longer using SQLite for Celery)
|
|
97
|
+
broker_url = os.getenv("EXPERIMENT_QUEUE_BROKER_URL", "redis://localhost:6379/0")
|
|
98
|
+
result_backend_url = os.getenv("EXPERIMENT_QUEUE_RESULT_BACKEND_URL", "redis://localhost:6379/1")
|
|
99
|
+
|
|
100
|
+
# Backend API URL for progress polling
|
|
101
|
+
# Defaults to production: https://api.usesynth.ai/api
|
|
102
|
+
# Override with EXPERIMENT_QUEUE_BACKEND_URL or EXPERIMENT_QUEUE_LOCAL=true for localhost:8000
|
|
103
|
+
if os.getenv("EXPERIMENT_QUEUE_LOCAL", "").lower() in ("true", "1", "yes"):
|
|
104
|
+
# Local mode: use localhost:8000
|
|
105
|
+
backend_url = os.getenv("EXPERIMENT_QUEUE_BACKEND_URL", "http://localhost:8000/api")
|
|
106
|
+
else:
|
|
107
|
+
# Production mode (default): use api.usesynth.ai
|
|
108
|
+
backend_url = (
|
|
109
|
+
os.getenv("EXPERIMENT_QUEUE_BACKEND_URL")
|
|
110
|
+
or os.getenv("DEV_BACKEND_URL")
|
|
111
|
+
or "https://api.usesynth.ai/api"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
return ExperimentQueueConfig(
|
|
115
|
+
sqlite_path=sqlite_path,
|
|
116
|
+
broker_url=broker_url,
|
|
117
|
+
result_backend_url=result_backend_url,
|
|
118
|
+
backend_url=backend_url,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def reset_config_cache() -> None:
|
|
123
|
+
"""Clear the cached config to force reload from environment variables.
|
|
124
|
+
|
|
125
|
+
Call this before importing/using the Celery app if EXPERIMENT_QUEUE_DB_PATH
|
|
126
|
+
or EXPERIMENT_QUEUE_TRAIN_CMD environment variables have changed.
|
|
127
|
+
"""
|
|
128
|
+
load_config.cache_clear()
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"""Helpers for preparing TOML configs for experiment jobs."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import copy
|
|
6
|
+
import tempfile
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any, Mapping, MutableMapping
|
|
10
|
+
|
|
11
|
+
import tomli_w
|
|
12
|
+
|
|
13
|
+
from synth_ai.core.telemetry import log_info
|
|
14
|
+
|
|
15
|
+
from .validation import validate_path
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _load_toml(config_path: Path) -> dict[str, Any]:
|
|
19
|
+
"""Load TOML using tomllib/tomli depending on runtime.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
config_path: Path to TOML config file
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
Parsed TOML as dictionary
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
AssertionError: If config_path is invalid or file cannot be parsed
|
|
29
|
+
FileNotFoundError: If config file doesn't exist
|
|
30
|
+
"""
|
|
31
|
+
# Validate input
|
|
32
|
+
assert config_path is not None, "config_path cannot be None"
|
|
33
|
+
path = validate_path(config_path, "config_path", must_exist=True)
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
import tomllib # type: ignore[attr-defined]
|
|
37
|
+
except ModuleNotFoundError:
|
|
38
|
+
import tomli as tomllib # type: ignore[no-redef]
|
|
39
|
+
|
|
40
|
+
with open(path, "rb") as fh:
|
|
41
|
+
config = tomllib.load(fh)
|
|
42
|
+
assert isinstance(config, dict), (
|
|
43
|
+
f"TOML config must be dict, got {type(config).__name__}"
|
|
44
|
+
)
|
|
45
|
+
return config
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _ensure_prompt_learning_section(config: dict[str, Any]) -> dict[str, Any]:
|
|
49
|
+
"""Ensure prompt_learning section exists and is a dict.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
config: TOML config dictionary
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
prompt_learning section dictionary
|
|
56
|
+
|
|
57
|
+
Raises:
|
|
58
|
+
AssertionError: If config is invalid or section is wrong type
|
|
59
|
+
"""
|
|
60
|
+
assert isinstance(config, dict), (
|
|
61
|
+
f"config must be dict, got {type(config).__name__}"
|
|
62
|
+
)
|
|
63
|
+
section = config.setdefault("prompt_learning", {})
|
|
64
|
+
assert isinstance(section, dict), (
|
|
65
|
+
f"Expected [prompt_learning] section to be a dict, got {type(section).__name__}"
|
|
66
|
+
)
|
|
67
|
+
return section
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _find_similar_keys(data: dict[str, Any], search_key: str, results: list[str], prefix: str = "") -> None:
|
|
71
|
+
"""Recursively find keys similar to search_key in nested dict structure."""
|
|
72
|
+
if not isinstance(data, dict):
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
for key, value in data.items():
|
|
76
|
+
current_path = f"{prefix}.{key}" if prefix else key
|
|
77
|
+
if search_key.lower() in key.lower() or key.lower() in search_key.lower():
|
|
78
|
+
results.append(current_path)
|
|
79
|
+
if isinstance(value, dict):
|
|
80
|
+
_find_similar_keys(value, search_key, results, current_path)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _deep_update(base: MutableMapping[str, Any], overrides: Mapping[str, Any]) -> MutableMapping[str, Any]:
|
|
84
|
+
"""Deep update with support for dot-notation keys (e.g., 'prompt_learning.gepa.rollout.budget').
|
|
85
|
+
|
|
86
|
+
Dot-notation keys are split and create nested dictionaries.
|
|
87
|
+
Regular keys are updated normally.
|
|
88
|
+
"""
|
|
89
|
+
for key, value in overrides.items():
|
|
90
|
+
# Handle dot-notation keys (e.g., "prompt_learning.gepa.rollout.budget")
|
|
91
|
+
if "." in key:
|
|
92
|
+
keys = key.split(".")
|
|
93
|
+
# Navigate/create nested structure
|
|
94
|
+
current = base
|
|
95
|
+
for k in keys[:-1]:
|
|
96
|
+
if k not in current or not isinstance(current[k], MutableMapping):
|
|
97
|
+
current[k] = {}
|
|
98
|
+
current = current[k]
|
|
99
|
+
# Set final value
|
|
100
|
+
final_key = keys[-1]
|
|
101
|
+
if (
|
|
102
|
+
isinstance(value, Mapping)
|
|
103
|
+
and isinstance(current.get(final_key), MutableMapping)
|
|
104
|
+
and not isinstance(value, str | bytes)
|
|
105
|
+
):
|
|
106
|
+
nested = copy.deepcopy(dict(current[final_key]))
|
|
107
|
+
current[final_key] = _deep_update(nested, value)
|
|
108
|
+
else:
|
|
109
|
+
current[final_key] = copy.deepcopy(value)
|
|
110
|
+
else:
|
|
111
|
+
# Regular key (no dot notation)
|
|
112
|
+
if (
|
|
113
|
+
isinstance(value, Mapping)
|
|
114
|
+
and isinstance(base.get(key), MutableMapping)
|
|
115
|
+
and not isinstance(value, str | bytes)
|
|
116
|
+
):
|
|
117
|
+
nested = copy.deepcopy(dict(base[key]))
|
|
118
|
+
base[key] = _deep_update(nested, value)
|
|
119
|
+
else:
|
|
120
|
+
base[key] = copy.deepcopy(value)
|
|
121
|
+
return base
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _resolve_path(value: str, *, relative_to: Path) -> Path:
|
|
125
|
+
path = Path(value)
|
|
126
|
+
if not path.is_absolute():
|
|
127
|
+
path = (relative_to / value).resolve()
|
|
128
|
+
else:
|
|
129
|
+
path = path.expanduser().resolve()
|
|
130
|
+
return path
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def resolve_results_folder(config: dict[str, Any], config_path: Path) -> Path:
|
|
134
|
+
"""Resolve and ensure the results folder exists."""
|
|
135
|
+
config_dir = config_path.parent.resolve()
|
|
136
|
+
prompt_section = _ensure_prompt_learning_section(config)
|
|
137
|
+
raw = prompt_section.get("results_folder") or config.get("results_folder")
|
|
138
|
+
if raw:
|
|
139
|
+
results_path = _resolve_path(str(raw), relative_to=config_dir)
|
|
140
|
+
else:
|
|
141
|
+
results_path = (config_dir / "results").resolve()
|
|
142
|
+
results_path.mkdir(parents=True, exist_ok=True)
|
|
143
|
+
prompt_section["results_folder"] = str(results_path)
|
|
144
|
+
return results_path
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def normalize_env_file_path(config: dict[str, Any], config_path: Path) -> None:
|
|
148
|
+
"""Ensure env_file_path fields are absolute so subprocesses inherit the right file."""
|
|
149
|
+
config_dir = config_path.parent.resolve()
|
|
150
|
+
prompt_section = _ensure_prompt_learning_section(config)
|
|
151
|
+
raw = prompt_section.get("env_file_path") or config.get("env_file_path")
|
|
152
|
+
if not raw:
|
|
153
|
+
return
|
|
154
|
+
env_path = _resolve_path(str(raw), relative_to=config_dir)
|
|
155
|
+
prompt_section["env_file_path"] = str(env_path)
|
|
156
|
+
config["env_file_path"] = str(env_path)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@dataclass(slots=True)
|
|
160
|
+
class PreparedConfig:
|
|
161
|
+
"""Container for a temporary config file plus metadata."""
|
|
162
|
+
|
|
163
|
+
path: Path
|
|
164
|
+
results_folder: Path
|
|
165
|
+
workdir: Path | None = None
|
|
166
|
+
|
|
167
|
+
def cleanup(self) -> None:
|
|
168
|
+
if self.workdir and self.workdir.exists():
|
|
169
|
+
import shutil
|
|
170
|
+
|
|
171
|
+
shutil.rmtree(self.workdir, ignore_errors=True)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def prepare_config_file(config_path: str | Path, overrides: Mapping[str, Any] | None = None) -> PreparedConfig:
|
|
175
|
+
"""
|
|
176
|
+
Load a TOML config, apply overrides, and materialize a temporary file.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
config_path: Path to source TOML config file
|
|
180
|
+
overrides: Optional dictionary of config overrides to apply
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
PreparedConfig with the path to the merged TOML and resolved results_folder.
|
|
184
|
+
|
|
185
|
+
Raises:
|
|
186
|
+
AssertionError: If inputs are invalid
|
|
187
|
+
FileNotFoundError: If config file doesn't exist
|
|
188
|
+
"""
|
|
189
|
+
ctx: dict[str, Any] = {"config_path": str(config_path), "has_overrides": overrides is not None}
|
|
190
|
+
log_info("prepare_config_file invoked", ctx=ctx)
|
|
191
|
+
# Validate inputs
|
|
192
|
+
assert config_path is not None, "config_path cannot be None"
|
|
193
|
+
source_path = validate_path(config_path, "config_path", must_exist=True)
|
|
194
|
+
|
|
195
|
+
if overrides is not None:
|
|
196
|
+
assert isinstance(overrides, Mapping), (
|
|
197
|
+
f"overrides must be Mapping, got {type(overrides).__name__}"
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
data = _load_toml(source_path)
|
|
201
|
+
assert isinstance(data, dict), (
|
|
202
|
+
f"_load_toml must return dict, got {type(data).__name__}"
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
if overrides:
|
|
206
|
+
_deep_update(data, overrides)
|
|
207
|
+
# Validate after merge
|
|
208
|
+
assert isinstance(data, dict), (
|
|
209
|
+
f"Config after merge must be dict, got {type(data).__name__}"
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
# VALIDATION: Verify critical overrides were actually applied
|
|
213
|
+
# This prevents silent failures where overrides don't match expected paths
|
|
214
|
+
for override_key, override_value in overrides.items():
|
|
215
|
+
# Navigate the nested dict structure (created by _deep_update)
|
|
216
|
+
keys = override_key.split(".")
|
|
217
|
+
current = data
|
|
218
|
+
found = True
|
|
219
|
+
|
|
220
|
+
# Navigate through nested structure
|
|
221
|
+
for key in keys:
|
|
222
|
+
if not isinstance(current, dict) or key not in current:
|
|
223
|
+
found = False
|
|
224
|
+
break
|
|
225
|
+
current = current[key]
|
|
226
|
+
|
|
227
|
+
if not found:
|
|
228
|
+
# Try to find similar keys for better error message
|
|
229
|
+
similar_keys = []
|
|
230
|
+
_find_similar_keys(data, keys[0], similar_keys)
|
|
231
|
+
similar_msg = f" Similar keys found: {similar_keys[:5]}" if similar_keys else ""
|
|
232
|
+
raise ValueError(
|
|
233
|
+
f"Config override validation failed: '{override_key}' was not found in config after merge.{similar_msg} "
|
|
234
|
+
f"Override value: {override_value!r}. This indicates the override path is incorrect or the config structure doesn't match."
|
|
235
|
+
)
|
|
236
|
+
elif isinstance(current, dict) and isinstance(override_value, dict):
|
|
237
|
+
# For dict overrides, check that override_value is a subset of current
|
|
238
|
+
# (i.e., all keys in override_value match current)
|
|
239
|
+
for key, val in override_value.items():
|
|
240
|
+
if key not in current or current[key] != val:
|
|
241
|
+
raise ValueError(
|
|
242
|
+
f"Config override validation failed: '{override_key}.{key}' was set to {current.get(key)!r} "
|
|
243
|
+
f"but override specified {val!r}. Override may not have been applied correctly."
|
|
244
|
+
)
|
|
245
|
+
elif current != override_value:
|
|
246
|
+
# Value exists but doesn't match - this is a problem
|
|
247
|
+
# This is critical for rollout limits - if base config has 300 but override specifies 100,
|
|
248
|
+
# we MUST ensure 100 is applied, not 300
|
|
249
|
+
raise ValueError(
|
|
250
|
+
f"Config override validation failed: '{override_key}' was set to {current!r} "
|
|
251
|
+
f"but override specified {override_value!r}. Override may not have been applied correctly. "
|
|
252
|
+
f"This indicates the base config value ({current!r}) was not overridden by the specified value ({override_value!r})."
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
normalize_env_file_path(data, source_path)
|
|
256
|
+
results_folder = resolve_results_folder(data, source_path)
|
|
257
|
+
assert results_folder.exists(), (
|
|
258
|
+
f"results_folder must exist after creation: {results_folder}"
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
workdir = Path(tempfile.mkdtemp(prefix="experiment_queue_cfg_"))
|
|
262
|
+
assert workdir.exists(), f"workdir must exist after creation: {workdir}"
|
|
263
|
+
|
|
264
|
+
tmp_config_path = workdir / source_path.name
|
|
265
|
+
with open(tmp_config_path, "wb") as fh:
|
|
266
|
+
tomli_w.dump(data, fh)
|
|
267
|
+
|
|
268
|
+
assert tmp_config_path.exists(), (
|
|
269
|
+
f"Temporary config file must exist after writing: {tmp_config_path}"
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
return PreparedConfig(path=tmp_config_path, results_folder=results_folder, workdir=workdir)
|