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,168 @@
|
|
|
1
|
+
"""Base configuration classes for Synth AI SDK.
|
|
2
|
+
|
|
3
|
+
This module defines the base config class that all job configs inherit from,
|
|
4
|
+
ensuring consistent handling of common fields like API keys and backend URLs.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from synth_ai.core.env import get_api_key, get_backend_url
|
|
13
|
+
from synth_ai.core.errors import ConfigError
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class BaseJobConfig:
|
|
18
|
+
"""Base class for all job configuration dataclasses.
|
|
19
|
+
|
|
20
|
+
This class provides common functionality shared across all job types
|
|
21
|
+
(prompt learning, SFT, RL, research agent). Subclasses should inherit
|
|
22
|
+
from this and add job-specific fields.
|
|
23
|
+
|
|
24
|
+
The base class ensures consistent handling of:
|
|
25
|
+
- Backend URL resolution
|
|
26
|
+
- API key validation
|
|
27
|
+
- Common configuration patterns
|
|
28
|
+
|
|
29
|
+
Example:
|
|
30
|
+
>>> from synth_ai.core.config import BaseJobConfig
|
|
31
|
+
>>> from dataclasses import dataclass
|
|
32
|
+
>>>
|
|
33
|
+
>>> @dataclass
|
|
34
|
+
... class MyJobConfig(BaseJobConfig):
|
|
35
|
+
... model: str
|
|
36
|
+
... temperature: float = 0.7
|
|
37
|
+
"""
|
|
38
|
+
"""Base configuration shared by all job types.
|
|
39
|
+
|
|
40
|
+
All job configs should inherit from this class to ensure consistent
|
|
41
|
+
handling of common fields like API keys and backend URLs.
|
|
42
|
+
|
|
43
|
+
Attributes:
|
|
44
|
+
task_app_url: URL of the task app to use
|
|
45
|
+
backend_url: Synth backend URL (defaults to production)
|
|
46
|
+
api_key: Synth API key (resolved from env if not provided)
|
|
47
|
+
environment_api_key: API key for environment access
|
|
48
|
+
timeout_seconds: Job timeout in seconds
|
|
49
|
+
metadata: Optional metadata dict attached to job
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
task_app_url: str | None = None
|
|
53
|
+
backend_url: str | None = None
|
|
54
|
+
api_key: str | None = None
|
|
55
|
+
environment_api_key: str | None = None
|
|
56
|
+
timeout_seconds: int = 3600
|
|
57
|
+
metadata: dict[str, Any] = field(default_factory=dict)
|
|
58
|
+
|
|
59
|
+
def resolve_credentials(self) -> tuple[str, str]:
|
|
60
|
+
"""Resolve API key and backend URL.
|
|
61
|
+
|
|
62
|
+
Uses provided values or falls back to environment resolution.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
Tuple of (backend_url, api_key)
|
|
66
|
+
|
|
67
|
+
Raises:
|
|
68
|
+
ConfigError: If required credentials cannot be resolved
|
|
69
|
+
"""
|
|
70
|
+
api_key = self.api_key or get_api_key(required=True)
|
|
71
|
+
backend_url = self.backend_url or get_backend_url()
|
|
72
|
+
|
|
73
|
+
if not api_key:
|
|
74
|
+
raise ConfigError("API key is required")
|
|
75
|
+
|
|
76
|
+
return backend_url, api_key
|
|
77
|
+
|
|
78
|
+
def validate(self) -> list[str]:
|
|
79
|
+
"""Validate the configuration.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
List of validation error messages (empty if valid)
|
|
83
|
+
"""
|
|
84
|
+
errors: list[str] = []
|
|
85
|
+
if self.timeout_seconds <= 0:
|
|
86
|
+
errors.append("timeout_seconds must be positive")
|
|
87
|
+
return errors
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class ConfigValidator:
|
|
91
|
+
"""Base class for configuration validators.
|
|
92
|
+
|
|
93
|
+
Validators provide a way to validate and normalize configuration
|
|
94
|
+
before it's used to create jobs. This is useful for:
|
|
95
|
+
- Type checking
|
|
96
|
+
- Value validation
|
|
97
|
+
- Default value injection
|
|
98
|
+
- Cross-field validation
|
|
99
|
+
|
|
100
|
+
Subclasses should implement the `validate()` method to perform
|
|
101
|
+
job-specific validation logic.
|
|
102
|
+
|
|
103
|
+
Example:
|
|
104
|
+
>>> from synth_ai.core.config import ConfigValidator
|
|
105
|
+
>>>
|
|
106
|
+
>>> class MyJobValidator(ConfigValidator):
|
|
107
|
+
... def validate(self, config: dict) -> dict:
|
|
108
|
+
... if config.get("temperature", 0) < 0:
|
|
109
|
+
... raise ValueError("temperature must be >= 0")
|
|
110
|
+
... return config
|
|
111
|
+
"""
|
|
112
|
+
"""Utility for validating configurations."""
|
|
113
|
+
|
|
114
|
+
@staticmethod
|
|
115
|
+
def require_field(
|
|
116
|
+
config: dict[str, Any],
|
|
117
|
+
field_name: str,
|
|
118
|
+
field_type: type | tuple[type, ...] | None = None,
|
|
119
|
+
) -> Any:
|
|
120
|
+
"""Require a field to be present in config.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
config: Configuration dict
|
|
124
|
+
field_name: Name of required field
|
|
125
|
+
field_type: Optional type(s) to validate against
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
The field value
|
|
129
|
+
|
|
130
|
+
Raises:
|
|
131
|
+
ConfigError: If field is missing or wrong type
|
|
132
|
+
"""
|
|
133
|
+
if field_name not in config:
|
|
134
|
+
raise ConfigError(f"Missing required field: {field_name}")
|
|
135
|
+
|
|
136
|
+
value = config[field_name]
|
|
137
|
+
if field_type is not None and not isinstance(value, field_type):
|
|
138
|
+
expected = (
|
|
139
|
+
field_type.__name__
|
|
140
|
+
if isinstance(field_type, type)
|
|
141
|
+
else " | ".join(t.__name__ for t in field_type)
|
|
142
|
+
)
|
|
143
|
+
raise ConfigError(
|
|
144
|
+
f"Field '{field_name}' must be {expected}, got {type(value).__name__}"
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
return value
|
|
148
|
+
|
|
149
|
+
@staticmethod
|
|
150
|
+
def validate_positive(value: int | float, field_name: str) -> None:
|
|
151
|
+
"""Validate that a numeric value is positive.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
value: Value to check
|
|
155
|
+
field_name: Name for error message
|
|
156
|
+
|
|
157
|
+
Raises:
|
|
158
|
+
ConfigError: If value is not positive
|
|
159
|
+
"""
|
|
160
|
+
if value <= 0:
|
|
161
|
+
raise ConfigError(f"{field_name} must be positive, got {value}")
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
__all__ = [
|
|
165
|
+
"BaseJobConfig",
|
|
166
|
+
"ConfigValidator",
|
|
167
|
+
]
|
|
168
|
+
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Optional, overload
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
|
|
7
|
+
from synth_ai.core.telemetry import log_info
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _get_required_value(*args, **kwargs):
|
|
11
|
+
"""Lazy import to avoid circular dependency."""
|
|
12
|
+
from synth_ai.cli.lib.errors import get_required_value
|
|
13
|
+
return get_required_value(*args, **kwargs)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ConfigResolver:
|
|
17
|
+
"""Resolve configuration values with consistent precedence and messaging."""
|
|
18
|
+
|
|
19
|
+
@overload
|
|
20
|
+
@staticmethod
|
|
21
|
+
def resolve(
|
|
22
|
+
name: str,
|
|
23
|
+
*,
|
|
24
|
+
cli_value: Optional[str] = None,
|
|
25
|
+
env_value: Optional[str] = None,
|
|
26
|
+
config_value: Optional[str] = None,
|
|
27
|
+
default: Optional[str] = None,
|
|
28
|
+
required: bool = False,
|
|
29
|
+
docs_url: Optional[str] = None,
|
|
30
|
+
) -> Optional[str]: ...
|
|
31
|
+
|
|
32
|
+
@overload
|
|
33
|
+
@staticmethod
|
|
34
|
+
def resolve(
|
|
35
|
+
name: str,
|
|
36
|
+
*,
|
|
37
|
+
cli_value: Optional[str] = None,
|
|
38
|
+
env_value: Optional[str] = None,
|
|
39
|
+
config_value: Optional[str] = None,
|
|
40
|
+
default: Optional[str] = None,
|
|
41
|
+
required: bool = True,
|
|
42
|
+
docs_url: Optional[str] = None,
|
|
43
|
+
) -> str: ...
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def resolve(
|
|
47
|
+
name: str,
|
|
48
|
+
*,
|
|
49
|
+
cli_value: Optional[str] = None,
|
|
50
|
+
env_value: Optional[str] = None,
|
|
51
|
+
config_value: Optional[str] = None,
|
|
52
|
+
default: Optional[str] = None,
|
|
53
|
+
required: bool = False,
|
|
54
|
+
docs_url: Optional[str] = None,
|
|
55
|
+
) -> Optional[str]:
|
|
56
|
+
"""Resolve value with CLI > ENV > CONFIG > DEFAULT precedence."""
|
|
57
|
+
ctx = {"name": name, "required": required, "has_cli": cli_value is not None, "has_env": env_value is not None}
|
|
58
|
+
log_info("ConfigResolver.resolve invoked", ctx=ctx)
|
|
59
|
+
|
|
60
|
+
def _clean(value: Optional[str]) -> Optional[str]:
|
|
61
|
+
if value is None:
|
|
62
|
+
return None
|
|
63
|
+
stripped = value.strip()
|
|
64
|
+
return stripped if stripped else None
|
|
65
|
+
|
|
66
|
+
cli_clean = _clean(cli_value)
|
|
67
|
+
env_clean = _clean(env_value)
|
|
68
|
+
config_clean = _clean(config_value)
|
|
69
|
+
default_clean = _clean(default)
|
|
70
|
+
|
|
71
|
+
if cli_clean and config_clean and cli_clean != config_clean:
|
|
72
|
+
click.secho(
|
|
73
|
+
f"⚠️ {name}: CLI flag overrides config file "
|
|
74
|
+
f"(using {cli_clean}, ignoring {config_clean})",
|
|
75
|
+
err=True,
|
|
76
|
+
fg="yellow",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
resolved = cli_clean or env_clean or config_clean or default_clean
|
|
80
|
+
if required:
|
|
81
|
+
return _get_required_value(
|
|
82
|
+
name,
|
|
83
|
+
cli_value=cli_clean,
|
|
84
|
+
env_value=env_clean,
|
|
85
|
+
config_value=config_clean,
|
|
86
|
+
default=default_clean,
|
|
87
|
+
docs_url=docs_url,
|
|
88
|
+
)
|
|
89
|
+
return resolved
|
synth_ai/core/env.py
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"""Environment resolution utilities.
|
|
2
|
+
|
|
3
|
+
This module provides non-interactive environment variable resolution
|
|
4
|
+
for use by SDK and CLI. It consolidates the various env resolution
|
|
5
|
+
patterns into a clean API.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Literal
|
|
13
|
+
|
|
14
|
+
from .errors import AuthenticationError, ConfigError
|
|
15
|
+
|
|
16
|
+
# Default production URL
|
|
17
|
+
PROD_BASE_URL = "https://api.usesynth.ai"
|
|
18
|
+
PROD_BASE_URL_DEFAULT = PROD_BASE_URL # Alias for backward compatibility
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_api_key(env_key: str = "SYNTH_API_KEY", required: bool = True) -> str | None:
|
|
22
|
+
"""Get API key from environment.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
env_key: Environment variable name to check
|
|
26
|
+
required: If True, raises AuthenticationError when not found
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
API key string or None if not required and not found
|
|
30
|
+
|
|
31
|
+
Raises:
|
|
32
|
+
AuthenticationError: If required and not found
|
|
33
|
+
"""
|
|
34
|
+
value = os.environ.get(env_key)
|
|
35
|
+
if not value and required:
|
|
36
|
+
raise AuthenticationError(
|
|
37
|
+
f"Missing required API key: {env_key}\n"
|
|
38
|
+
f"Set it via: export {env_key}=<your-key>\n"
|
|
39
|
+
f"Or add to .env file: {env_key}=<your-key>"
|
|
40
|
+
)
|
|
41
|
+
return value
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def get_backend_url(
|
|
45
|
+
mode: Literal["prod", "dev", "local"] | None = None,
|
|
46
|
+
) -> str:
|
|
47
|
+
"""Resolve backend URL.
|
|
48
|
+
|
|
49
|
+
Priority order:
|
|
50
|
+
1. SYNTH_BACKEND_URL env var (if set)
|
|
51
|
+
2. Mode-specific URL based on SYNTH_BACKEND_MODE or explicit mode
|
|
52
|
+
3. Default to production
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
mode: Force a specific mode (prod/dev/local), or detect from env
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
Backend URL (without trailing /api)
|
|
59
|
+
"""
|
|
60
|
+
# Direct override takes precedence
|
|
61
|
+
direct = os.environ.get("SYNTH_BACKEND_URL")
|
|
62
|
+
if direct:
|
|
63
|
+
return _normalize_url(direct)
|
|
64
|
+
|
|
65
|
+
# Determine mode
|
|
66
|
+
if mode is None:
|
|
67
|
+
mode_env = os.environ.get("SYNTH_BACKEND_MODE", "").lower()
|
|
68
|
+
mode = mode_env if mode_env in ("prod", "dev", "local") else "prod" # type: ignore
|
|
69
|
+
|
|
70
|
+
if mode == "local":
|
|
71
|
+
url = os.environ.get("SYNTH_LOCAL_URL", "http://localhost:8000")
|
|
72
|
+
elif mode == "dev":
|
|
73
|
+
url = os.environ.get("SYNTH_DEV_URL", "http://localhost:8000")
|
|
74
|
+
else:
|
|
75
|
+
url = os.environ.get("SYNTH_PROD_URL", PROD_BASE_URL)
|
|
76
|
+
|
|
77
|
+
return _normalize_url(url)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _normalize_url(url: str) -> str:
|
|
81
|
+
"""Normalize URL: strip trailing slashes and /api suffix."""
|
|
82
|
+
url = url.strip().rstrip("/")
|
|
83
|
+
if url.endswith("/api"):
|
|
84
|
+
url = url[:-4]
|
|
85
|
+
if url.endswith("/v1"):
|
|
86
|
+
url = url[:-3]
|
|
87
|
+
return url
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def resolve_env_file(
|
|
91
|
+
explicit_path: str | Path | None = None,
|
|
92
|
+
search_cwd: bool = True,
|
|
93
|
+
) -> Path | None:
|
|
94
|
+
"""Find and return path to .env file.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
explicit_path: If provided, use this path directly
|
|
98
|
+
search_cwd: If True, search current directory for .env
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
Path to .env file, or None if not found
|
|
102
|
+
"""
|
|
103
|
+
if explicit_path:
|
|
104
|
+
path = Path(explicit_path).expanduser().resolve()
|
|
105
|
+
if path.exists():
|
|
106
|
+
return path
|
|
107
|
+
raise ConfigError(f"Env file not found: {path}")
|
|
108
|
+
|
|
109
|
+
if search_cwd:
|
|
110
|
+
cwd_env = Path.cwd() / ".env"
|
|
111
|
+
if cwd_env.exists():
|
|
112
|
+
return cwd_env.resolve()
|
|
113
|
+
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def load_env_file(path: Path) -> dict[str, str]:
|
|
118
|
+
"""Parse a .env file into a dictionary.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
path: Path to .env file
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
Dict mapping env var names to values
|
|
125
|
+
"""
|
|
126
|
+
result: dict[str, str] = {}
|
|
127
|
+
try:
|
|
128
|
+
with path.open("r", encoding="utf-8") as f:
|
|
129
|
+
for line in f:
|
|
130
|
+
line = line.strip()
|
|
131
|
+
if not line or line.startswith("#"):
|
|
132
|
+
continue
|
|
133
|
+
if line.lower().startswith("export "):
|
|
134
|
+
line = line[7:].strip()
|
|
135
|
+
if "=" not in line:
|
|
136
|
+
continue
|
|
137
|
+
key, _, value = line.partition("=")
|
|
138
|
+
key = key.strip()
|
|
139
|
+
value = value.strip()
|
|
140
|
+
# Strip quotes
|
|
141
|
+
if len(value) >= 2 and value[0] == value[-1] and value[0] in ('"', "'"):
|
|
142
|
+
value = value[1:-1]
|
|
143
|
+
result[key] = value
|
|
144
|
+
except (OSError, UnicodeDecodeError) as e:
|
|
145
|
+
raise ConfigError(f"Failed to read env file {path}: {e}") from e
|
|
146
|
+
return result
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def mask_value(value: str, visible_chars: int = 4) -> str:
|
|
150
|
+
"""Mask a sensitive value for display.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
value: The value to mask
|
|
154
|
+
visible_chars: Number of characters to show at start and end
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
Masked string like "abc...xyz"
|
|
158
|
+
"""
|
|
159
|
+
if len(value) <= visible_chars * 2:
|
|
160
|
+
return "***"
|
|
161
|
+
return f"{value[:visible_chars]}...{value[-visible_chars:]}"
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def get_backend_from_env() -> tuple[str, str]:
|
|
165
|
+
"""Resolve (base_url, api_key) using LOCAL/DEV/PROD override scheme.
|
|
166
|
+
|
|
167
|
+
Env vars consulted:
|
|
168
|
+
- BACKEND_OVERRIDE = full URL (with or without /api)
|
|
169
|
+
- SYNTH_BACKEND_URL_OVERRIDE = local|dev|prod (case-insensitive)
|
|
170
|
+
- LOCAL_BACKEND_URL, TESTING_LOCAL_SYNTH_API_KEY
|
|
171
|
+
- DEV_BACKEND_URL, DEV_SYNTH_API_KEY
|
|
172
|
+
- PROD_BACKEND_URL, TESTING_PROD_SYNTH_API_KEY (fallback to SYNTH_API_KEY)
|
|
173
|
+
|
|
174
|
+
Base URL is normalized (no trailing /api).
|
|
175
|
+
Defaults: prod base URL → https://api.usesynth.ai
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
Tuple of (base_url, api_key)
|
|
179
|
+
"""
|
|
180
|
+
direct_override = (os.environ.get("BACKEND_OVERRIDE") or "").strip()
|
|
181
|
+
if direct_override:
|
|
182
|
+
base = _normalize_url(direct_override)
|
|
183
|
+
if not base:
|
|
184
|
+
raise ConfigError("BACKEND_OVERRIDE is set but empty or invalid")
|
|
185
|
+
api_key = os.environ.get("SYNTH_API_KEY", "").strip()
|
|
186
|
+
return base, api_key
|
|
187
|
+
|
|
188
|
+
# Determine mode from env
|
|
189
|
+
mode_override = (os.environ.get("SYNTH_BACKEND_URL_OVERRIDE", "") or "").strip().lower()
|
|
190
|
+
mode = mode_override if mode_override in ("local", "dev", "prod") else "prod"
|
|
191
|
+
|
|
192
|
+
if mode == "local":
|
|
193
|
+
base = os.environ.get("LOCAL_BACKEND_URL", "http://localhost:8000")
|
|
194
|
+
# If explicitly set to empty string, use default
|
|
195
|
+
if not base or not base.strip():
|
|
196
|
+
base = "http://localhost:8000"
|
|
197
|
+
key = os.environ.get("TESTING_LOCAL_SYNTH_API_KEY", "")
|
|
198
|
+
return _normalize_url(base), key
|
|
199
|
+
|
|
200
|
+
if mode == "dev":
|
|
201
|
+
base = os.environ.get("DEV_BACKEND_URL", "") or "http://localhost:8000"
|
|
202
|
+
# If explicitly set to empty string, use default
|
|
203
|
+
if not base or not base.strip():
|
|
204
|
+
base = "http://localhost:8000"
|
|
205
|
+
key = os.environ.get("DEV_SYNTH_API_KEY", "")
|
|
206
|
+
return _normalize_url(base), key
|
|
207
|
+
|
|
208
|
+
# prod
|
|
209
|
+
base = os.environ.get("PROD_BACKEND_URL", PROD_BASE_URL)
|
|
210
|
+
# If explicitly set to empty string, use default
|
|
211
|
+
if not base or not base.strip():
|
|
212
|
+
base = PROD_BASE_URL
|
|
213
|
+
key = (
|
|
214
|
+
os.environ.get("PROD_SYNTH_API_KEY", "")
|
|
215
|
+
or os.environ.get("TESTING_PROD_SYNTH_API_KEY", "")
|
|
216
|
+
or os.environ.get("SYNTH_API_KEY", "")
|
|
217
|
+
)
|
|
218
|
+
return _normalize_url(base), key
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
__all__ = [
|
|
222
|
+
"get_api_key",
|
|
223
|
+
"get_backend_url",
|
|
224
|
+
"get_backend_from_env",
|
|
225
|
+
"resolve_env_file",
|
|
226
|
+
"load_env_file",
|
|
227
|
+
"mask_value",
|
|
228
|
+
"PROD_BASE_URL",
|
|
229
|
+
"PROD_BASE_URL_DEFAULT",
|
|
230
|
+
]
|
|
231
|
+
|
synth_ai/core/errors.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""Consolidated error types for Synth AI SDK.
|
|
2
|
+
|
|
3
|
+
This module provides base exception classes used throughout the SDK.
|
|
4
|
+
CLI-specific errors remain in cli/ modules; these are for SDK/core use.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SynthError(Exception):
|
|
14
|
+
"""Base exception for all Synth AI SDK errors."""
|
|
15
|
+
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ConfigError(SynthError):
|
|
20
|
+
"""Raised when configuration is invalid or missing."""
|
|
21
|
+
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AuthenticationError(SynthError):
|
|
26
|
+
"""Raised when API authentication fails."""
|
|
27
|
+
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ValidationError(SynthError):
|
|
32
|
+
"""Raised when data validation fails."""
|
|
33
|
+
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass
|
|
38
|
+
class HTTPError(SynthError):
|
|
39
|
+
"""Raised when an HTTP request fails."""
|
|
40
|
+
|
|
41
|
+
status: int
|
|
42
|
+
url: str
|
|
43
|
+
message: str
|
|
44
|
+
body_snippet: str | None = None
|
|
45
|
+
detail: Any | None = None
|
|
46
|
+
|
|
47
|
+
def __str__(self) -> str:
|
|
48
|
+
base = f"HTTP {self.status} for {self.url}: {self.message}"
|
|
49
|
+
if self.body_snippet:
|
|
50
|
+
base += f" | body[0:200]={self.body_snippet[:200]}"
|
|
51
|
+
return base
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class JobError(SynthError):
|
|
55
|
+
"""Raised when a job operation fails."""
|
|
56
|
+
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class TimeoutError(SynthError):
|
|
61
|
+
"""Raised when an operation times out."""
|
|
62
|
+
|
|
63
|
+
pass
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class StorageError(SynthError):
|
|
67
|
+
"""Raised when storage operations fail."""
|
|
68
|
+
|
|
69
|
+
pass
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class ModelNotSupportedError(SynthError):
|
|
73
|
+
"""Raised when a model is not supported."""
|
|
74
|
+
|
|
75
|
+
def __init__(self, model: str, provider: str | None = None) -> None:
|
|
76
|
+
self.model = model
|
|
77
|
+
self.provider = provider
|
|
78
|
+
msg = f"Model '{model}' is not supported"
|
|
79
|
+
if provider:
|
|
80
|
+
msg += f" by provider '{provider}'"
|
|
81
|
+
super().__init__(msg)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@dataclass
|
|
85
|
+
class UsageLimitError(SynthError):
|
|
86
|
+
"""Raised when an org rate limit is exceeded.
|
|
87
|
+
|
|
88
|
+
Attributes:
|
|
89
|
+
limit_type: The type of limit exceeded (e.g., "inference_tokens_per_day")
|
|
90
|
+
api: The API that hit the limit (e.g., "inference", "judges", "prompt_opt")
|
|
91
|
+
current: Current usage value
|
|
92
|
+
limit: The limit value
|
|
93
|
+
tier: The org's tier (e.g., "free", "starter", "growth")
|
|
94
|
+
retry_after_seconds: Seconds until the limit resets (if available)
|
|
95
|
+
upgrade_url: URL to upgrade tier
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
limit_type: str
|
|
99
|
+
api: str
|
|
100
|
+
current: int | float
|
|
101
|
+
limit: int | float
|
|
102
|
+
tier: str = "free"
|
|
103
|
+
retry_after_seconds: int | None = None
|
|
104
|
+
upgrade_url: str = "https://usesynth.ai/pricing"
|
|
105
|
+
|
|
106
|
+
def __str__(self) -> str:
|
|
107
|
+
return (
|
|
108
|
+
f"Rate limit exceeded: {self.limit_type} "
|
|
109
|
+
f"({self.current}/{self.limit}) for tier '{self.tier}'. "
|
|
110
|
+
f"Upgrade at {self.upgrade_url}"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
__all__ = [
|
|
115
|
+
"SynthError",
|
|
116
|
+
"ConfigError",
|
|
117
|
+
"AuthenticationError",
|
|
118
|
+
"ValidationError",
|
|
119
|
+
"HTTPError",
|
|
120
|
+
"JobError",
|
|
121
|
+
"TimeoutError",
|
|
122
|
+
"StorageError",
|
|
123
|
+
"ModelNotSupportedError",
|
|
124
|
+
"UsageLimitError",
|
|
125
|
+
]
|
|
126
|
+
|