synth-ai 0.2.8.dev2__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/{demos → cli/demo_apps}/core/cli.py +783 -441
- 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 +75 -37
- 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/{demos → cli/demo_apps}/demo_task_apps/math/_common.py +1 -2
- 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} +16 -4
- 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 -108
- 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.8.dev2.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 -144
- synth_ai/cli/legacy_root_backup.py +0 -470
- synth_ai/cli/man.py +0 -106
- synth_ai/cli/rl_demo.py +0 -202
- synth_ai/cli/status.py +0 -133
- synth_ai/config/base_url.py +0 -107
- 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/demo_task_apps/__init__.py +0 -1
- synth_ai/demos/demo_task_apps/math/config.toml +0 -129
- synth_ai/demos/demo_task_apps/math/deploy_task_app.sh +0 -22
- synth_ai/demos/demo_task_apps/math/modal_task_app.py +0 -415
- 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 -738
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/kick_off_ft_modal.py +0 -384
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_action_results.py +0 -53
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_agent_actions.py +0 -178
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_latest_run.py +0 -222
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_lm_traces.py +0 -183
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_no_rewards.py +0 -210
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_trace_issue.py +0 -206
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/check_db_schema.py +0 -49
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/check_latest_results.py +0 -64
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/debug_agent_responses.py +0 -88
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/quick_trace_check.py +0 -77
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/compare_experiments.py +0 -324
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/filter_traces_sft_turso.py +0 -580
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/kick_off_ft_oai.py +0 -362
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/multi_model_config.toml +0 -49
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/analyze_enhanced_hooks.py +0 -332
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/analyze_hook_events.py +0 -97
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/analyze_hook_results.py +0 -217
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/check_hook_storage.py +0 -87
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/check_seeds.py +0 -88
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/compare_seed_performance.py +0 -195
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/custom_eval_pipelines.py +0 -400
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/plot_hook_frequency.py +0 -195
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/seed_analysis_summary.py +0 -56
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/run_rollouts_for_models_and_compare_v3.py +0 -858
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_quick_evaluation.py +0 -52
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_react_agent.py +0 -874
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_trace_evaluation.py +0 -1412
- synth_ai/environments/examples/crafter_classic/agent_demos/example_v3_usage.py +0 -216
- synth_ai/environments/examples/crafter_classic/agent_demos/old/compare_traces.py +0 -296
- synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_comprehensive_evaluation.py +0 -58
- synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_env_serialization.py +0 -464
- synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_evaluation_browser.py +0 -152
- synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_quick_evaluation.py +0 -51
- synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_trace_evaluation.py +0 -1412
- synth_ai/environments/examples/crafter_classic/agent_demos/old/debug_player_loss.py +0 -112
- synth_ai/environments/examples/crafter_classic/agent_demos/old/diagnose_service.py +0 -203
- synth_ai/environments/examples/crafter_classic/agent_demos/old/diagnose_slowness.py +0 -305
- synth_ai/environments/examples/crafter_classic/agent_demos/old/eval_by_difficulty.py +0 -126
- synth_ai/environments/examples/crafter_classic/agent_demos/old/eval_example.py +0 -94
- synth_ai/environments/examples/crafter_classic/agent_demos/old/explore_saved_states.py +0 -142
- synth_ai/environments/examples/crafter_classic/agent_demos/old/filter_traces_sft.py +0 -26
- synth_ai/environments/examples/crafter_classic/agent_demos/old/filter_traces_sft_OLD.py +0 -984
- synth_ai/environments/examples/crafter_classic/agent_demos/old/generate_ft_data_gemini.py +0 -724
- synth_ai/environments/examples/crafter_classic/agent_demos/old/generate_ft_data_modal.py +0 -386
- synth_ai/environments/examples/crafter_classic/agent_demos/old/generate_ft_metadata.py +0 -205
- synth_ai/environments/examples/crafter_classic/agent_demos/old/kick_off_ft_gemini.py +0 -150
- synth_ai/environments/examples/crafter_classic/agent_demos/old/kick_off_ft_modal.py +0 -283
- synth_ai/environments/examples/crafter_classic/agent_demos/old/prepare_vertex_ft.py +0 -280
- synth_ai/environments/examples/crafter_classic/agent_demos/old/profile_env_slowness.py +0 -456
- synth_ai/environments/examples/crafter_classic/agent_demos/old/replicate_issue.py +0 -166
- synth_ai/environments/examples/crafter_classic/agent_demos/old/run_and_eval.py +0 -102
- synth_ai/environments/examples/crafter_classic/agent_demos/old/run_comparison.py +0 -128
- synth_ai/environments/examples/crafter_classic/agent_demos/old/run_qwen_rollouts.py +0 -655
- synth_ai/environments/examples/crafter_classic/agent_demos/old/trace_eval_OLD.py +0 -202
- synth_ai/environments/examples/crafter_classic/agent_demos/old/validate_openai_format.py +0 -166
- synth_ai/environments/examples/crafter_classic/config_logging.py +0 -111
- synth_ai/environments/examples/crafter_classic/debug_translation.py +0 -0
- synth_ai/environments/examples/crafter_classic/engine.py +0 -579
- synth_ai/environments/examples/crafter_classic/engine_deterministic_patch.py +0 -64
- synth_ai/environments/examples/crafter_classic/engine_helpers/action_map.py +0 -6
- synth_ai/environments/examples/crafter_classic/engine_helpers/serialization.py +0 -75
- synth_ai/environments/examples/crafter_classic/engine_serialization_patch_v3.py +0 -267
- synth_ai/environments/examples/crafter_classic/environment.py +0 -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 -98
- 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/handshake.py +0 -63
- synth_ai/http.py +0 -26
- synth_ai/http_client.py +0 -104
- 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 -225
- 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 -142
- synth_ai/v0/tracing/context.py +0 -146
- synth_ai/v0/tracing/decorators.py +0 -682
- synth_ai/v0/tracing/events/__init__.py +0 -0
- synth_ai/v0/tracing/events/manage.py +0 -147
- synth_ai/v0/tracing/events/scope.py +0 -86
- synth_ai/v0/tracing/events/store.py +0 -228
- synth_ai/v0/tracing/immediate_client.py +0 -151
- synth_ai/v0/tracing/local.py +0 -18
- synth_ai/v0/tracing/log_client_base.py +0 -73
- synth_ai/v0/tracing/retry_queue.py +0 -186
- synth_ai/v0/tracing/trackers.py +0 -515
- synth_ai/v0/tracing/upload.py +0 -512
- synth_ai/v0/tracing/utils.py +0 -9
- synth_ai/v0/tracing_v1/__init__.py +0 -16
- synth_ai/v0/tracing_v1/abstractions.py +0 -224
- synth_ai/v0/tracing_v1/base_client.py +0 -91
- synth_ai/v0/tracing_v1/client_manager.py +0 -131
- synth_ai/v0/tracing_v1/config.py +0 -142
- synth_ai/v0/tracing_v1/context.py +0 -146
- synth_ai/v0/tracing_v1/decorators.py +0 -703
- synth_ai/v0/tracing_v1/events/__init__.py +0 -0
- synth_ai/v0/tracing_v1/events/manage.py +0 -147
- synth_ai/v0/tracing_v1/events/scope.py +0 -86
- synth_ai/v0/tracing_v1/events/store.py +0 -228
- synth_ai/v0/tracing_v1/immediate_client.py +0 -151
- synth_ai/v0/tracing_v1/local.py +0 -18
- synth_ai/v0/tracing_v1/log_client_base.py +0 -73
- synth_ai/v0/tracing_v1/retry_queue.py +0 -186
- synth_ai/v0/tracing_v1/trackers.py +0 -515
- synth_ai/v0/tracing_v1/upload.py +0 -527
- synth_ai/v0/tracing_v1/utils.py +0 -9
- synth_ai/zyk/__init__.py +0 -30
- synth_ai-0.2.8.dev2.dist-info/METADATA +0 -129
- synth_ai-0.2.8.dev2.dist-info/RECORD +0 -420
- /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.8.dev2.dist-info → synth_ai-0.4.3.dist-info}/WHEEL +0 -0
- {synth_ai-0.2.8.dev2.dist-info → synth_ai-0.4.3.dist-info}/licenses/LICENSE +0 -0
- {synth_ai-0.2.8.dev2.dist-info → synth_ai-0.4.3.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"""Help content for CLI commands."""
|
|
2
|
+
|
|
3
|
+
DEPLOY_HELP = """
|
|
4
|
+
Deploy a Synth AI task app locally, to Modal, or via Cloudflare Tunnel.
|
|
5
|
+
|
|
6
|
+
OVERVIEW
|
|
7
|
+
--------
|
|
8
|
+
The deploy command supports three runtimes:
|
|
9
|
+
• modal: Deploy to Modal's cloud platform (default)
|
|
10
|
+
• local: Run locally with FastAPI/Uvicorn
|
|
11
|
+
• tunnel: Expose local app via Cloudflare Tunnel (for RL/prompt optimization)
|
|
12
|
+
|
|
13
|
+
BASIC USAGE
|
|
14
|
+
-----------
|
|
15
|
+
# Deploy to Modal (production)
|
|
16
|
+
uvx synth-ai deploy
|
|
17
|
+
|
|
18
|
+
# Deploy specific task app
|
|
19
|
+
uvx synth-ai deploy my-math-app
|
|
20
|
+
|
|
21
|
+
# Run locally for development
|
|
22
|
+
uvx synth-ai deploy --runtime=local --port 8001
|
|
23
|
+
|
|
24
|
+
# Deploy via Cloudflare Tunnel (for training)
|
|
25
|
+
uvx synth-ai deploy --runtime=tunnel --tunnel-mode quick
|
|
26
|
+
|
|
27
|
+
MODAL DEPLOYMENT
|
|
28
|
+
----------------
|
|
29
|
+
Modal deployment requires:
|
|
30
|
+
1. Modal authentication (run: modal token new)
|
|
31
|
+
2. ENVIRONMENT_API_KEY (run: uvx synth-ai setup)
|
|
32
|
+
|
|
33
|
+
Options:
|
|
34
|
+
--modal-mode [deploy|serve] Use 'deploy' for production (default),
|
|
35
|
+
'serve' for ephemeral development
|
|
36
|
+
--name TEXT Override Modal app name
|
|
37
|
+
--dry-run Preview the deploy command without executing
|
|
38
|
+
--env-file PATH Env file(s) to load (can be repeated)
|
|
39
|
+
|
|
40
|
+
Examples:
|
|
41
|
+
# Standard production deployment
|
|
42
|
+
uvx synth-ai deploy --runtime=modal
|
|
43
|
+
|
|
44
|
+
# Deploy with custom name
|
|
45
|
+
uvx synth-ai deploy --runtime=modal --name my-task-app-v2
|
|
46
|
+
|
|
47
|
+
# Preview deployment command
|
|
48
|
+
uvx synth-ai deploy --dry-run
|
|
49
|
+
|
|
50
|
+
# Deploy with custom env file
|
|
51
|
+
uvx synth-ai deploy --env-file .env.production
|
|
52
|
+
|
|
53
|
+
LOCAL DEVELOPMENT
|
|
54
|
+
-----------------
|
|
55
|
+
Run locally with auto-reload and tracing:
|
|
56
|
+
|
|
57
|
+
uvx synth-ai deploy --runtime=uvicorn --port 8001 --reload
|
|
58
|
+
|
|
59
|
+
Options:
|
|
60
|
+
--host TEXT Bind address (default: 0.0.0.0)
|
|
61
|
+
--port INTEGER Port number (prompted if not provided)
|
|
62
|
+
--reload/--no-reload Enable auto-reload on code changes
|
|
63
|
+
--force/--no-force Kill existing process on port
|
|
64
|
+
--trace PATH Enable tracing to directory (default: traces/v3)
|
|
65
|
+
--trace-db PATH SQLite DB for traces
|
|
66
|
+
|
|
67
|
+
Examples:
|
|
68
|
+
# Basic local server
|
|
69
|
+
uvx synth-ai deploy --runtime=uvicorn
|
|
70
|
+
|
|
71
|
+
# Development with auto-reload
|
|
72
|
+
uvx synth-ai deploy --runtime=uvicorn --reload --port 8001
|
|
73
|
+
|
|
74
|
+
# With custom trace directory
|
|
75
|
+
uvx synth-ai deploy --runtime=uvicorn --trace ./my-traces
|
|
76
|
+
|
|
77
|
+
TROUBLESHOOTING
|
|
78
|
+
---------------
|
|
79
|
+
Common issues:
|
|
80
|
+
|
|
81
|
+
1. "ENVIRONMENT_API_KEY is required"
|
|
82
|
+
→ Run: uvx synth-ai setup
|
|
83
|
+
|
|
84
|
+
2. "Modal CLI not found"
|
|
85
|
+
→ Install: pip install modal
|
|
86
|
+
→ Authenticate: modal token new
|
|
87
|
+
|
|
88
|
+
3. "Task app not found"
|
|
89
|
+
→ Check app_id matches your task_app.py configuration
|
|
90
|
+
→ Run: uvx synth-ai task-app list (if available)
|
|
91
|
+
|
|
92
|
+
4. "Port already in use" (local/tunnel)
|
|
93
|
+
→ Use --force to kill existing process
|
|
94
|
+
→ Or specify different --port
|
|
95
|
+
|
|
96
|
+
5. "cloudflared not found" (tunnel)
|
|
97
|
+
→ Install: brew install cloudflare/cloudflare/cloudflared
|
|
98
|
+
→ Or: https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/
|
|
99
|
+
|
|
100
|
+
6. "No env file discovered"
|
|
101
|
+
→ Create .env file with required keys
|
|
102
|
+
→ Or pass --env-file explicitly
|
|
103
|
+
|
|
104
|
+
ENVIRONMENT VARIABLES
|
|
105
|
+
---------------------
|
|
106
|
+
SYNTH_API_KEY Your Synth platform API key
|
|
107
|
+
ENVIRONMENT_API_KEY Task environment authentication
|
|
108
|
+
TASK_APP_BASE_URL Base URL for deployed task app
|
|
109
|
+
DEMO_DIR Demo directory path
|
|
110
|
+
SYNTH_DEMO_DIR Alternative demo directory
|
|
111
|
+
|
|
112
|
+
For more information: https://docs.usesynth.ai/deploy
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
SETUP_HELP = """
|
|
116
|
+
Configure Synth AI credentials and environment.
|
|
117
|
+
|
|
118
|
+
OVERVIEW
|
|
119
|
+
--------
|
|
120
|
+
The setup command initializes your Synth AI environment by:
|
|
121
|
+
1. Authenticating with the Synth platform via browser
|
|
122
|
+
2. Saving your API keys to ~/.synth/config
|
|
123
|
+
3. Verifying Modal authentication (for deployments)
|
|
124
|
+
4. Testing connectivity to backend services
|
|
125
|
+
|
|
126
|
+
USAGE
|
|
127
|
+
-----
|
|
128
|
+
uvx synth-ai setup
|
|
129
|
+
|
|
130
|
+
The command will:
|
|
131
|
+
• Open your browser for authentication (or prompt for manual entry)
|
|
132
|
+
• Save SYNTH_API_KEY and ENVIRONMENT_API_KEY
|
|
133
|
+
• Verify Modal is authenticated
|
|
134
|
+
• Test backend connectivity
|
|
135
|
+
|
|
136
|
+
WHAT YOU'LL NEED
|
|
137
|
+
----------------
|
|
138
|
+
• Web browser for authentication
|
|
139
|
+
• Modal account (for deployments): https://modal.com
|
|
140
|
+
• Active internet connection
|
|
141
|
+
|
|
142
|
+
TROUBLESHOOTING
|
|
143
|
+
---------------
|
|
144
|
+
1. "Failed to fetch keys from frontend"
|
|
145
|
+
→ You'll be prompted to enter keys manually
|
|
146
|
+
→ Get keys from: https://www.usesynth.ai/dashboard/settings
|
|
147
|
+
|
|
148
|
+
2. "Modal authentication status: not authenticated"
|
|
149
|
+
→ Run: modal token new
|
|
150
|
+
→ Then re-run: uvx synth-ai setup
|
|
151
|
+
|
|
152
|
+
3. Browser doesn't open
|
|
153
|
+
→ Check your default browser settings
|
|
154
|
+
→ Or enter keys manually when prompted
|
|
155
|
+
|
|
156
|
+
WHERE ARE KEYS STORED?
|
|
157
|
+
----------------------
|
|
158
|
+
Keys are saved to: ~/.synth/config
|
|
159
|
+
|
|
160
|
+
This file is read automatically by all Synth AI commands.
|
|
161
|
+
You can also use .env files in your project directory.
|
|
162
|
+
|
|
163
|
+
NEXT STEPS
|
|
164
|
+
----------
|
|
165
|
+
After setup completes:
|
|
166
|
+
1. Deploy your task app: uvx synth-ai deploy
|
|
167
|
+
2. Start local development: uvx synth-ai deploy --runtime=uvicorn
|
|
168
|
+
3. Run training: uvx synth-ai train
|
|
169
|
+
|
|
170
|
+
For more information: https://docs.usesynth.ai/setup
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
COMMAND_HELP = {
|
|
174
|
+
"deploy": DEPLOY_HELP,
|
|
175
|
+
"setup": SETUP_HELP,
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def get_command_help(command: str) -> str | None:
|
|
180
|
+
"""Get detailed help text for a command."""
|
|
181
|
+
return COMMAND_HELP.get(command)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
__all__ = ["DEPLOY_HELP", "SETUP_HELP", "COMMAND_HELP", "get_command_help"]
|
|
185
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""Help command implementation."""
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
from click.exceptions import Exit
|
|
5
|
+
|
|
6
|
+
from . import COMMAND_HELP, get_command_help
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@click.command("help")
|
|
10
|
+
@click.argument("command_name", type=str, required=False)
|
|
11
|
+
def help_command(command_name: str | None) -> None:
|
|
12
|
+
"""Display detailed help for Synth AI commands.
|
|
13
|
+
|
|
14
|
+
USAGE
|
|
15
|
+
-----
|
|
16
|
+
uvx synth-ai help [COMMAND]
|
|
17
|
+
|
|
18
|
+
EXAMPLES
|
|
19
|
+
--------
|
|
20
|
+
# List available help topics
|
|
21
|
+
uvx synth-ai help
|
|
22
|
+
|
|
23
|
+
# Get detailed help for deploy
|
|
24
|
+
uvx synth-ai help deploy
|
|
25
|
+
|
|
26
|
+
# Get detailed help for setup
|
|
27
|
+
uvx synth-ai help setup
|
|
28
|
+
"""
|
|
29
|
+
if not command_name:
|
|
30
|
+
# Show list of available help topics
|
|
31
|
+
click.echo("Synth AI - Detailed Help")
|
|
32
|
+
click.echo("=" * 50)
|
|
33
|
+
click.echo("\nAvailable help topics:")
|
|
34
|
+
click.echo("")
|
|
35
|
+
|
|
36
|
+
for cmd in sorted(COMMAND_HELP.keys()):
|
|
37
|
+
click.echo(f" • {cmd}")
|
|
38
|
+
|
|
39
|
+
click.echo("\nUsage:")
|
|
40
|
+
click.echo(" uvx synth-ai help [COMMAND]")
|
|
41
|
+
click.echo("")
|
|
42
|
+
click.echo("Examples:")
|
|
43
|
+
click.echo(" uvx synth-ai help deploy")
|
|
44
|
+
click.echo(" uvx synth-ai help setup")
|
|
45
|
+
click.echo("")
|
|
46
|
+
click.echo("You can also use standard --help flags:")
|
|
47
|
+
click.echo(" uvx synth-ai deploy --help")
|
|
48
|
+
click.echo(" uvx synth-ai setup --help")
|
|
49
|
+
return
|
|
50
|
+
|
|
51
|
+
# Show detailed help for specific command
|
|
52
|
+
help_text = get_command_help(command_name)
|
|
53
|
+
if not help_text:
|
|
54
|
+
click.echo(f"No detailed help available for '{command_name}'", err=True)
|
|
55
|
+
click.echo(f"\nTry: uvx synth-ai {command_name} --help", err=True)
|
|
56
|
+
click.echo("Or: uvx synth-ai help (to see available topics)", err=True)
|
|
57
|
+
raise Exit(1)
|
|
58
|
+
|
|
59
|
+
click.echo(help_text)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_command() -> click.Command:
|
|
63
|
+
"""Get the help command for registration."""
|
|
64
|
+
return help_command
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def register(group: click.Group) -> None:
|
|
68
|
+
"""Register the help command with a Click group."""
|
|
69
|
+
group.add_command(help_command)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
__all__ = ["help_command", "get_command", "register"]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Scan command for discovering active task apps."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
|
|
7
|
+
from synth_ai.cli.commands.scan.core import scan_command
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def register(cli: click.Group) -> None:
|
|
11
|
+
"""Register the scan command with the CLI."""
|
|
12
|
+
cli.add_command(scan_command)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
"""Cloudflare app discovery for scan command."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import re
|
|
7
|
+
import subprocess
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
import httpx
|
|
12
|
+
|
|
13
|
+
from synth_ai.cli.commands.scan.health_checker import check_app_health, extract_app_info
|
|
14
|
+
from synth_ai.cli.commands.scan.models import ScannedApp
|
|
15
|
+
from synth_ai.core.urls import BACKEND_URL_BASE
|
|
16
|
+
|
|
17
|
+
# Regex for parsing quick tunnel URLs from cloudflared output
|
|
18
|
+
_QUICK_TUNNEL_URL_RE = re.compile(r"https://[a-z0-9-]+\.trycloudflare\.com", re.I)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def scan_cloudflare_processes() -> list[dict[str, Any]]:
|
|
22
|
+
"""Scan running cloudflared processes to find tunnels.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
List of tunnel info dicts with keys: port, mode, pid, cmdline, url (if discoverable)
|
|
26
|
+
"""
|
|
27
|
+
tunnels: list[dict[str, Any]] = []
|
|
28
|
+
|
|
29
|
+
# Try using psutil if available
|
|
30
|
+
try:
|
|
31
|
+
import psutil # type: ignore[import-untyped]
|
|
32
|
+
|
|
33
|
+
for proc in psutil.process_iter(["pid", "name", "cmdline"]):
|
|
34
|
+
try:
|
|
35
|
+
if proc.info["name"] and "cloudflared" in proc.info["name"].lower():
|
|
36
|
+
cmdline = proc.info.get("cmdline") or []
|
|
37
|
+
pid = proc.info.get("pid")
|
|
38
|
+
|
|
39
|
+
# Check for quick tunnel: cloudflared tunnel --url http://127.0.0.1:PORT
|
|
40
|
+
for i, arg in enumerate(cmdline):
|
|
41
|
+
if arg == "--url" and i + 1 < len(cmdline):
|
|
42
|
+
local_url = cmdline[i + 1]
|
|
43
|
+
# Extract port from URL like http://127.0.0.1:8000
|
|
44
|
+
port_match = re.search(r":(\d+)$", local_url)
|
|
45
|
+
if port_match:
|
|
46
|
+
port = int(port_match.group(1))
|
|
47
|
+
# Try to get tunnel URL from process stdout/stderr or log files
|
|
48
|
+
tunnel_url = _try_get_quick_tunnel_url(pid, port)
|
|
49
|
+
tunnels.append({
|
|
50
|
+
"port": port,
|
|
51
|
+
"mode": "quick",
|
|
52
|
+
"pid": pid,
|
|
53
|
+
"cmdline": cmdline,
|
|
54
|
+
"url": tunnel_url,
|
|
55
|
+
"local_url": local_url,
|
|
56
|
+
})
|
|
57
|
+
break
|
|
58
|
+
|
|
59
|
+
# Check for managed tunnel: cloudflared tunnel run --token TOKEN
|
|
60
|
+
if arg == "run" and i > 0 and cmdline[i - 1] == "tunnel":
|
|
61
|
+
# Managed tunnel - we can't get URL from process alone
|
|
62
|
+
tunnels.append({
|
|
63
|
+
"port": None, # Unknown from process
|
|
64
|
+
"mode": "managed",
|
|
65
|
+
"pid": pid,
|
|
66
|
+
"cmdline": cmdline,
|
|
67
|
+
"url": None, # Need backend API
|
|
68
|
+
})
|
|
69
|
+
break
|
|
70
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
|
71
|
+
continue
|
|
72
|
+
except ImportError:
|
|
73
|
+
# Fallback to subprocess + ps/pgrep
|
|
74
|
+
try:
|
|
75
|
+
result = subprocess.run(
|
|
76
|
+
["pgrep", "-fl", "cloudflared"],
|
|
77
|
+
capture_output=True,
|
|
78
|
+
text=True,
|
|
79
|
+
timeout=2.0,
|
|
80
|
+
)
|
|
81
|
+
if result.returncode == 0:
|
|
82
|
+
for line in result.stdout.splitlines():
|
|
83
|
+
# Parse line like "12345 cloudflared tunnel --url http://127.0.0.1:8000"
|
|
84
|
+
parts = line.split(None, 1)
|
|
85
|
+
if len(parts) < 2:
|
|
86
|
+
continue
|
|
87
|
+
pid_str, rest = parts
|
|
88
|
+
try:
|
|
89
|
+
pid = int(pid_str)
|
|
90
|
+
except ValueError:
|
|
91
|
+
continue
|
|
92
|
+
|
|
93
|
+
# Check for quick tunnel
|
|
94
|
+
url_match = re.search(r"--url\s+(\S+)", rest)
|
|
95
|
+
if url_match:
|
|
96
|
+
local_url = url_match.group(1)
|
|
97
|
+
port_match = re.search(r":(\d+)$", local_url)
|
|
98
|
+
if port_match:
|
|
99
|
+
port = int(port_match.group(1))
|
|
100
|
+
tunnel_url = _try_get_quick_tunnel_url(pid, port)
|
|
101
|
+
tunnels.append({
|
|
102
|
+
"port": port,
|
|
103
|
+
"mode": "quick",
|
|
104
|
+
"pid": pid,
|
|
105
|
+
"cmdline": rest.split(),
|
|
106
|
+
"url": tunnel_url,
|
|
107
|
+
"local_url": local_url,
|
|
108
|
+
})
|
|
109
|
+
# Check for managed tunnel
|
|
110
|
+
elif "tunnel run" in rest or "tunnel run --token" in rest:
|
|
111
|
+
tunnels.append({
|
|
112
|
+
"port": None,
|
|
113
|
+
"mode": "managed",
|
|
114
|
+
"pid": pid,
|
|
115
|
+
"cmdline": rest.split(),
|
|
116
|
+
"url": None,
|
|
117
|
+
})
|
|
118
|
+
except Exception:
|
|
119
|
+
pass
|
|
120
|
+
|
|
121
|
+
return tunnels
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _try_get_quick_tunnel_url(pid: int | None, port: int) -> str | None:
|
|
125
|
+
"""Try to get quick tunnel URL from process stdout/stderr or log files.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
pid: Process ID
|
|
129
|
+
port: Local port being tunneled
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
Tunnel URL if found, None otherwise
|
|
133
|
+
"""
|
|
134
|
+
if pid is None:
|
|
135
|
+
return None
|
|
136
|
+
|
|
137
|
+
# Try to read from common log file locations
|
|
138
|
+
log_paths = [
|
|
139
|
+
Path(f"/tmp/cloudflared_{port}.log"),
|
|
140
|
+
Path.home() / f".cloudflared_{port}.log",
|
|
141
|
+
Path(f"/tmp/cloudflared_{pid}.log"),
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
for log_path in log_paths:
|
|
145
|
+
try:
|
|
146
|
+
if log_path.exists():
|
|
147
|
+
with log_path.open("r") as f:
|
|
148
|
+
content = f.read()
|
|
149
|
+
match = _QUICK_TUNNEL_URL_RE.search(content)
|
|
150
|
+
if match:
|
|
151
|
+
return match.group(0)
|
|
152
|
+
except Exception:
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
# Try to read from process file descriptors (if accessible)
|
|
156
|
+
try:
|
|
157
|
+
import psutil # type: ignore[import-untyped]
|
|
158
|
+
proc = psutil.Process(pid)
|
|
159
|
+
# Try to read from stdout/stderr if they're pipes/files
|
|
160
|
+
for fd in [proc.stdout, proc.stderr]:
|
|
161
|
+
if fd and hasattr(fd, 'read'):
|
|
162
|
+
try:
|
|
163
|
+
# Read last few KB
|
|
164
|
+
content = fd.read(8192) if hasattr(fd, 'read') else None
|
|
165
|
+
if content:
|
|
166
|
+
if isinstance(content, bytes):
|
|
167
|
+
content = content.decode('utf-8', errors='ignore')
|
|
168
|
+
match = _QUICK_TUNNEL_URL_RE.search(content)
|
|
169
|
+
if match:
|
|
170
|
+
return match.group(0)
|
|
171
|
+
except Exception:
|
|
172
|
+
pass
|
|
173
|
+
except Exception:
|
|
174
|
+
pass
|
|
175
|
+
|
|
176
|
+
return None
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
async def fetch_managed_tunnels(api_key: str | None) -> list[dict[str, Any]]:
|
|
180
|
+
"""Fetch active managed tunnels from backend API.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
api_key: SYNTH_API_KEY for authentication
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
List of tunnel metadata dicts
|
|
187
|
+
"""
|
|
188
|
+
if not api_key:
|
|
189
|
+
return []
|
|
190
|
+
|
|
191
|
+
try:
|
|
192
|
+
headers: dict[str, str] = {}
|
|
193
|
+
if api_key:
|
|
194
|
+
headers["Authorization"] = f"Bearer {api_key}"
|
|
195
|
+
|
|
196
|
+
async with httpx.AsyncClient(timeout=5.0) as client:
|
|
197
|
+
url = f"{BACKEND_URL_BASE.rstrip('/')}/api/v1/tunnels/"
|
|
198
|
+
resp = await client.get(url, headers=headers)
|
|
199
|
+
if resp.status_code == 200:
|
|
200
|
+
data = resp.json()
|
|
201
|
+
if isinstance(data, list):
|
|
202
|
+
# Filter for active tunnels
|
|
203
|
+
return [t for t in data if isinstance(t, dict) and t.get("status") == "active"]
|
|
204
|
+
except Exception:
|
|
205
|
+
pass
|
|
206
|
+
|
|
207
|
+
return []
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def get_tunnel_processes() -> dict[int, Any]:
|
|
211
|
+
"""Get tunnel processes from global state.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
Dict mapping port -> process handle
|
|
215
|
+
"""
|
|
216
|
+
try:
|
|
217
|
+
from synth_ai.core.integrations.cloudflare import _TUNNEL_PROCESSES
|
|
218
|
+
|
|
219
|
+
return _TUNNEL_PROCESSES.copy()
|
|
220
|
+
except Exception:
|
|
221
|
+
return {}
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
async def scan_cloudflare_apps(
|
|
225
|
+
api_key: str | None,
|
|
226
|
+
env_api_key: str | None,
|
|
227
|
+
env_file: Path | None = None,
|
|
228
|
+
timeout: float = 2.0,
|
|
229
|
+
) -> list[ScannedApp]:
|
|
230
|
+
"""Scan for Cloudflare tunnel apps using process-based discovery.
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
api_key: SYNTH_API_KEY for backend API
|
|
234
|
+
env_api_key: ENVIRONMENT_API_KEY for health checks
|
|
235
|
+
env_file: Not used (kept for API compatibility)
|
|
236
|
+
timeout: Health check timeout
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
List of discovered ScannedApp instances
|
|
240
|
+
"""
|
|
241
|
+
apps: list[ScannedApp] = []
|
|
242
|
+
seen_urls: set[str] = set()
|
|
243
|
+
|
|
244
|
+
# Method 1: Check cloudflared processes (primary discovery method)
|
|
245
|
+
process_tunnels = scan_cloudflare_processes()
|
|
246
|
+
for tunnel_info in process_tunnels:
|
|
247
|
+
tunnel_url = tunnel_info.get("url")
|
|
248
|
+
port = tunnel_info.get("port")
|
|
249
|
+
mode = tunnel_info.get("mode")
|
|
250
|
+
pid = tunnel_info.get("pid")
|
|
251
|
+
|
|
252
|
+
if mode == "quick" and tunnel_url:
|
|
253
|
+
# Quick tunnel with discovered URL
|
|
254
|
+
if tunnel_url not in seen_urls:
|
|
255
|
+
seen_urls.add(tunnel_url)
|
|
256
|
+
health_status, metadata = await check_app_health(tunnel_url, env_api_key, timeout)
|
|
257
|
+
app_id, task_name, dataset_id, version = extract_app_info(metadata)
|
|
258
|
+
|
|
259
|
+
tunnel_hostname = tunnel_url.replace("https://", "").split("/")[0]
|
|
260
|
+
name = app_id or task_name or tunnel_hostname or tunnel_url
|
|
261
|
+
|
|
262
|
+
apps.append(
|
|
263
|
+
ScannedApp(
|
|
264
|
+
name=name,
|
|
265
|
+
url=tunnel_url,
|
|
266
|
+
type="cloudflare",
|
|
267
|
+
health_status=health_status,
|
|
268
|
+
port=port,
|
|
269
|
+
tunnel_mode="quick",
|
|
270
|
+
tunnel_hostname=tunnel_hostname,
|
|
271
|
+
app_id=app_id,
|
|
272
|
+
task_name=task_name,
|
|
273
|
+
dataset_id=dataset_id,
|
|
274
|
+
version=version,
|
|
275
|
+
metadata={**metadata, "pid": pid, "local_port": port},
|
|
276
|
+
discovered_via="cloudflared_process",
|
|
277
|
+
)
|
|
278
|
+
)
|
|
279
|
+
elif mode == "quick" and port:
|
|
280
|
+
# Quick tunnel process found but URL not discoverable
|
|
281
|
+
# We know there's a tunnel but can't get the public URL
|
|
282
|
+
# Skip for now - could potentially match with backend API later
|
|
283
|
+
pass
|
|
284
|
+
elif mode == "managed":
|
|
285
|
+
# Managed tunnel - need backend API to get URL
|
|
286
|
+
# Will be handled by backend API query below
|
|
287
|
+
pass
|
|
288
|
+
|
|
289
|
+
# Method 2: Query backend API for managed tunnels
|
|
290
|
+
synth_api_key = api_key or os.getenv("SYNTH_API_KEY")
|
|
291
|
+
managed_tunnels = await fetch_managed_tunnels(synth_api_key)
|
|
292
|
+
for tunnel in managed_tunnels:
|
|
293
|
+
hostname = tunnel.get("hostname")
|
|
294
|
+
local_port = tunnel.get("local_port")
|
|
295
|
+
if hostname:
|
|
296
|
+
url = f"https://{hostname}"
|
|
297
|
+
if url not in seen_urls:
|
|
298
|
+
seen_urls.add(url)
|
|
299
|
+
health_status, metadata = await check_app_health(url, env_api_key, timeout)
|
|
300
|
+
app_id, task_name, dataset_id, version = extract_app_info(metadata)
|
|
301
|
+
|
|
302
|
+
name = app_id or task_name or hostname.split(".")[0] or url
|
|
303
|
+
|
|
304
|
+
apps.append(
|
|
305
|
+
ScannedApp(
|
|
306
|
+
name=name,
|
|
307
|
+
url=url,
|
|
308
|
+
type="cloudflare",
|
|
309
|
+
health_status=health_status,
|
|
310
|
+
port=local_port,
|
|
311
|
+
tunnel_mode="managed",
|
|
312
|
+
tunnel_hostname=hostname,
|
|
313
|
+
app_id=app_id,
|
|
314
|
+
task_name=task_name,
|
|
315
|
+
dataset_id=dataset_id,
|
|
316
|
+
version=version,
|
|
317
|
+
metadata={**metadata, **tunnel},
|
|
318
|
+
discovered_via="backend_api",
|
|
319
|
+
)
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
# Method 3: Check global tunnel processes state (if tunnels started in same Python process)
|
|
323
|
+
tunnel_procs = get_tunnel_processes()
|
|
324
|
+
for port, proc in tunnel_procs.items():
|
|
325
|
+
# These are tunnels we started - try to match with discovered URLs
|
|
326
|
+
# or check if we can get URL from process
|
|
327
|
+
if proc and proc.poll() is None: # Process still running
|
|
328
|
+
# Try to get URL from quick tunnel
|
|
329
|
+
tunnel_url = _try_get_quick_tunnel_url(proc.pid, port)
|
|
330
|
+
if tunnel_url and tunnel_url not in seen_urls:
|
|
331
|
+
seen_urls.add(tunnel_url)
|
|
332
|
+
health_status, metadata = await check_app_health(tunnel_url, env_api_key, timeout)
|
|
333
|
+
app_id, task_name, dataset_id, version = extract_app_info(metadata)
|
|
334
|
+
|
|
335
|
+
tunnel_hostname = tunnel_url.replace("https://", "").split("/")[0]
|
|
336
|
+
name = app_id or task_name or tunnel_hostname or tunnel_url
|
|
337
|
+
|
|
338
|
+
apps.append(
|
|
339
|
+
ScannedApp(
|
|
340
|
+
name=name,
|
|
341
|
+
url=tunnel_url,
|
|
342
|
+
type="cloudflare",
|
|
343
|
+
health_status=health_status,
|
|
344
|
+
port=port,
|
|
345
|
+
tunnel_mode="quick",
|
|
346
|
+
tunnel_hostname=tunnel_hostname,
|
|
347
|
+
app_id=app_id,
|
|
348
|
+
task_name=task_name,
|
|
349
|
+
dataset_id=dataset_id,
|
|
350
|
+
version=version,
|
|
351
|
+
metadata={**metadata, "pid": proc.pid},
|
|
352
|
+
discovered_via="cloudflared_process",
|
|
353
|
+
)
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
# Method 4: Check service records file (tunnels deployed via synth-ai)
|
|
357
|
+
try:
|
|
358
|
+
from synth_ai.cli.lib.tunnel_records import cleanup_stale_records, load_service_records
|
|
359
|
+
|
|
360
|
+
# Clean up stale records first
|
|
361
|
+
cleanup_stale_records()
|
|
362
|
+
|
|
363
|
+
records = load_service_records()
|
|
364
|
+
# Filter for tunnels only
|
|
365
|
+
records = {k: v for k, v in records.items() if v.get("type") == "tunnel"}
|
|
366
|
+
for _, record in records.items():
|
|
367
|
+
tunnel_url = record.get("url")
|
|
368
|
+
port = record.get("port")
|
|
369
|
+
mode = record.get("mode", "quick")
|
|
370
|
+
hostname = record.get("hostname")
|
|
371
|
+
|
|
372
|
+
if tunnel_url and tunnel_url not in seen_urls:
|
|
373
|
+
seen_urls.add(tunnel_url)
|
|
374
|
+
health_status, metadata = await check_app_health(tunnel_url, env_api_key, timeout)
|
|
375
|
+
app_id, task_name, dataset_id, version = extract_app_info(metadata)
|
|
376
|
+
|
|
377
|
+
if not hostname and tunnel_url.startswith("https://"):
|
|
378
|
+
hostname = tunnel_url.replace("https://", "").split("/")[0]
|
|
379
|
+
|
|
380
|
+
name = app_id or task_name or hostname or tunnel_url
|
|
381
|
+
|
|
382
|
+
apps.append(
|
|
383
|
+
ScannedApp(
|
|
384
|
+
name=name,
|
|
385
|
+
url=tunnel_url,
|
|
386
|
+
type="cloudflare",
|
|
387
|
+
health_status=health_status,
|
|
388
|
+
port=port,
|
|
389
|
+
tunnel_mode=mode,
|
|
390
|
+
tunnel_hostname=hostname,
|
|
391
|
+
app_id=app_id,
|
|
392
|
+
task_name=task_name,
|
|
393
|
+
dataset_id=dataset_id,
|
|
394
|
+
version=version,
|
|
395
|
+
metadata={**metadata, **record},
|
|
396
|
+
discovered_via="tunnel_records",
|
|
397
|
+
)
|
|
398
|
+
)
|
|
399
|
+
except Exception:
|
|
400
|
+
pass # Fail silently if records unavailable
|
|
401
|
+
|
|
402
|
+
return apps
|
|
403
|
+
|