synth-ai 0.2.6.dev1__py3-none-any.whl → 0.4.3__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.
- synth_ai/__init__.py +44 -24
- synth_ai/__main__.py +30 -3
- synth_ai/cli/__init__.py +103 -48
- synth_ai/cli/__main__.py +42 -0
- synth_ai/cli/_internal/__init__.py +5 -0
- synth_ai/cli/_internal/modal_wrapper.py +31 -0
- synth_ai/cli/_internal/storage.py +20 -0
- synth_ai/cli/_internal/typer_patch.py +47 -0
- synth_ai/cli/_internal/validate_task_app.py +29 -0
- synth_ai/cli/agents/__init__.py +17 -0
- synth_ai/cli/agents/claude.py +77 -0
- synth_ai/cli/agents/codex.py +265 -0
- synth_ai/cli/agents/opencode.py +253 -0
- synth_ai/cli/commands/__init__.py +18 -0
- synth_ai/cli/commands/artifacts/__init__.py +13 -0
- synth_ai/cli/commands/artifacts/client.py +119 -0
- synth_ai/cli/commands/artifacts/config.py +57 -0
- synth_ai/cli/commands/artifacts/core.py +24 -0
- synth_ai/cli/commands/artifacts/download.py +188 -0
- synth_ai/cli/commands/artifacts/export.py +186 -0
- synth_ai/cli/commands/artifacts/list.py +156 -0
- synth_ai/cli/commands/artifacts/parsing.py +250 -0
- synth_ai/cli/commands/artifacts/show.py +336 -0
- synth_ai/cli/commands/demo/__init__.py +3 -0
- synth_ai/cli/commands/demo/core.py +153 -0
- synth_ai/cli/commands/eval/__init__.py +10 -0
- synth_ai/cli/commands/eval/config.py +338 -0
- synth_ai/cli/commands/eval/core.py +256 -0
- synth_ai/cli/commands/eval/runner.py +704 -0
- synth_ai/cli/commands/eval/validation.py +60 -0
- synth_ai/cli/commands/filter/__init__.py +12 -0
- synth_ai/cli/commands/filter/core.py +424 -0
- synth_ai/cli/commands/filter/errors.py +55 -0
- synth_ai/cli/commands/filter/validation.py +77 -0
- synth_ai/cli/commands/help/__init__.py +185 -0
- synth_ai/cli/commands/help/core.py +72 -0
- synth_ai/cli/commands/scan/__init__.py +19 -0
- synth_ai/cli/commands/scan/cloudflare_scanner.py +403 -0
- synth_ai/cli/commands/scan/core.py +344 -0
- synth_ai/cli/commands/scan/health_checker.py +242 -0
- synth_ai/cli/commands/scan/local_scanner.py +278 -0
- synth_ai/cli/commands/scan/models.py +83 -0
- synth_ai/cli/commands/smoke/__init__.py +7 -0
- synth_ai/cli/commands/smoke/core.py +1428 -0
- synth_ai/cli/commands/status/__init__.py +3 -0
- synth_ai/cli/commands/status/client.py +91 -0
- synth_ai/cli/commands/status/config.py +12 -0
- synth_ai/cli/commands/status/errors.py +11 -0
- synth_ai/cli/commands/status/subcommands/__init__.py +3 -0
- synth_ai/cli/commands/status/subcommands/config.py +13 -0
- synth_ai/cli/commands/status/subcommands/files.py +34 -0
- synth_ai/cli/commands/status/subcommands/jobs.py +51 -0
- synth_ai/cli/commands/status/subcommands/models.py +35 -0
- synth_ai/cli/commands/status/subcommands/runs.py +34 -0
- synth_ai/cli/commands/status/subcommands/session.py +77 -0
- synth_ai/cli/commands/status/subcommands/summary.py +39 -0
- synth_ai/cli/commands/status/subcommands/utils.py +41 -0
- synth_ai/cli/commands/status/utils.py +23 -0
- synth_ai/cli/commands/train/__init__.py +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/__init__.py +1 -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/__init__.py +7 -0
- synth_ai/{demos → cli/demo_apps}/demo_task_apps/core.py +117 -51
- synth_ai/cli/demo_apps/demo_task_apps/crafter/__init__.py +1 -0
- synth_ai/cli/demo_apps/demo_task_apps/crafter/configs/crafter_fft_4b.toml +53 -0
- synth_ai/cli/demo_apps/demo_task_apps/crafter/configs/rl_from_base_qwen4b.toml +73 -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/_common.py +16 -0
- synth_ai/{demos → cli/demo_apps}/demo_task_apps/math/app.py +2 -1
- synth_ai/cli/demo_apps/demo_task_apps/math/config.toml +73 -0
- synth_ai/{demos → cli/demo_apps}/demo_task_apps/math/deploy_modal.py +3 -6
- synth_ai/cli/demo_apps/demo_task_apps/math/modal_task_app.py +738 -0
- synth_ai/cli/demo_apps/demo_task_apps/math/task_app_entry.py +39 -0
- synth_ai/cli/demo_apps/math/__init__.py +1 -0
- synth_ai/cli/demo_apps/math/_common.py +16 -0
- synth_ai/cli/demo_apps/math/app.py +38 -0
- synth_ai/cli/demo_apps/math/config.toml +75 -0
- synth_ai/cli/demo_apps/math/deploy_modal.py +54 -0
- synth_ai/cli/demo_apps/math/modal_task_app.py +698 -0
- synth_ai/cli/demo_apps/math/task_app_entry.py +53 -0
- synth_ai/cli/demo_apps/mipro/main.py +271 -0
- synth_ai/cli/demo_apps/mipro/task_app.py +922 -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/{balance.py → infra/balance.py} +21 -3
- synth_ai/cli/infra/mcp.py +35 -0
- synth_ai/cli/infra/modal_app.py +36 -0
- synth_ai/cli/infra/setup.py +69 -0
- synth_ai/cli/infra/status.py +16 -0
- synth_ai/cli/infra/turso.py +77 -0
- synth_ai/cli/lib/__init__.py +10 -0
- synth_ai/cli/lib/agents.py +76 -0
- synth_ai/cli/lib/apps/modal_app.py +101 -0
- synth_ai/cli/lib/apps/task_app.py +642 -0
- synth_ai/cli/lib/bin.py +39 -0
- synth_ai/cli/lib/env.py +375 -0
- synth_ai/cli/lib/errors.py +85 -0
- synth_ai/cli/lib/modal.py +315 -0
- synth_ai/cli/lib/plotting.py +126 -0
- synth_ai/cli/lib/prompt_args.py +39 -0
- synth_ai/cli/lib/prompts.py +284 -0
- synth_ai/cli/lib/sqld.py +122 -0
- synth_ai/cli/lib/task_app_discovery.py +884 -0
- synth_ai/cli/lib/task_app_env.py +295 -0
- synth_ai/cli/lib/train_cfgs.py +300 -0
- synth_ai/cli/lib/tunnel_records.py +207 -0
- synth_ai/cli/local/__init__.py +14 -0
- synth_ai/cli/local/experiment_queue/__init__.py +72 -0
- synth_ai/cli/local/experiment_queue/api_schemas.py +221 -0
- synth_ai/cli/local/experiment_queue/celery_app.py +208 -0
- synth_ai/cli/local/experiment_queue/config.py +128 -0
- synth_ai/cli/local/experiment_queue/config_utils.py +272 -0
- synth_ai/cli/local/experiment_queue/database.py +175 -0
- synth_ai/cli/local/experiment_queue/dispatcher.py +119 -0
- synth_ai/cli/local/experiment_queue/models.py +231 -0
- synth_ai/cli/local/experiment_queue/progress_info.py +160 -0
- synth_ai/cli/local/experiment_queue/results.py +373 -0
- synth_ai/cli/local/experiment_queue/schemas.py +131 -0
- synth_ai/cli/local/experiment_queue/service.py +344 -0
- synth_ai/cli/local/experiment_queue/status.py +372 -0
- synth_ai/cli/local/experiment_queue/status_tracker.py +360 -0
- synth_ai/cli/local/experiment_queue/tasks.py +1984 -0
- synth_ai/cli/local/experiment_queue/trace_storage.py +65 -0
- synth_ai/cli/local/experiment_queue/validation.py +157 -0
- synth_ai/cli/local/session/__init__.py +92 -0
- synth_ai/cli/local/session/client.py +383 -0
- synth_ai/cli/local/session/constants.py +63 -0
- synth_ai/cli/local/session/exceptions.py +105 -0
- synth_ai/cli/local/session/manager.py +139 -0
- synth_ai/cli/local/session/models.py +89 -0
- synth_ai/cli/local/session/query.py +110 -0
- synth_ai/cli/root.py +150 -102
- synth_ai/cli/task_apps/__init__.py +37 -0
- synth_ai/cli/task_apps/commands.py +3145 -0
- synth_ai/cli/task_apps/deploy.py +7 -0
- synth_ai/cli/task_apps/list.py +26 -0
- synth_ai/cli/task_apps/main.py +36 -0
- synth_ai/cli/task_apps/modal_serve.py +11 -0
- synth_ai/cli/task_apps/serve.py +11 -0
- synth_ai/cli/training/__init__.py +8 -0
- synth_ai/cli/training/train.py +5 -0
- synth_ai/cli/training/train_cfg.py +34 -0
- synth_ai/cli/{watch.py → training/watch.py} +13 -18
- synth_ai/cli/turso.py +52 -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/{recent.py → utils/recent.py} +13 -7
- synth_ai/cli/{traces.py → utils/traces.py} +9 -5
- synth_ai/contracts/__init__.py +67 -0
- synth_ai/core/__init__.py +100 -0
- synth_ai/core/_utils/__init__.py +54 -0
- synth_ai/core/_utils/base_url.py +10 -0
- synth_ai/core/_utils/http.py +10 -0
- synth_ai/core/_utils/prompts.py +14 -0
- synth_ai/core/_utils/task_app_state.py +12 -0
- synth_ai/core/_utils/user_config.py +10 -0
- synth_ai/core/apps/common.py +116 -0
- synth_ai/core/auth.py +95 -0
- synth_ai/core/cfgs.py +240 -0
- synth_ai/core/config/__init__.py +16 -0
- synth_ai/core/config/base.py +168 -0
- synth_ai/core/config/resolver.py +89 -0
- synth_ai/core/env.py +231 -0
- synth_ai/core/errors.py +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/{tracing_v3 → core/tracing_v3}/__init__.py +5 -1
- synth_ai/{tracing_v3 → core/tracing_v3}/abstractions.py +21 -4
- synth_ai/core/tracing_v3/config.py +229 -0
- synth_ai/core/tracing_v3/constants.py +21 -0
- synth_ai/{tracing_v3 → core/tracing_v3}/db_config.py +42 -29
- synth_ai/{tracing_v3 → core/tracing_v3}/decorators.py +80 -45
- synth_ai/{tracing_v3 → core/tracing_v3}/examples/basic_usage.py +15 -9
- synth_ai/{tracing_v3 → core/tracing_v3}/hooks.py +6 -4
- synth_ai/{tracing_v3 → core/tracing_v3}/llm_call_record_helpers.py +161 -61
- synth_ai/{tracing_v3 → core/tracing_v3}/migration_helper.py +1 -2
- synth_ai/{tracing_v3 → core/tracing_v3}/replica_sync.py +12 -7
- synth_ai/core/tracing_v3/serialization.py +130 -0
- synth_ai/{tracing_v3 → core/tracing_v3}/session_tracer.py +88 -21
- synth_ai/{tracing_v3 → core/tracing_v3}/storage/base.py +99 -12
- synth_ai/core/tracing_v3/storage/config.py +109 -0
- synth_ai/{tracing_v3 → core/tracing_v3}/storage/factory.py +11 -9
- synth_ai/{tracing_v3 → core/tracing_v3}/storage/utils.py +15 -11
- 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/{tracing_v3 → core/tracing_v3}/turso/models.py +7 -3
- synth_ai/core/tracing_v3/turso/native_manager.py +1385 -0
- synth_ai/{tracing_v3 → core/tracing_v3}/utils.py +5 -4
- synth_ai/core/urls.py +18 -0
- synth_ai/core/user_config.py +137 -0
- synth_ai/core/uvicorn.py +222 -0
- synth_ai/data/__init__.py +83 -0
- synth_ai/data/enums.py +123 -0
- synth_ai/data/rewards.py +152 -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/products/graph_gepa/__init__.py +23 -0
- synth_ai/products/graph_gepa/converters/__init__.py +19 -0
- synth_ai/products/graph_gepa/converters/openai_sft.py +29 -0
- synth_ai/sdk/__init__.py +123 -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 +296 -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 +2199 -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 +187 -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/local_api.py +10 -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 +469 -0
- synth_ai/sdk/api/train/rl.py +441 -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 +351 -0
- synth_ai/sdk/api/train/utils.py +279 -0
- synth_ai/sdk/api/train/validators.py +2424 -0
- synth_ai/sdk/graphs/__init__.py +15 -0
- synth_ai/sdk/graphs/completions.py +570 -0
- synth_ai/{inference → sdk/inference}/__init__.py +0 -1
- 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 +14 -0
- synth_ai/sdk/judging/base.py +24 -0
- synth_ai/sdk/judging/client.py +40 -0
- synth_ai/sdk/judging/schemas.py +222 -0
- synth_ai/sdk/judging/types.py +42 -0
- synth_ai/sdk/learning/__init__.py +99 -0
- synth_ai/sdk/learning/algorithms.py +14 -0
- synth_ai/{learning → sdk/learning}/client.py +121 -30
- synth_ai/sdk/learning/config.py +5 -0
- synth_ai/{learning → sdk/learning}/constants.py +0 -2
- synth_ai/sdk/learning/context_learning_client.py +531 -0
- synth_ai/sdk/learning/context_learning_types.py +292 -0
- synth_ai/sdk/learning/ft_client.py +7 -0
- synth_ai/{learning → sdk/learning}/health.py +15 -9
- synth_ai/{learning → sdk/learning}/jobs.py +44 -47
- synth_ai/sdk/learning/prompt_extraction.py +334 -0
- synth_ai/sdk/learning/prompt_learning_client.py +455 -0
- synth_ai/sdk/learning/prompt_learning_types.py +186 -0
- synth_ai/{rl → sdk/learning/rl}/__init__.py +13 -8
- synth_ai/{learning/rl_client.py → sdk/learning/rl/client.py} +89 -77
- synth_ai/sdk/learning/rl/config.py +31 -0
- synth_ai/{rl → sdk/learning/rl}/contracts.py +5 -14
- synth_ai/{rl → sdk/learning/rl}/env_keys.py +45 -16
- synth_ai/sdk/learning/rl/secrets.py +13 -0
- synth_ai/sdk/learning/rl_client.py +5 -0
- synth_ai/sdk/learning/sft/__init__.py +29 -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/sse.py +57 -0
- synth_ai/sdk/learning/validators.py +52 -0
- synth_ai/sdk/localapi/__init__.py +40 -0
- synth_ai/sdk/localapi/apps/__init__.py +28 -0
- synth_ai/sdk/localapi/client.py +10 -0
- synth_ai/sdk/localapi/contracts.py +10 -0
- synth_ai/sdk/localapi/helpers.py +519 -0
- synth_ai/sdk/localapi/rollouts.py +87 -0
- synth_ai/sdk/localapi/server.py +29 -0
- synth_ai/sdk/localapi/template.py +70 -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 +713 -0
- synth_ai/sdk/streaming/types.py +112 -0
- synth_ai/sdk/task/__init__.py +164 -0
- synth_ai/sdk/task/apps/__init__.py +169 -0
- synth_ai/sdk/task/auth.py +165 -0
- synth_ai/sdk/task/client.py +175 -0
- synth_ai/sdk/task/config.py +257 -0
- synth_ai/sdk/task/contracts.py +219 -0
- synth_ai/sdk/task/datasets.py +108 -0
- synth_ai/sdk/task/errors.py +50 -0
- synth_ai/sdk/task/health.py +34 -0
- synth_ai/sdk/task/in_process.py +1190 -0
- synth_ai/sdk/task/in_process_runner.py +314 -0
- synth_ai/sdk/task/inference_api.py +299 -0
- synth_ai/sdk/task/json.py +111 -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/rubrics.py +219 -0
- synth_ai/sdk/task/server.py +631 -0
- synth_ai/sdk/task/trace_correlation_helpers.py +539 -0
- synth_ai/sdk/task/tracing_utils.py +95 -0
- synth_ai/sdk/task/validators.py +441 -0
- synth_ai/sdk/task/vendors.py +59 -0
- synth_ai/sdk/training/__init__.py +102 -0
- synth_ai/sdk/tunnels/__init__.py +83 -0
- synth_ai/sdk/tunnels/cleanup.py +83 -0
- synth_ai/sdk/tunnels/ports.py +120 -0
- synth_ai/utils/__init__.py +213 -0
- synth_ai-0.4.3.dist-info/METADATA +262 -0
- synth_ai-0.4.3.dist-info/RECORD +370 -0
- {synth_ai-0.2.6.dev1.dist-info → synth_ai-0.4.3.dist-info}/entry_points.txt +0 -1
- synth_ai/cli/calc.py +0 -69
- synth_ai/cli/demo.py +0 -131
- synth_ai/cli/legacy_root_backup.py +0 -470
- synth_ai/cli/man.py +0 -106
- synth_ai/cli/rl_demo.py +0 -137
- synth_ai/cli/status.py +0 -133
- synth_ai/config/base_url.py +0 -98
- synth_ai/core/experiment.py +0 -15
- synth_ai/core/system.py +0 -15
- synth_ai/demos/core/__init__.py +0 -1
- synth_ai/demos/core/cli.py +0 -685
- synth_ai/demos/demo_task_apps/__init__.py +0 -1
- synth_ai/demos/demo_task_apps/math/config.toml +0 -44
- synth_ai/demos/demo_task_apps/math/deploy_task_app.sh +0 -22
- 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 -294
- 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 -724
- 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 -404
- 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/sokoban/units/astar_common.py +0 -95
- 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 -364
- synth_ai/environments/service/app.py +0 -91
- synth_ai/environments/service/core_routes.py +0 -1020
- 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 -80
- synth_ai/environments/tasks/filters.py +0 -41
- synth_ai/environments/tasks/utils.py +0 -91
- synth_ai/environments/v0_observability/history.py +0 -3
- synth_ai/environments/v0_observability/log.py +0 -2
- synth_ai/evals/base.py +0 -15
- synth_ai/experimental/synth_oss.py +0 -446
- synth_ai/http.py +0 -102
- synth_ai/inference/client.py +0 -20
- synth_ai/install_sqld.sh +0 -40
- synth_ai/jobs/client.py +0 -246
- synth_ai/learning/__init__.py +0 -24
- synth_ai/learning/config.py +0 -43
- synth_ai/learning/filtering.py +0 -0
- synth_ai/learning/ft_client.py +0 -59
- synth_ai/learning/offline/dpo.py +0 -0
- synth_ai/learning/offline/providers.py +0 -7
- synth_ai/learning/offline/sft.py +0 -0
- synth_ai/learning/offline/shared.py +0 -0
- synth_ai/learning/online/grpo.py +0 -0
- synth_ai/learning/online/irft.py +0 -0
- synth_ai/learning/prompts/banking77_injection_eval.py +0 -168
- synth_ai/learning/prompts/gepa.py +0 -0
- synth_ai/learning/prompts/hello_world_in_context_injection_ex.py +0 -213
- synth_ai/learning/prompts/mipro.py +0 -289
- synth_ai/learning/prompts/random_search.py +0 -246
- synth_ai/learning/prompts/run_mipro_banking77.py +0 -172
- synth_ai/learning/prompts/run_random_search_banking77.py +0 -324
- synth_ai/learning/sse.py +0 -58
- synth_ai/learning/validators.py +0 -48
- synth_ai/lm/__init__.py +0 -51
- synth_ai/lm/caching/constants.py +0 -6
- synth_ai/lm/caching/dbs.py +0 -0
- synth_ai/lm/caching/ephemeral.py +0 -102
- synth_ai/lm/caching/handler.py +0 -137
- synth_ai/lm/caching/initialize.py +0 -11
- synth_ai/lm/caching/persistent.py +0 -114
- synth_ai/lm/config.py +0 -110
- synth_ai/lm/constants.py +0 -32
- synth_ai/lm/core/__init__.py +0 -8
- synth_ai/lm/core/all.py +0 -73
- synth_ai/lm/core/exceptions.py +0 -7
- synth_ai/lm/core/main.py +0 -319
- synth_ai/lm/core/main_v3.py +0 -594
- synth_ai/lm/core/synth_models.py +0 -48
- synth_ai/lm/core/vendor_clients.py +0 -188
- synth_ai/lm/cost/__init__.py +0 -0
- synth_ai/lm/cost/monitor.py +0 -1
- synth_ai/lm/cost/statefulness.py +0 -1
- synth_ai/lm/injection.py +0 -80
- synth_ai/lm/overrides.py +0 -206
- synth_ai/lm/provider_support/__init__.py +0 -8
- synth_ai/lm/provider_support/anthropic.py +0 -972
- synth_ai/lm/provider_support/openai.py +0 -1139
- synth_ai/lm/provider_support/suppress_logging.py +0 -31
- synth_ai/lm/structured_outputs/__init__.py +0 -0
- synth_ai/lm/structured_outputs/handler.py +0 -440
- synth_ai/lm/structured_outputs/inject.py +0 -297
- synth_ai/lm/structured_outputs/rehabilitate.py +0 -185
- synth_ai/lm/tools/__init__.py +0 -3
- synth_ai/lm/tools/base.py +0 -172
- synth_ai/lm/unified_interface.py +0 -202
- synth_ai/lm/vendors/__init__.py +0 -0
- synth_ai/lm/vendors/base.py +0 -81
- synth_ai/lm/vendors/core/__init__.py +0 -0
- synth_ai/lm/vendors/core/anthropic_api.py +0 -387
- synth_ai/lm/vendors/core/gemini_api.py +0 -292
- synth_ai/lm/vendors/core/mistral_api.py +0 -322
- synth_ai/lm/vendors/core/openai_api.py +0 -220
- synth_ai/lm/vendors/core/synth_dev_api.py +0 -0
- synth_ai/lm/vendors/local/__init__.py +0 -0
- synth_ai/lm/vendors/local/ollama.py +0 -0
- synth_ai/lm/vendors/openai_standard.py +0 -780
- synth_ai/lm/vendors/openai_standard_responses.py +0 -256
- synth_ai/lm/vendors/retries.py +0 -22
- synth_ai/lm/vendors/supported/__init__.py +0 -0
- synth_ai/lm/vendors/supported/custom_endpoint.py +0 -417
- synth_ai/lm/vendors/supported/deepseek.py +0 -69
- synth_ai/lm/vendors/supported/grok.py +0 -75
- synth_ai/lm/vendors/supported/groq.py +0 -16
- synth_ai/lm/vendors/supported/ollama.py +0 -15
- synth_ai/lm/vendors/supported/openrouter.py +0 -74
- synth_ai/lm/vendors/supported/together.py +0 -11
- synth_ai/lm/vendors/synth_client.py +0 -808
- synth_ai/lm/warmup.py +0 -186
- synth_ai/rl/secrets.py +0 -19
- synth_ai/scripts/verify_rewards.py +0 -100
- synth_ai/task/__init__.py +0 -10
- synth_ai/task/contracts.py +0 -120
- synth_ai/task/health.py +0 -28
- synth_ai/task/validators.py +0 -12
- synth_ai/tracing/__init__.py +0 -30
- synth_ai/tracing_v1/__init__.py +0 -33
- synth_ai/tracing_v3/config.py +0 -84
- synth_ai/tracing_v3/storage/config.py +0 -62
- synth_ai/tracing_v3/turso/__init__.py +0 -25
- synth_ai/tracing_v3/turso/daemon.py +0 -144
- synth_ai/tracing_v3/turso/manager.py +0 -760
- 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 -140
- synth_ai/v0/tracing/context.py +0 -146
- synth_ai/v0/tracing/decorators.py +0 -680
- 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 -510
- 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 -140
- synth_ai/v0/tracing_v1/context.py +0 -146
- synth_ai/v0/tracing_v1/decorators.py +0 -701
- 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 -525
- synth_ai/v0/tracing_v1/utils.py +0 -9
- synth_ai/zyk/__init__.py +0 -30
- synth_ai-0.2.6.dev1.dist-info/METADATA +0 -106
- synth_ai-0.2.6.dev1.dist-info/RECORD +0 -416
- /synth_ai/{demos → cli/demo_apps}/demo_task_apps/math/__init__.py +0 -0
- /synth_ai/{lm/caching → core/apps}/__init__.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}/core.py +0 -0
- /synth_ai/{learning → sdk/learning}/gateway.py +0 -0
- {synth_ai-0.2.6.dev1.dist-info → synth_ai-0.4.3.dist-info}/WHEEL +0 -0
- {synth_ai-0.2.6.dev1.dist-info → synth_ai-0.4.3.dist-info}/licenses/LICENSE +0 -0
- {synth_ai-0.2.6.dev1.dist-info → synth_ai-0.4.3.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
"""Queue management commands for running Celery workers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import shutil
|
|
7
|
+
import subprocess
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
import click
|
|
11
|
+
|
|
12
|
+
# Clear config cache if env vars are set (must happen before other imports)
|
|
13
|
+
if os.getenv("EXPERIMENT_QUEUE_DB_PATH") or os.getenv("EXPERIMENT_QUEUE_TRAIN_CMD"):
|
|
14
|
+
from synth_ai.cli.local.experiment_queue import config as queue_config
|
|
15
|
+
|
|
16
|
+
queue_config.reset_config_cache()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _require_celery_binary() -> str:
|
|
20
|
+
celery_path = shutil.which("celery")
|
|
21
|
+
if not celery_path:
|
|
22
|
+
# Check if we're in a virtual environment and celery is installed there
|
|
23
|
+
venv_bin = os.environ.get("VIRTUAL_ENV")
|
|
24
|
+
if venv_bin:
|
|
25
|
+
venv_celery = Path(venv_bin) / "bin" / "celery"
|
|
26
|
+
if venv_celery.exists():
|
|
27
|
+
celery_path = str(venv_celery)
|
|
28
|
+
# Also check common uv venv locations
|
|
29
|
+
if not celery_path:
|
|
30
|
+
import sys
|
|
31
|
+
if hasattr(sys, "executable"):
|
|
32
|
+
venv_base = Path(sys.executable).parent.parent
|
|
33
|
+
uv_celery = venv_base / "bin" / "celery"
|
|
34
|
+
if uv_celery.exists():
|
|
35
|
+
celery_path = str(uv_celery)
|
|
36
|
+
if not celery_path:
|
|
37
|
+
raise click.ClickException(
|
|
38
|
+
"Celery executable not found on PATH. Install it with `uv pip install celery` or ensure it is available."
|
|
39
|
+
)
|
|
40
|
+
return celery_path
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _background_log_file() -> Path:
|
|
44
|
+
log_dir = Path("logs")
|
|
45
|
+
log_dir.mkdir(parents=True, exist_ok=True)
|
|
46
|
+
return log_dir / "experiment_queue_worker.log"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _worker_lock_file() -> Path:
|
|
50
|
+
"""Return path to lock file for ensuring only one worker runs."""
|
|
51
|
+
lock_dir = Path("logs")
|
|
52
|
+
lock_dir.mkdir(parents=True, exist_ok=True)
|
|
53
|
+
return lock_dir / "experiment_queue_worker.lock"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _kill_all_existing_workers() -> int:
|
|
57
|
+
"""Kill ALL existing Celery workers for experiment queue.
|
|
58
|
+
|
|
59
|
+
Returns the number of workers killed.
|
|
60
|
+
"""
|
|
61
|
+
killed = 0
|
|
62
|
+
try:
|
|
63
|
+
import psutil # type: ignore[import-untyped]
|
|
64
|
+
for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
|
|
65
|
+
try:
|
|
66
|
+
cmdline = proc.info.get('cmdline', [])
|
|
67
|
+
if not cmdline:
|
|
68
|
+
continue
|
|
69
|
+
cmdline_str = ' '.join(cmdline)
|
|
70
|
+
# Check if this is a Celery worker for our experiment queue
|
|
71
|
+
if ('celery' in cmdline_str.lower() and
|
|
72
|
+
'synth_ai.experiment_queue' in cmdline_str):
|
|
73
|
+
click.echo(f"Killing existing worker (PID: {proc.info['pid']})", err=True)
|
|
74
|
+
proc.terminate()
|
|
75
|
+
try:
|
|
76
|
+
proc.wait(timeout=3)
|
|
77
|
+
except psutil.TimeoutExpired:
|
|
78
|
+
proc.kill()
|
|
79
|
+
proc.wait()
|
|
80
|
+
killed += 1
|
|
81
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
82
|
+
pass
|
|
83
|
+
except ImportError:
|
|
84
|
+
# Fallback to pgrep/pkill if psutil not available
|
|
85
|
+
import subprocess
|
|
86
|
+
try:
|
|
87
|
+
result = subprocess.run(
|
|
88
|
+
['pgrep', '-f', 'celery.*synth_ai.experiment_queue'],
|
|
89
|
+
capture_output=True,
|
|
90
|
+
text=True
|
|
91
|
+
)
|
|
92
|
+
if result.returncode == 0:
|
|
93
|
+
pids = result.stdout.strip().split('\n')
|
|
94
|
+
for pid in pids:
|
|
95
|
+
if pid.strip():
|
|
96
|
+
click.echo(f"Killing existing worker (PID: {pid})", err=True)
|
|
97
|
+
try:
|
|
98
|
+
subprocess.run(['kill', '-TERM', pid], timeout=3)
|
|
99
|
+
import time as time_module # Import here to avoid F823 false positive
|
|
100
|
+
time_module.sleep(1)
|
|
101
|
+
subprocess.run(['kill', '-9', pid], timeout=1)
|
|
102
|
+
killed += 1
|
|
103
|
+
except Exception:
|
|
104
|
+
pass
|
|
105
|
+
except Exception:
|
|
106
|
+
pass
|
|
107
|
+
|
|
108
|
+
# Remove lock file if it exists
|
|
109
|
+
lock_file = _worker_lock_file()
|
|
110
|
+
if lock_file.exists():
|
|
111
|
+
lock_file.unlink(missing_ok=True)
|
|
112
|
+
|
|
113
|
+
if killed > 0:
|
|
114
|
+
import time as time_module
|
|
115
|
+
time_module.sleep(2) # Give processes time to fully terminate
|
|
116
|
+
|
|
117
|
+
return killed
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _get_running_workers() -> list[dict]:
|
|
121
|
+
"""Get all running experiment queue workers.
|
|
122
|
+
|
|
123
|
+
Returns list of dicts with 'pid', 'cmdline', 'db_path', 'broker_url' keys.
|
|
124
|
+
"""
|
|
125
|
+
workers = []
|
|
126
|
+
try:
|
|
127
|
+
import psutil # type: ignore[import-untyped]
|
|
128
|
+
for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
|
|
129
|
+
try:
|
|
130
|
+
cmdline = proc.info.get('cmdline', [])
|
|
131
|
+
if not cmdline:
|
|
132
|
+
continue
|
|
133
|
+
cmdline_str = ' '.join(cmdline)
|
|
134
|
+
# Check if this is a Celery worker for our experiment queue
|
|
135
|
+
if ('celery' in cmdline_str.lower() and
|
|
136
|
+
'synth_ai.experiment_queue' in cmdline_str):
|
|
137
|
+
env = proc.environ()
|
|
138
|
+
workers.append({
|
|
139
|
+
'pid': proc.info['pid'],
|
|
140
|
+
'cmdline': cmdline_str,
|
|
141
|
+
'db_path': env.get('EXPERIMENT_QUEUE_DB_PATH', 'N/A'),
|
|
142
|
+
'broker_url': env.get('EXPERIMENT_QUEUE_BROKER_URL', 'N/A'),
|
|
143
|
+
'result_backend_url': env.get('EXPERIMENT_QUEUE_RESULT_BACKEND_URL', 'N/A'),
|
|
144
|
+
})
|
|
145
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
146
|
+
pass
|
|
147
|
+
except ImportError:
|
|
148
|
+
# Fallback to pgrep if psutil not available
|
|
149
|
+
try:
|
|
150
|
+
result = subprocess.run(
|
|
151
|
+
['pgrep', '-f', 'celery.*synth_ai.experiment_queue'],
|
|
152
|
+
capture_output=True,
|
|
153
|
+
text=True
|
|
154
|
+
)
|
|
155
|
+
if result.returncode == 0:
|
|
156
|
+
pids = result.stdout.strip().split('\n')
|
|
157
|
+
for pid in pids:
|
|
158
|
+
if pid.strip():
|
|
159
|
+
workers.append({
|
|
160
|
+
'pid': int(pid.strip()),
|
|
161
|
+
'cmdline': 'N/A (psutil not available)',
|
|
162
|
+
'db_path': 'N/A',
|
|
163
|
+
'broker_url': 'N/A',
|
|
164
|
+
'result_backend_url': 'N/A',
|
|
165
|
+
})
|
|
166
|
+
except Exception:
|
|
167
|
+
pass
|
|
168
|
+
|
|
169
|
+
return workers
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def _check_existing_worker() -> bool:
|
|
173
|
+
"""Check if a worker is already running by checking lock file."""
|
|
174
|
+
lock_file = _worker_lock_file()
|
|
175
|
+
if not lock_file.exists():
|
|
176
|
+
return False
|
|
177
|
+
|
|
178
|
+
try:
|
|
179
|
+
# Read PID from lock file
|
|
180
|
+
pid = int(lock_file.read_text().strip())
|
|
181
|
+
# Check if process is still running
|
|
182
|
+
import psutil # type: ignore[import-untyped]
|
|
183
|
+
try:
|
|
184
|
+
proc = psutil.Process(pid)
|
|
185
|
+
# Check if it's actually a celery worker
|
|
186
|
+
cmdline = ' '.join(proc.cmdline())
|
|
187
|
+
if 'celery' in cmdline.lower() and 'synth_ai.experiment_queue' in cmdline:
|
|
188
|
+
return True
|
|
189
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
|
190
|
+
# Process doesn't exist or we can't access it - remove stale lock
|
|
191
|
+
lock_file.unlink(missing_ok=True)
|
|
192
|
+
return False
|
|
193
|
+
except (ValueError, FileNotFoundError):
|
|
194
|
+
# Invalid lock file - remove it
|
|
195
|
+
lock_file.unlink(missing_ok=True)
|
|
196
|
+
return False
|
|
197
|
+
|
|
198
|
+
return False
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
@click.command("status")
|
|
202
|
+
def status_cmd() -> None:
|
|
203
|
+
"""Show status of experiment queue workers."""
|
|
204
|
+
workers = _get_running_workers()
|
|
205
|
+
|
|
206
|
+
# Get current config
|
|
207
|
+
db_path = os.getenv("EXPERIMENT_QUEUE_DB_PATH", "NOT SET")
|
|
208
|
+
broker_url = os.getenv("EXPERIMENT_QUEUE_BROKER_URL", "redis://localhost:6379/0 (default)")
|
|
209
|
+
result_backend_url = os.getenv("EXPERIMENT_QUEUE_RESULT_BACKEND_URL", "redis://localhost:6379/1 (default)")
|
|
210
|
+
|
|
211
|
+
click.echo("=" * 60)
|
|
212
|
+
click.echo("Experiment Queue Status")
|
|
213
|
+
click.echo("=" * 60)
|
|
214
|
+
click.echo()
|
|
215
|
+
|
|
216
|
+
click.echo("Configuration:")
|
|
217
|
+
click.echo(f" EXPERIMENT_QUEUE_DB_PATH: {db_path}")
|
|
218
|
+
click.echo(f" EXPERIMENT_QUEUE_BROKER_URL: {broker_url}")
|
|
219
|
+
click.echo(f" EXPERIMENT_QUEUE_RESULT_BACKEND_URL: {result_backend_url}")
|
|
220
|
+
click.echo()
|
|
221
|
+
|
|
222
|
+
if not workers:
|
|
223
|
+
click.echo("❌ No workers running")
|
|
224
|
+
click.echo()
|
|
225
|
+
click.echo("Start a worker with: synth-ai queue start")
|
|
226
|
+
return
|
|
227
|
+
|
|
228
|
+
click.echo(f"✅ {len(workers)} worker(s) running:")
|
|
229
|
+
click.echo()
|
|
230
|
+
for i, worker in enumerate(workers, 1):
|
|
231
|
+
click.echo(f"Worker {i}:")
|
|
232
|
+
click.echo(f" PID: {worker['pid']}")
|
|
233
|
+
click.echo(f" Database: {worker['db_path']}")
|
|
234
|
+
click.echo(f" Broker: {worker['broker_url']}")
|
|
235
|
+
click.echo(f" Result Backend: {worker['result_backend_url']}")
|
|
236
|
+
if i < len(workers):
|
|
237
|
+
click.echo()
|
|
238
|
+
|
|
239
|
+
# Check for database path mismatches
|
|
240
|
+
if db_path != "NOT SET":
|
|
241
|
+
mismatches = [w for w in workers if w['db_path'] != db_path and w['db_path'] != 'N/A']
|
|
242
|
+
if mismatches:
|
|
243
|
+
click.echo()
|
|
244
|
+
click.echo("⚠️ WARNING: Some workers are using different database paths!")
|
|
245
|
+
for worker in mismatches:
|
|
246
|
+
click.echo(f" Worker PID {worker['pid']}: {worker['db_path']} (expected: {db_path})")
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
@click.command("stop")
|
|
250
|
+
def stop_cmd() -> None:
|
|
251
|
+
"""Stop all running experiment queue workers."""
|
|
252
|
+
workers = _get_running_workers()
|
|
253
|
+
if not workers:
|
|
254
|
+
click.echo("No experiment queue workers running.")
|
|
255
|
+
return
|
|
256
|
+
|
|
257
|
+
click.echo(f"Found {len(workers)} worker(s) to stop...")
|
|
258
|
+
killed = _kill_all_existing_workers()
|
|
259
|
+
|
|
260
|
+
if killed > 0:
|
|
261
|
+
click.echo(f"✅ Stopped {killed} worker(s)")
|
|
262
|
+
else:
|
|
263
|
+
click.echo("⚠️ No workers were stopped (they may have already exited)")
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
@click.group("queue", invoke_without_command=True)
|
|
267
|
+
@click.pass_context
|
|
268
|
+
def queue_group(ctx: click.Context) -> None:
|
|
269
|
+
"""Manage the experiment queue Celery worker.
|
|
270
|
+
|
|
271
|
+
Use subcommands to start, stop, or check status of the worker.
|
|
272
|
+
"""
|
|
273
|
+
if ctx.invoked_subcommand is None:
|
|
274
|
+
# Default to status if no subcommand
|
|
275
|
+
ctx.invoke(status_cmd)
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
@queue_group.command("start")
|
|
279
|
+
@click.option(
|
|
280
|
+
"--concurrency",
|
|
281
|
+
default=None,
|
|
282
|
+
type=int,
|
|
283
|
+
help="Worker concurrency (default: 5, or EXPERIMENT_QUEUE_WORKER_CONCURRENCY env var).",
|
|
284
|
+
)
|
|
285
|
+
@click.option(
|
|
286
|
+
"--loglevel",
|
|
287
|
+
default="info",
|
|
288
|
+
show_default=True,
|
|
289
|
+
type=click.Choice(["debug", "info", "warning", "error", "critical"], case_sensitive=False),
|
|
290
|
+
help="Logging level for Celery worker and task queue (debug/info/warning/error/critical).",
|
|
291
|
+
)
|
|
292
|
+
@click.option(
|
|
293
|
+
"--pool",
|
|
294
|
+
default="prefork",
|
|
295
|
+
show_default=True,
|
|
296
|
+
type=click.Choice(["solo", "prefork", "threads", "gevent", "eventlet"]),
|
|
297
|
+
help="Worker pool type (default 'prefork' for Redis broker).",
|
|
298
|
+
)
|
|
299
|
+
@click.option(
|
|
300
|
+
"--background/--foreground",
|
|
301
|
+
default=True,
|
|
302
|
+
show_default=True,
|
|
303
|
+
help="Run worker in background (default) or foreground.",
|
|
304
|
+
)
|
|
305
|
+
@click.option(
|
|
306
|
+
"--beat/--no-beat",
|
|
307
|
+
default=True,
|
|
308
|
+
show_default=True,
|
|
309
|
+
help="Run Celery Beat scheduler in the same process (for periodic queue checks).",
|
|
310
|
+
)
|
|
311
|
+
@click.option(
|
|
312
|
+
"--local/--no-local",
|
|
313
|
+
default=None,
|
|
314
|
+
help="Use local backend (localhost:8000) instead of production. "
|
|
315
|
+
"Sets EXPERIMENT_QUEUE_LOCAL=true. Default: use production backend.",
|
|
316
|
+
)
|
|
317
|
+
@click.option(
|
|
318
|
+
"--extra",
|
|
319
|
+
multiple=True,
|
|
320
|
+
help="Extra arguments forwarded to celery worker (use multiple times).",
|
|
321
|
+
)
|
|
322
|
+
def start_cmd(
|
|
323
|
+
concurrency: int | None,
|
|
324
|
+
loglevel: str,
|
|
325
|
+
pool: str,
|
|
326
|
+
background: bool,
|
|
327
|
+
beat: bool,
|
|
328
|
+
local: bool | None,
|
|
329
|
+
extra: tuple[str, ...],
|
|
330
|
+
) -> None:
|
|
331
|
+
"""Start the experiment queue Celery worker.
|
|
332
|
+
|
|
333
|
+
The periodic queue check task runs every 5 seconds to dispatch queued jobs.
|
|
334
|
+
Use --beat to run Beat scheduler in the same process (default: enabled).
|
|
335
|
+
|
|
336
|
+
Backend URL Configuration:
|
|
337
|
+
- Default: Production backend (https://api.usesynth.ai/api)
|
|
338
|
+
- Use --local flag to connect to local backend (http://localhost:8000/api)
|
|
339
|
+
- Override with EXPERIMENT_QUEUE_BACKEND_URL env var for custom URL
|
|
340
|
+
|
|
341
|
+
Database Configuration:
|
|
342
|
+
- Uses EXPERIMENT_QUEUE_DB_PATH if set, otherwise defaults to ~/.synth_ai/experiment_queue.db
|
|
343
|
+
|
|
344
|
+
Concurrency:
|
|
345
|
+
- Defaults to 5 (or EXPERIMENT_QUEUE_WORKER_CONCURRENCY env var), allowing up to 5
|
|
346
|
+
experiments/jobs to run in parallel. Override with --concurrency flag.
|
|
347
|
+
|
|
348
|
+
Logging:
|
|
349
|
+
- Use --loglevel to control verbosity (debug/info/warning/error/critical)
|
|
350
|
+
- Controls both Celery worker logs and task queue internal logs (poller, etc.)
|
|
351
|
+
- Default: info (shows INFO and above)
|
|
352
|
+
- Use debug for verbose output including API polling details
|
|
353
|
+
|
|
354
|
+
Examples:
|
|
355
|
+
# Start worker with production backend (default)
|
|
356
|
+
synth-ai queue start
|
|
357
|
+
|
|
358
|
+
# Start worker with local backend
|
|
359
|
+
synth-ai queue start --local
|
|
360
|
+
|
|
361
|
+
# Start worker with verbose logging (debug level)
|
|
362
|
+
synth-ai queue start --loglevel debug
|
|
363
|
+
|
|
364
|
+
# Start worker with custom backend URL
|
|
365
|
+
EXPERIMENT_QUEUE_BACKEND_URL=http://localhost:8000/api synth-ai queue start
|
|
366
|
+
"""
|
|
367
|
+
# Determine concurrency: flag > env var > default
|
|
368
|
+
if concurrency is None:
|
|
369
|
+
concurrency = int(os.getenv("EXPERIMENT_QUEUE_WORKER_CONCURRENCY", "5"))
|
|
370
|
+
# CRITICAL: Kill ALL existing workers to ensure only one instance
|
|
371
|
+
killed = _kill_all_existing_workers()
|
|
372
|
+
if killed > 0:
|
|
373
|
+
click.echo(f"Killed {killed} existing worker(s)", err=True)
|
|
374
|
+
|
|
375
|
+
# CRITICAL: Clear config cache before starting worker to ensure fresh config
|
|
376
|
+
from synth_ai.cli.local.experiment_queue import config as queue_config
|
|
377
|
+
queue_config.reset_config_cache()
|
|
378
|
+
|
|
379
|
+
# Load config to get database path (uses EXPERIMENT_QUEUE_DB_PATH if set, otherwise default)
|
|
380
|
+
config = queue_config.load_config()
|
|
381
|
+
db_path_resolved = config.sqlite_path.resolve()
|
|
382
|
+
|
|
383
|
+
# Log which path is being used
|
|
384
|
+
db_path_env = os.getenv("EXPERIMENT_QUEUE_DB_PATH")
|
|
385
|
+
if db_path_env:
|
|
386
|
+
click.echo(f"Using database from EXPERIMENT_QUEUE_DB_PATH: {db_path_resolved}", err=True)
|
|
387
|
+
else:
|
|
388
|
+
click.echo(f"Using default database path: {db_path_resolved}", err=True)
|
|
389
|
+
|
|
390
|
+
# Ensure parent directory exists
|
|
391
|
+
db_path_resolved.parent.mkdir(parents=True, exist_ok=True)
|
|
392
|
+
|
|
393
|
+
# CRITICAL: Verify this is the ONLY database path being used
|
|
394
|
+
# Check for any other workers using different database paths
|
|
395
|
+
try:
|
|
396
|
+
import psutil # type: ignore[import-untyped]
|
|
397
|
+
for proc in psutil.process_iter(['pid', 'cmdline']):
|
|
398
|
+
try:
|
|
399
|
+
cmdline = proc.info.get('cmdline', [])
|
|
400
|
+
if not cmdline:
|
|
401
|
+
continue
|
|
402
|
+
cmdline_str = ' '.join(cmdline)
|
|
403
|
+
if ('celery' in cmdline_str.lower() and
|
|
404
|
+
'synth_ai.experiment_queue' in cmdline_str):
|
|
405
|
+
# Check env vars of this process
|
|
406
|
+
env = proc.environ()
|
|
407
|
+
other_db = env.get('EXPERIMENT_QUEUE_DB_PATH')
|
|
408
|
+
if other_db and Path(other_db).resolve() != db_path_resolved:
|
|
409
|
+
raise click.ClickException(
|
|
410
|
+
f"Another worker is using different database: {other_db} "
|
|
411
|
+
f"(this worker: {db_path_resolved}). "
|
|
412
|
+
f"All workers must use the same database path."
|
|
413
|
+
)
|
|
414
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
|
415
|
+
pass
|
|
416
|
+
except ImportError:
|
|
417
|
+
pass # psutil not available, skip check
|
|
418
|
+
|
|
419
|
+
celery_bin = _require_celery_binary()
|
|
420
|
+
base_cmd = [
|
|
421
|
+
celery_bin,
|
|
422
|
+
"-A",
|
|
423
|
+
"synth_ai.cli.local.experiment_queue.celery_app",
|
|
424
|
+
"worker",
|
|
425
|
+
"--loglevel",
|
|
426
|
+
loglevel,
|
|
427
|
+
"--concurrency",
|
|
428
|
+
str(concurrency),
|
|
429
|
+
"--pool",
|
|
430
|
+
pool,
|
|
431
|
+
]
|
|
432
|
+
if beat:
|
|
433
|
+
base_cmd.append("--beat")
|
|
434
|
+
if extra:
|
|
435
|
+
base_cmd.extend(extra)
|
|
436
|
+
|
|
437
|
+
# Lock file check is now redundant since we kill all workers above
|
|
438
|
+
# But keep it as a safety check
|
|
439
|
+
if _check_existing_worker():
|
|
440
|
+
lock_file = _worker_lock_file()
|
|
441
|
+
# This shouldn't happen since we killed workers above, but be safe
|
|
442
|
+
click.echo("WARNING: Lock file exists but worker should be killed", err=True)
|
|
443
|
+
lock_file.unlink(missing_ok=True)
|
|
444
|
+
|
|
445
|
+
env = os.environ.copy()
|
|
446
|
+
# Ensure EXPERIMENT_QUEUE_DB_PATH is explicitly set in worker environment
|
|
447
|
+
# Use the resolved path from config (either from env var or default)
|
|
448
|
+
env["EXPERIMENT_QUEUE_DB_PATH"] = str(db_path_resolved)
|
|
449
|
+
|
|
450
|
+
# Set Python logging level for task queue loggers (poller, etc.)
|
|
451
|
+
# This controls our custom loggers, while --loglevel controls Celery's logger
|
|
452
|
+
env["EXPERIMENT_QUEUE_LOG_LEVEL"] = loglevel.upper()
|
|
453
|
+
|
|
454
|
+
# Set EXPERIMENT_QUEUE_LOCAL if --local flag is provided
|
|
455
|
+
if local is True:
|
|
456
|
+
env["EXPERIMENT_QUEUE_LOCAL"] = "true"
|
|
457
|
+
click.echo("Using local backend (localhost:8000)", err=True)
|
|
458
|
+
elif local is False:
|
|
459
|
+
# Explicitly unset if --no-local is used
|
|
460
|
+
env.pop("EXPERIMENT_QUEUE_LOCAL", None)
|
|
461
|
+
click.echo("Using production backend (api.usesynth.ai)", err=True)
|
|
462
|
+
else:
|
|
463
|
+
# Use existing env var or default (production)
|
|
464
|
+
if "EXPERIMENT_QUEUE_LOCAL" not in env:
|
|
465
|
+
click.echo("Using production backend (api.usesynth.ai)", err=True)
|
|
466
|
+
|
|
467
|
+
# Create lock file with current PID before starting worker
|
|
468
|
+
lock_file = _worker_lock_file()
|
|
469
|
+
lock_file.write_text(str(os.getpid()))
|
|
470
|
+
|
|
471
|
+
def cleanup_lock():
|
|
472
|
+
"""Remove lock file on exit."""
|
|
473
|
+
from contextlib import suppress
|
|
474
|
+
with suppress(Exception):
|
|
475
|
+
lock_file.unlink(missing_ok=True)
|
|
476
|
+
|
|
477
|
+
import atexit
|
|
478
|
+
atexit.register(cleanup_lock)
|
|
479
|
+
|
|
480
|
+
if background:
|
|
481
|
+
log_path = _background_log_file()
|
|
482
|
+
with open(log_path, "ab") as handle:
|
|
483
|
+
proc = subprocess.Popen(
|
|
484
|
+
base_cmd,
|
|
485
|
+
stdout=handle,
|
|
486
|
+
stderr=subprocess.STDOUT,
|
|
487
|
+
start_new_session=True,
|
|
488
|
+
env=env,
|
|
489
|
+
)
|
|
490
|
+
click.echo(f"Started experiment queue worker (pid={proc.pid}) in background.")
|
|
491
|
+
click.echo(f"Logs streaming to {log_path}")
|
|
492
|
+
else:
|
|
493
|
+
click.echo("Starting experiment queue worker (foreground)...")
|
|
494
|
+
subprocess.run(base_cmd, check=True, env=env)
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
# Register subcommands (already registered via decorators, but ensure they're all added)
|
|
498
|
+
queue_group.add_command(stop_cmd, name="stop")
|
|
499
|
+
queue_group.add_command(status_cmd, name="status")
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
def register(cli: click.Group) -> None:
|
|
503
|
+
"""Register queue command with CLI."""
|
|
504
|
+
cli.add_command(queue_group, name="queue")
|
|
@@ -5,40 +5,46 @@ CLI: experiments active in the last K hours with summary stats.
|
|
|
5
5
|
|
|
6
6
|
import asyncio
|
|
7
7
|
from datetime import datetime, timedelta
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
8
9
|
|
|
9
10
|
import click
|
|
10
11
|
from rich import box
|
|
11
12
|
from rich.console import Console
|
|
12
13
|
from rich.table import Table
|
|
13
14
|
|
|
15
|
+
from synth_ai.cli._internal.storage import load_storage
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
if TYPE_CHECKING: # pragma: no cover - typing only
|
|
18
|
+
import pandas as pd
|
|
19
|
+
else:
|
|
20
|
+
pd = Any # type: ignore[assignment]
|
|
21
|
+
|
|
22
|
+
def _fmt_int(v: Any) -> str:
|
|
16
23
|
try:
|
|
17
24
|
return f"{int(v):,}"
|
|
18
25
|
except Exception:
|
|
19
26
|
return "0"
|
|
20
27
|
|
|
21
28
|
|
|
22
|
-
def _fmt_money(v) -> str:
|
|
29
|
+
def _fmt_money(v: Any) -> str:
|
|
23
30
|
try:
|
|
24
31
|
return f"${float(v or 0.0):.4f}"
|
|
25
32
|
except Exception:
|
|
26
33
|
return "$0.0000"
|
|
27
34
|
|
|
28
35
|
|
|
29
|
-
def _fmt_time(v) -> str:
|
|
36
|
+
def _fmt_time(v: Any) -> str:
|
|
30
37
|
try:
|
|
31
38
|
return str(v)
|
|
32
39
|
except Exception:
|
|
33
40
|
return "-"
|
|
34
41
|
|
|
35
42
|
|
|
36
|
-
async def _fetch_recent(db_url: str, hours: float):
|
|
37
|
-
from synth_ai.tracing_v3.turso.manager import AsyncSQLTraceManager
|
|
38
|
-
|
|
43
|
+
async def _fetch_recent(db_url: str, hours: float) -> "pd.DataFrame":
|
|
39
44
|
start_time = datetime.now() - timedelta(hours=hours)
|
|
40
45
|
|
|
41
|
-
|
|
46
|
+
create_storage, storage_config = load_storage()
|
|
47
|
+
db: Any = create_storage(storage_config(connection_string=db_url))
|
|
42
48
|
await db.initialize()
|
|
43
49
|
try:
|
|
44
50
|
query = """
|
|
@@ -11,6 +11,8 @@ from rich import box
|
|
|
11
11
|
from rich.console import Console
|
|
12
12
|
from rich.table import Table
|
|
13
13
|
|
|
14
|
+
from synth_ai.cli._internal.storage import load_storage
|
|
15
|
+
|
|
14
16
|
|
|
15
17
|
def register(cli):
|
|
16
18
|
@cli.command()
|
|
@@ -26,8 +28,6 @@ def register(cli):
|
|
|
26
28
|
console = Console()
|
|
27
29
|
|
|
28
30
|
async def _run():
|
|
29
|
-
from synth_ai.tracing_v3.turso.manager import AsyncSQLTraceManager
|
|
30
|
-
|
|
31
31
|
# Discover DBs under ./synth_ai.db/dbs (or override via env)
|
|
32
32
|
root = os.getenv("SYNTH_TRACES_ROOT", "./synth_ai.db/dbs")
|
|
33
33
|
if not os.path.isdir(root):
|
|
@@ -51,13 +51,15 @@ def register(cli):
|
|
|
51
51
|
for fn in files:
|
|
52
52
|
fp = os.path.join(dp, fn)
|
|
53
53
|
import contextlib
|
|
54
|
+
|
|
54
55
|
with contextlib.suppress(OSError):
|
|
55
56
|
total += os.path.getsize(fp)
|
|
56
57
|
return total
|
|
57
58
|
|
|
58
59
|
async def db_counts(db_dir: str) -> tuple[int, dict[str, int], int, str | None, int]:
|
|
59
60
|
data_file = os.path.join(db_dir, "data")
|
|
60
|
-
|
|
61
|
+
create_storage, storage_config = load_storage()
|
|
62
|
+
mgr = create_storage(storage_config(connection_string=f"sqlite+aiosqlite:///{data_file}"))
|
|
61
63
|
await mgr.initialize()
|
|
62
64
|
try:
|
|
63
65
|
traces_df = await mgr.query_traces("SELECT COUNT(*) AS c FROM session_traces")
|
|
@@ -73,9 +75,11 @@ def register(cli):
|
|
|
73
75
|
system_counts = (
|
|
74
76
|
{
|
|
75
77
|
str(r["system_type"] or "-"): int(r["c"] or 0)
|
|
76
|
-
for _, r in
|
|
78
|
+
for _, r in systems_df.iterrows()
|
|
77
79
|
}
|
|
78
|
-
if systems_df is not None
|
|
80
|
+
if systems_df is not None
|
|
81
|
+
and hasattr(systems_df, "iterrows")
|
|
82
|
+
and not systems_df.empty
|
|
79
83
|
else {}
|
|
80
84
|
)
|
|
81
85
|
except Exception:
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Synth AI Contracts
|
|
3
|
+
|
|
4
|
+
OpenAPI contracts for implementing Task Apps in any language.
|
|
5
|
+
These contracts define the HTTP interface between Synth optimizers
|
|
6
|
+
(MIPRO, GEPA) and your Task App service.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
# Get the contract file path
|
|
10
|
+
from synth_ai.contracts import TASK_APP_CONTRACT_PATH
|
|
11
|
+
|
|
12
|
+
# Get the contract as a string
|
|
13
|
+
from synth_ai.contracts import get_task_app_contract
|
|
14
|
+
yaml_content = get_task_app_contract()
|
|
15
|
+
|
|
16
|
+
# Or access directly via CLI
|
|
17
|
+
# synth contracts show task-app
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
CONTRACTS_DIR = Path(__file__).parent
|
|
23
|
+
TASK_APP_CONTRACT_PATH = CONTRACTS_DIR / "task_app.yaml"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_task_app_contract() -> str:
|
|
27
|
+
"""Return the Task App contract as a YAML string.
|
|
28
|
+
|
|
29
|
+
This OpenAPI spec defines the HTTP interface that Task Apps must implement
|
|
30
|
+
to work with Synth's MIPRO and GEPA prompt optimizers.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
The full OpenAPI 3.1 specification as a YAML string.
|
|
34
|
+
|
|
35
|
+
Example:
|
|
36
|
+
>>> contract = get_task_app_contract()
|
|
37
|
+
>>> print(contract[:50])
|
|
38
|
+
openapi: 3.1.0
|
|
39
|
+
info:
|
|
40
|
+
title: Synth Task App
|
|
41
|
+
"""
|
|
42
|
+
return TASK_APP_CONTRACT_PATH.read_text()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_contract_path(contract_name: str = "task-app") -> Path:
|
|
46
|
+
"""Get the filesystem path to a contract file.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
contract_name: Name of the contract. Currently only "task-app" is supported.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Path to the contract YAML file.
|
|
53
|
+
|
|
54
|
+
Raises:
|
|
55
|
+
ValueError: If the contract name is not recognized.
|
|
56
|
+
"""
|
|
57
|
+
if contract_name in ("task-app", "task_app"):
|
|
58
|
+
return TASK_APP_CONTRACT_PATH
|
|
59
|
+
raise ValueError(f"Unknown contract: {contract_name}. Available: task-app")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
__all__ = [
|
|
63
|
+
"CONTRACTS_DIR",
|
|
64
|
+
"TASK_APP_CONTRACT_PATH",
|
|
65
|
+
"get_task_app_contract",
|
|
66
|
+
"get_contract_path",
|
|
67
|
+
]
|