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
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
OpenAI Responses API extensions for OpenAIStandard vendor.
|
|
3
|
-
|
|
4
|
-
This module contains the Responses API and Harmony encoding methods
|
|
5
|
-
that extend the OpenAIStandard class functionality.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import uuid
|
|
9
|
-
from typing import Any
|
|
10
|
-
|
|
11
|
-
from synth_ai.lm.tools.base import BaseTool
|
|
12
|
-
from synth_ai.lm.vendors.base import BaseLMResponse
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def _silent_backoff_handler(_details):
|
|
16
|
-
"""No-op handler to keep stdout clean while still allowing visibility via logging if desired."""
|
|
17
|
-
pass
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
DEFAULT_EXCEPTIONS_TO_RETRY = (
|
|
21
|
-
Exception, # Will be more specific when imported
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class OpenAIResponsesAPIMixin:
|
|
26
|
-
"""Mixin class providing Responses API functionality for OpenAI vendors."""
|
|
27
|
-
|
|
28
|
-
async def _hit_api_async_responses(
|
|
29
|
-
self,
|
|
30
|
-
model: str,
|
|
31
|
-
messages: list[dict[str, Any]],
|
|
32
|
-
lm_config: dict[str, Any],
|
|
33
|
-
previous_response_id: str | None = None,
|
|
34
|
-
use_ephemeral_cache_only: bool = False,
|
|
35
|
-
tools: list[BaseTool] | None = None,
|
|
36
|
-
) -> BaseLMResponse:
|
|
37
|
-
"""Use OpenAI Responses API for supported models."""
|
|
38
|
-
|
|
39
|
-
print(f"🔍 RESPONSES API: Called for model {model}")
|
|
40
|
-
print(f"🔍 RESPONSES API: previous_response_id = {previous_response_id}")
|
|
41
|
-
|
|
42
|
-
# Check if the client has responses attribute
|
|
43
|
-
if not hasattr(self.async_client, "responses"):
|
|
44
|
-
print("🔍 RESPONSES API: Client doesn't have responses attribute, using fallback")
|
|
45
|
-
# Fallback - use chat completions with simulated response_id
|
|
46
|
-
response = await self._hit_api_async(
|
|
47
|
-
model=model,
|
|
48
|
-
messages=messages,
|
|
49
|
-
lm_config=lm_config,
|
|
50
|
-
use_ephemeral_cache_only=use_ephemeral_cache_only,
|
|
51
|
-
tools=tools,
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
# Add Responses API fields
|
|
55
|
-
if not response.response_id:
|
|
56
|
-
import uuid
|
|
57
|
-
|
|
58
|
-
response.response_id = str(uuid.uuid4())
|
|
59
|
-
response.api_type = "responses"
|
|
60
|
-
return response
|
|
61
|
-
|
|
62
|
-
# Use the official Responses API
|
|
63
|
-
try:
|
|
64
|
-
# Common API call params for Responses API
|
|
65
|
-
api_params = {
|
|
66
|
-
"model": model,
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
# For Responses API, we use 'input' parameter
|
|
70
|
-
if previous_response_id:
|
|
71
|
-
# Continue existing thread
|
|
72
|
-
api_params["previous_response_id"] = previous_response_id
|
|
73
|
-
# Only pass the new user input
|
|
74
|
-
if messages and len(messages) > 0:
|
|
75
|
-
# Get the last user message content
|
|
76
|
-
last_message = messages[-1]
|
|
77
|
-
api_params["input"] = last_message.get("content", "")
|
|
78
|
-
else:
|
|
79
|
-
# Start new thread - combine system and user messages into input
|
|
80
|
-
if messages and len(messages) > 0:
|
|
81
|
-
# Combine messages into a single input string
|
|
82
|
-
input_parts = []
|
|
83
|
-
for msg in messages:
|
|
84
|
-
role = msg.get("role", "")
|
|
85
|
-
content = msg.get("content", "")
|
|
86
|
-
if role == "system":
|
|
87
|
-
input_parts.append(f"System: {content}")
|
|
88
|
-
elif role == "user":
|
|
89
|
-
input_parts.append(f"User: {content}")
|
|
90
|
-
elif role == "assistant":
|
|
91
|
-
input_parts.append(f"Assistant: {content}")
|
|
92
|
-
api_params["input"] = "\n".join(input_parts)
|
|
93
|
-
|
|
94
|
-
# Add tools if provided
|
|
95
|
-
if tools and all(isinstance(tool, BaseTool) for tool in tools):
|
|
96
|
-
api_params["tools"] = [tool.to_openai_tool() for tool in tools]
|
|
97
|
-
elif tools:
|
|
98
|
-
api_params["tools"] = tools
|
|
99
|
-
|
|
100
|
-
# Add other parameters from lm_config if needed
|
|
101
|
-
if "max_tokens" in lm_config:
|
|
102
|
-
api_params["max_tokens"] = lm_config["max_tokens"]
|
|
103
|
-
|
|
104
|
-
print(f"🔍 RESPONSES API: Calling with params: {list(api_params.keys())}")
|
|
105
|
-
|
|
106
|
-
# Call the Responses API
|
|
107
|
-
response = await self.async_client.responses.create(**api_params)
|
|
108
|
-
|
|
109
|
-
print(f"🔍 RESPONSES API: Response received, type: {type(response)}")
|
|
110
|
-
|
|
111
|
-
# Extract fields from response
|
|
112
|
-
output_text = getattr(response, "output_text", getattr(response, "content", ""))
|
|
113
|
-
reasoning_obj = getattr(response, "reasoning", None)
|
|
114
|
-
response_id = getattr(response, "id", None)
|
|
115
|
-
|
|
116
|
-
# Debug reasoning type (only first time)
|
|
117
|
-
if reasoning_obj and not hasattr(self, "_reasoning_logged"):
|
|
118
|
-
print(f"🔍 RESPONSES API: Reasoning type: {type(reasoning_obj)}")
|
|
119
|
-
print(
|
|
120
|
-
f"🔍 RESPONSES API: Reasoning attributes: {[x for x in dir(reasoning_obj) if not x.startswith('_')]}"
|
|
121
|
-
)
|
|
122
|
-
self._reasoning_logged = True
|
|
123
|
-
|
|
124
|
-
# Handle reasoning - it might be an object or a string
|
|
125
|
-
reasoning = None
|
|
126
|
-
if reasoning_obj:
|
|
127
|
-
if isinstance(reasoning_obj, str):
|
|
128
|
-
# Synth backend returns full reasoning as string
|
|
129
|
-
reasoning = reasoning_obj
|
|
130
|
-
else:
|
|
131
|
-
# OpenAI returns a Reasoning object
|
|
132
|
-
# Try to get summary first, but preserve entire object if no summary
|
|
133
|
-
if hasattr(reasoning_obj, "summary") and reasoning_obj.summary:
|
|
134
|
-
reasoning = reasoning_obj.summary
|
|
135
|
-
else:
|
|
136
|
-
# Preserve the full object structure as JSON
|
|
137
|
-
# This includes effort level and any other fields
|
|
138
|
-
if hasattr(reasoning_obj, "model_dump_json"):
|
|
139
|
-
reasoning = reasoning_obj.model_dump_json()
|
|
140
|
-
elif hasattr(reasoning_obj, "to_dict"):
|
|
141
|
-
import json
|
|
142
|
-
|
|
143
|
-
reasoning = json.dumps(reasoning_obj.to_dict())
|
|
144
|
-
else:
|
|
145
|
-
reasoning = str(reasoning_obj)
|
|
146
|
-
|
|
147
|
-
# Handle tool calls if present
|
|
148
|
-
tool_calls = None
|
|
149
|
-
if hasattr(response, "tool_calls") and response.tool_calls:
|
|
150
|
-
tool_calls = [
|
|
151
|
-
{
|
|
152
|
-
"id": tc.id,
|
|
153
|
-
"type": tc.type,
|
|
154
|
-
"function": {
|
|
155
|
-
"name": tc.function.name,
|
|
156
|
-
"arguments": tc.function.arguments,
|
|
157
|
-
},
|
|
158
|
-
}
|
|
159
|
-
for tc in response.tool_calls
|
|
160
|
-
]
|
|
161
|
-
|
|
162
|
-
print(f"🔍 RESPONSES API: Extracted response_id = {response_id}")
|
|
163
|
-
|
|
164
|
-
return BaseLMResponse(
|
|
165
|
-
raw_response=output_text,
|
|
166
|
-
response_id=response_id,
|
|
167
|
-
reasoning=reasoning,
|
|
168
|
-
api_type="responses",
|
|
169
|
-
tool_calls=tool_calls,
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
except (AttributeError, Exception) as e:
|
|
173
|
-
print(f"🔍 RESPONSES API: Error calling Responses API: {e}")
|
|
174
|
-
# No fallback - raise the error
|
|
175
|
-
raise
|
|
176
|
-
|
|
177
|
-
async def _hit_api_async_harmony(
|
|
178
|
-
self,
|
|
179
|
-
model: str,
|
|
180
|
-
messages: list[dict[str, Any]],
|
|
181
|
-
lm_config: dict[str, Any],
|
|
182
|
-
previous_response_id: str | None = None,
|
|
183
|
-
use_ephemeral_cache_only: bool = False,
|
|
184
|
-
tools: list[BaseTool] | None = None,
|
|
185
|
-
) -> BaseLMResponse:
|
|
186
|
-
"""Use Harmony encoding for OSS-GPT models."""
|
|
187
|
-
if not self.harmony_available:
|
|
188
|
-
raise ImportError(
|
|
189
|
-
"openai-harmony package required for OSS-GPT models. Install with: pip install openai-harmony"
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
from openai_harmony import Conversation, Message, Role
|
|
193
|
-
|
|
194
|
-
# Convert messages to Harmony format
|
|
195
|
-
harmony_messages = []
|
|
196
|
-
for msg in messages:
|
|
197
|
-
role = (
|
|
198
|
-
Role.SYSTEM
|
|
199
|
-
if msg["role"] == "system"
|
|
200
|
-
else (Role.USER if msg["role"] == "user" else Role.ASSISTANT)
|
|
201
|
-
)
|
|
202
|
-
content = msg["content"]
|
|
203
|
-
# Handle multimodal content
|
|
204
|
-
if isinstance(content, list):
|
|
205
|
-
# Extract text content for now
|
|
206
|
-
text_parts = [
|
|
207
|
-
part.get("text", "") for part in content if part.get("type") == "text"
|
|
208
|
-
]
|
|
209
|
-
content = " ".join(text_parts)
|
|
210
|
-
harmony_messages.append(Message.from_role_and_content(role, content))
|
|
211
|
-
|
|
212
|
-
conv = Conversation.from_messages(harmony_messages)
|
|
213
|
-
tokens = self.harmony_enc.render_conversation_for_completion(conv, Role.ASSISTANT)
|
|
214
|
-
|
|
215
|
-
# For now, we'll need to integrate with Synth GPU endpoint
|
|
216
|
-
# This would require the actual endpoint to be configured
|
|
217
|
-
# Placeholder for actual Synth GPU call
|
|
218
|
-
import os
|
|
219
|
-
|
|
220
|
-
import aiohttp
|
|
221
|
-
|
|
222
|
-
synth_gpu_endpoint = os.getenv("SYNTH_GPU_HARMONY_ENDPOINT")
|
|
223
|
-
if not synth_gpu_endpoint:
|
|
224
|
-
raise ValueError("SYNTH_GPU_HARMONY_ENDPOINT environment variable not set")
|
|
225
|
-
|
|
226
|
-
async with aiohttp.ClientSession() as session, session.post(
|
|
227
|
-
f"{synth_gpu_endpoint}/v1/completions",
|
|
228
|
-
json={
|
|
229
|
-
"model": model,
|
|
230
|
-
"prompt": tokens,
|
|
231
|
-
"max_tokens": lm_config.get("max_tokens", 4096),
|
|
232
|
-
"temperature": lm_config.get("temperature", 0.8),
|
|
233
|
-
},
|
|
234
|
-
) as resp:
|
|
235
|
-
result = await resp.json()
|
|
236
|
-
|
|
237
|
-
# Parse response using Harmony
|
|
238
|
-
response_tokens = result.get("choices", [{}])[0].get("text", "")
|
|
239
|
-
parsed = self.harmony_enc.parse_messages_from_completion_tokens(
|
|
240
|
-
response_tokens, Role.ASSISTANT
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
if parsed:
|
|
244
|
-
assistant_msg = (
|
|
245
|
-
parsed[-1].content_text()
|
|
246
|
-
if hasattr(parsed[-1], "content_text")
|
|
247
|
-
else str(parsed[-1])
|
|
248
|
-
)
|
|
249
|
-
else:
|
|
250
|
-
assistant_msg = response_tokens
|
|
251
|
-
|
|
252
|
-
return BaseLMResponse(
|
|
253
|
-
raw_response=assistant_msg,
|
|
254
|
-
response_id=previous_response_id or str(uuid.uuid4()),
|
|
255
|
-
api_type="harmony",
|
|
256
|
-
)
|
synth_ai/lm/vendors/retries.py
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
|
-
import backoff
|
|
4
|
-
|
|
5
|
-
# Number of retry attempts that some legacy decorators rely on.
|
|
6
|
-
BACKOFF_TOLERANCE: int = 20
|
|
7
|
-
|
|
8
|
-
# Maximum wall-clock seconds allowed for exponential back-off when retrying an
|
|
9
|
-
# LLM API call. This can be overridden at runtime with the environment
|
|
10
|
-
# variable `SYNTH_AI_MAX_BACKOFF`.
|
|
11
|
-
|
|
12
|
-
try:
|
|
13
|
-
MAX_BACKOFF: int = max(1, int(os.getenv("SYNTH_AI_MAX_BACKOFF", "120")))
|
|
14
|
-
except ValueError:
|
|
15
|
-
MAX_BACKOFF = 120
|
|
16
|
-
|
|
17
|
-
# Re-export backoff for convenient import patterns elsewhere
|
|
18
|
-
__all__ = [
|
|
19
|
-
"BACKOFF_TOLERANCE",
|
|
20
|
-
"MAX_BACKOFF",
|
|
21
|
-
"backoff",
|
|
22
|
-
]
|
|
File without changes
|
|
@@ -1,417 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
import json
|
|
3
|
-
import os
|
|
4
|
-
import random
|
|
5
|
-
import re
|
|
6
|
-
import time
|
|
7
|
-
from typing import Any
|
|
8
|
-
|
|
9
|
-
import httpx
|
|
10
|
-
import requests
|
|
11
|
-
from requests.adapters import HTTPAdapter
|
|
12
|
-
from urllib3.util.retry import Retry
|
|
13
|
-
|
|
14
|
-
from synth_ai.lm.caching.initialize import get_cache_handler
|
|
15
|
-
from synth_ai.lm.tools.base import BaseTool
|
|
16
|
-
from synth_ai.lm.vendors.base import BaseLMResponse, VendorBase
|
|
17
|
-
|
|
18
|
-
# Exception types for retry
|
|
19
|
-
CUSTOM_ENDPOINT_EXCEPTIONS_TO_RETRY: tuple[type[Exception], ...] = (
|
|
20
|
-
requests.RequestException,
|
|
21
|
-
requests.Timeout,
|
|
22
|
-
httpx.RequestError,
|
|
23
|
-
httpx.TimeoutException,
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class CustomEndpointAPI(VendorBase):
|
|
28
|
-
"""Generic vendor client for custom OpenAI-compatible endpoints."""
|
|
29
|
-
|
|
30
|
-
used_for_structured_outputs: bool = False
|
|
31
|
-
exceptions_to_retry: list = list(CUSTOM_ENDPOINT_EXCEPTIONS_TO_RETRY)
|
|
32
|
-
|
|
33
|
-
def __init__(self, endpoint_url: str):
|
|
34
|
-
# Validate and sanitize URL
|
|
35
|
-
self._validate_endpoint_url(endpoint_url)
|
|
36
|
-
self.endpoint_url = endpoint_url
|
|
37
|
-
|
|
38
|
-
# Construct full chat completions URL
|
|
39
|
-
if endpoint_url.endswith("/"):
|
|
40
|
-
endpoint_url = endpoint_url[:-1]
|
|
41
|
-
|
|
42
|
-
# Handle full URLs that already include protocol
|
|
43
|
-
if endpoint_url.startswith(("http://", "https://")):
|
|
44
|
-
# Remove protocol and domain part, keep only the base path if any
|
|
45
|
-
parsed = endpoint_url.replace("https://", "").replace("http://", "")
|
|
46
|
-
base_url = parsed.split("/")[0] # Get domain only
|
|
47
|
-
self.chat_completions_url = f"https://{base_url}/chat/completions"
|
|
48
|
-
self.health_url = f"https://{base_url}/health"
|
|
49
|
-
else:
|
|
50
|
-
# Original logic for domain-only URLs
|
|
51
|
-
self.chat_completions_url = f"https://{endpoint_url}/chat/completions"
|
|
52
|
-
self.health_url = f"https://{endpoint_url}/health"
|
|
53
|
-
|
|
54
|
-
# Setup session with connection pooling and retries
|
|
55
|
-
self.session = self._create_session()
|
|
56
|
-
self.async_client = None # Lazy init
|
|
57
|
-
|
|
58
|
-
# Get auth token from environment (generic support for any auth)
|
|
59
|
-
self.auth_token = os.environ.get("CUSTOM_ENDPOINT_API_TOKEN")
|
|
60
|
-
|
|
61
|
-
def _validate_endpoint_url(self, url: str) -> None:
|
|
62
|
-
"""Validate endpoint URL format and prevent SSRF."""
|
|
63
|
-
# Block dangerous URL patterns
|
|
64
|
-
dangerous_patterns = [
|
|
65
|
-
"file://",
|
|
66
|
-
"ftp://",
|
|
67
|
-
"gopher://",
|
|
68
|
-
"localhost",
|
|
69
|
-
"127.",
|
|
70
|
-
"0.0.0.0",
|
|
71
|
-
"10.",
|
|
72
|
-
"192.168.",
|
|
73
|
-
"172.16.",
|
|
74
|
-
"172.17.",
|
|
75
|
-
"172.18.",
|
|
76
|
-
"172.19.",
|
|
77
|
-
"172.20.",
|
|
78
|
-
"172.21.",
|
|
79
|
-
"172.22.",
|
|
80
|
-
"172.23.",
|
|
81
|
-
"172.24.",
|
|
82
|
-
"172.25.",
|
|
83
|
-
"172.26.",
|
|
84
|
-
"172.27.",
|
|
85
|
-
"172.28.",
|
|
86
|
-
"172.29.",
|
|
87
|
-
"172.30.",
|
|
88
|
-
"172.31.",
|
|
89
|
-
"169.254.", # link-local
|
|
90
|
-
"::1",
|
|
91
|
-
"fc00:",
|
|
92
|
-
"fd00:",
|
|
93
|
-
"fe80:", # IPv6 private
|
|
94
|
-
]
|
|
95
|
-
|
|
96
|
-
for pattern in dangerous_patterns:
|
|
97
|
-
if pattern in url.lower():
|
|
98
|
-
raise ValueError(f"Blocked URL pattern for security: {pattern}")
|
|
99
|
-
|
|
100
|
-
# Limit URL length
|
|
101
|
-
if len(url) > 256:
|
|
102
|
-
raise ValueError("Endpoint URL too long (max 256 chars)")
|
|
103
|
-
|
|
104
|
-
# Basic URL format check
|
|
105
|
-
if not re.match(r"^[a-zA-Z0-9\-._~:/?#\[\]@!$&\'()*+,;=]+$", url):
|
|
106
|
-
raise ValueError(f"Invalid URL format: {url}")
|
|
107
|
-
|
|
108
|
-
def _create_session(self) -> requests.Session:
|
|
109
|
-
"""Create session with retry strategy and connection pooling."""
|
|
110
|
-
session = requests.Session()
|
|
111
|
-
|
|
112
|
-
# Exponential backoff with jitter
|
|
113
|
-
retry_strategy = Retry(
|
|
114
|
-
total=3,
|
|
115
|
-
backoff_factor=1,
|
|
116
|
-
status_forcelist=[429, 500, 502, 503, 504],
|
|
117
|
-
allowed_methods=["POST", "GET"],
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
adapter = HTTPAdapter(max_retries=retry_strategy, pool_connections=10, pool_maxsize=20)
|
|
121
|
-
|
|
122
|
-
session.mount("http://", adapter)
|
|
123
|
-
session.mount("https://", adapter)
|
|
124
|
-
|
|
125
|
-
return session
|
|
126
|
-
|
|
127
|
-
async def _get_async_client(self) -> httpx.AsyncClient:
|
|
128
|
-
"""Lazy init async client with shared retry logic."""
|
|
129
|
-
if self.async_client is None:
|
|
130
|
-
self.async_client = httpx.AsyncClient(
|
|
131
|
-
timeout=httpx.Timeout(30.0),
|
|
132
|
-
limits=httpx.Limits(max_connections=10, max_keepalive_connections=5),
|
|
133
|
-
)
|
|
134
|
-
return self.async_client
|
|
135
|
-
|
|
136
|
-
def _get_timeout(self, lm_config: dict[str, Any]) -> float:
|
|
137
|
-
"""Get timeout with per-call override support."""
|
|
138
|
-
return lm_config.get(
|
|
139
|
-
"timeout", float(os.environ.get("CUSTOM_ENDPOINT_REQUEST_TIMEOUT", "30"))
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
def _get_temperature_override(self) -> float | None:
|
|
143
|
-
"""Get temperature override from environment for this specific endpoint."""
|
|
144
|
-
# Create a safe env var key from the endpoint URL
|
|
145
|
-
# e.g., "example.com/api" -> "CUSTOM_ENDPOINT_TEMP_EXAMPLE_COM_API"
|
|
146
|
-
safe_key = re.sub(r"[^A-Za-z0-9]", "_", self.endpoint_url).upper()
|
|
147
|
-
safe_key = safe_key[:64] # Limit length
|
|
148
|
-
|
|
149
|
-
env_key = f"CUSTOM_ENDPOINT_TEMP_{safe_key}"
|
|
150
|
-
temp_str = os.environ.get(env_key)
|
|
151
|
-
return float(temp_str) if temp_str else None
|
|
152
|
-
|
|
153
|
-
def _compress_tool_schema(self, schema: dict[str, Any]) -> dict[str, Any]:
|
|
154
|
-
"""Compress JSON schema to reduce token usage."""
|
|
155
|
-
if isinstance(schema, dict):
|
|
156
|
-
# Remove verbose keys
|
|
157
|
-
compressed = {
|
|
158
|
-
k: self._compress_tool_schema(v)
|
|
159
|
-
for k, v in schema.items()
|
|
160
|
-
if k not in ["title", "$ref", "$schema"]
|
|
161
|
-
}
|
|
162
|
-
# Shorten descriptions
|
|
163
|
-
if "description" in compressed and len(compressed["description"]) > 50:
|
|
164
|
-
compressed["description"] = compressed["description"][:47] + "..."
|
|
165
|
-
return compressed
|
|
166
|
-
elif isinstance(schema, list):
|
|
167
|
-
return [self._compress_tool_schema(item) for item in schema]
|
|
168
|
-
return schema
|
|
169
|
-
|
|
170
|
-
def _inject_tools_into_prompt(self, system_message: str, tools: list[BaseTool]) -> str:
|
|
171
|
-
"""Inject tool definitions with compressed schemas and clear output format."""
|
|
172
|
-
if not tools:
|
|
173
|
-
return system_message
|
|
174
|
-
|
|
175
|
-
tool_descriptions = []
|
|
176
|
-
for tool in tools:
|
|
177
|
-
schema = tool.arguments.model_json_schema()
|
|
178
|
-
compressed_schema = self._compress_tool_schema(schema)
|
|
179
|
-
|
|
180
|
-
tool_desc = f"Tool: {tool.name}\nDesc: {tool.description}\nParams: {json.dumps(compressed_schema, separators=(',', ':'))}"
|
|
181
|
-
tool_descriptions.append(tool_desc)
|
|
182
|
-
|
|
183
|
-
tools_text = "\n".join(tool_descriptions)
|
|
184
|
-
|
|
185
|
-
return f"""{system_message}
|
|
186
|
-
|
|
187
|
-
Available tools:
|
|
188
|
-
{tools_text}
|
|
189
|
-
|
|
190
|
-
IMPORTANT: To use a tool, respond with JSON wrapped in ```json fences:
|
|
191
|
-
```json
|
|
192
|
-
{{"tool_call": {{"name": "tool_name", "arguments": {{...}}}}}}
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
For regular responses, just respond normally without JSON fences."""
|
|
196
|
-
|
|
197
|
-
def _extract_tool_calls(
|
|
198
|
-
self, content: str, tools: list[BaseTool]
|
|
199
|
-
) -> tuple[list | None, str]:
|
|
200
|
-
"""Extract and validate tool calls from response."""
|
|
201
|
-
# Look for JSON fenced blocks
|
|
202
|
-
json_pattern = r"```json\s*(\{.*?\})\s*```"
|
|
203
|
-
matches = re.findall(json_pattern, content, re.DOTALL)
|
|
204
|
-
|
|
205
|
-
if not matches:
|
|
206
|
-
return None, content
|
|
207
|
-
|
|
208
|
-
tool_calls = []
|
|
209
|
-
cleaned_content = content
|
|
210
|
-
|
|
211
|
-
for match in matches:
|
|
212
|
-
try:
|
|
213
|
-
tool_data = json.loads(match)
|
|
214
|
-
if "tool_call" in tool_data:
|
|
215
|
-
call_data = tool_data["tool_call"]
|
|
216
|
-
tool_name = call_data.get("name")
|
|
217
|
-
|
|
218
|
-
# Validate against available tools
|
|
219
|
-
matching_tool = next((t for t in tools if t.name == tool_name), None)
|
|
220
|
-
if matching_tool:
|
|
221
|
-
# Validate arguments with pydantic
|
|
222
|
-
validated_args = matching_tool.arguments(**call_data.get("arguments", {}))
|
|
223
|
-
tool_calls.append(
|
|
224
|
-
{"name": tool_name, "arguments": validated_args.model_dump()}
|
|
225
|
-
)
|
|
226
|
-
|
|
227
|
-
# Remove tool call from content
|
|
228
|
-
cleaned_content = cleaned_content.replace(
|
|
229
|
-
f"```json\n{match}\n```", ""
|
|
230
|
-
).strip()
|
|
231
|
-
|
|
232
|
-
except (json.JSONDecodeError, Exception):
|
|
233
|
-
# Fall back to treating as normal text if validation fails
|
|
234
|
-
continue
|
|
235
|
-
|
|
236
|
-
return tool_calls if tool_calls else None, cleaned_content
|
|
237
|
-
|
|
238
|
-
def _exponential_backoff_with_jitter(self, attempt: int) -> float:
|
|
239
|
-
"""Calculate backoff time with jitter to prevent thundering herd."""
|
|
240
|
-
base_delay = min(2**attempt, 32) # Cap at 32 seconds
|
|
241
|
-
jitter = random.uniform(0, 1)
|
|
242
|
-
return base_delay + jitter
|
|
243
|
-
|
|
244
|
-
def _handle_rate_limit(self, response: requests.Response) -> None:
|
|
245
|
-
"""Extract and propagate rate limit information."""
|
|
246
|
-
if response.status_code == 429:
|
|
247
|
-
retry_after = response.headers.get("Retry-After")
|
|
248
|
-
if retry_after:
|
|
249
|
-
# Bubble up to synth-ai scheduler
|
|
250
|
-
raise requests.exceptions.RetryError(f"Rate limited. Retry after {retry_after}s")
|
|
251
|
-
|
|
252
|
-
async def _hit_api_async(
|
|
253
|
-
self,
|
|
254
|
-
model: str,
|
|
255
|
-
messages: list[dict[str, Any]],
|
|
256
|
-
lm_config: dict[str, Any],
|
|
257
|
-
use_ephemeral_cache_only: bool = False,
|
|
258
|
-
reasoning_effort: str = "low",
|
|
259
|
-
tools: list[BaseTool] | None = None,
|
|
260
|
-
) -> BaseLMResponse:
|
|
261
|
-
"""Async API call with comprehensive error handling and streaming support."""
|
|
262
|
-
|
|
263
|
-
# Cache integration - check first
|
|
264
|
-
used_cache_handler = get_cache_handler(use_ephemeral_cache_only)
|
|
265
|
-
cache_result = used_cache_handler.hit_managed_cache(
|
|
266
|
-
model, messages, lm_config=lm_config, tools=tools
|
|
267
|
-
)
|
|
268
|
-
if cache_result:
|
|
269
|
-
return cache_result
|
|
270
|
-
|
|
271
|
-
# Apply tool injection
|
|
272
|
-
if tools and messages:
|
|
273
|
-
messages = messages.copy()
|
|
274
|
-
if messages and messages[0].get("role") == "system":
|
|
275
|
-
messages[0]["content"] = self._inject_tools_into_prompt(
|
|
276
|
-
messages[0]["content"], tools
|
|
277
|
-
)
|
|
278
|
-
|
|
279
|
-
# Prepare request
|
|
280
|
-
headers = {"Content-Type": "application/json"}
|
|
281
|
-
if self.auth_token:
|
|
282
|
-
headers["Authorization"] = f"Bearer {self.auth_token}"
|
|
283
|
-
|
|
284
|
-
# Apply temperature override
|
|
285
|
-
temp_override = self._get_temperature_override()
|
|
286
|
-
request_temp = temp_override if temp_override else lm_config.get("temperature", 0.7)
|
|
287
|
-
|
|
288
|
-
payload = {
|
|
289
|
-
"model": model, # Pass through the model name
|
|
290
|
-
"messages": messages,
|
|
291
|
-
"temperature": request_temp,
|
|
292
|
-
"stream": lm_config.get("stream", False),
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
timeout = self._get_timeout(lm_config)
|
|
296
|
-
client = await self._get_async_client()
|
|
297
|
-
|
|
298
|
-
# Make request with retry logic
|
|
299
|
-
for attempt in range(3):
|
|
300
|
-
try:
|
|
301
|
-
response = await client.post(
|
|
302
|
-
self.chat_completions_url, json=payload, headers=headers, timeout=timeout
|
|
303
|
-
)
|
|
304
|
-
|
|
305
|
-
if response.status_code == 429:
|
|
306
|
-
self._handle_rate_limit(response)
|
|
307
|
-
|
|
308
|
-
response.raise_for_status()
|
|
309
|
-
|
|
310
|
-
response_data = response.json()
|
|
311
|
-
content = response_data["choices"][0]["message"]["content"]
|
|
312
|
-
|
|
313
|
-
# Extract tool calls
|
|
314
|
-
tool_calls, clean_content = self._extract_tool_calls(content, tools or [])
|
|
315
|
-
|
|
316
|
-
lm_response = BaseLMResponse(
|
|
317
|
-
raw_response=clean_content, structured_output=None, tool_calls=tool_calls
|
|
318
|
-
)
|
|
319
|
-
|
|
320
|
-
# Add to cache
|
|
321
|
-
used_cache_handler.add_to_managed_cache(
|
|
322
|
-
model, messages, lm_config=lm_config, output=lm_response, tools=tools
|
|
323
|
-
)
|
|
324
|
-
|
|
325
|
-
return lm_response
|
|
326
|
-
|
|
327
|
-
except (httpx.RequestError, httpx.TimeoutException):
|
|
328
|
-
if attempt == 2: # Last attempt
|
|
329
|
-
raise
|
|
330
|
-
await asyncio.sleep(self._exponential_backoff_with_jitter(attempt))
|
|
331
|
-
|
|
332
|
-
def _hit_api_sync(
|
|
333
|
-
self,
|
|
334
|
-
model: str,
|
|
335
|
-
messages: list[dict[str, Any]],
|
|
336
|
-
lm_config: dict[str, Any],
|
|
337
|
-
use_ephemeral_cache_only: bool = False,
|
|
338
|
-
reasoning_effort: str = "low",
|
|
339
|
-
tools: list[BaseTool] | None = None,
|
|
340
|
-
) -> BaseLMResponse:
|
|
341
|
-
"""Sync version with same logic as async."""
|
|
342
|
-
|
|
343
|
-
# Cache integration - check first
|
|
344
|
-
used_cache_handler = get_cache_handler(use_ephemeral_cache_only)
|
|
345
|
-
cache_result = used_cache_handler.hit_managed_cache(
|
|
346
|
-
model, messages, lm_config=lm_config, tools=tools
|
|
347
|
-
)
|
|
348
|
-
if cache_result:
|
|
349
|
-
return cache_result
|
|
350
|
-
|
|
351
|
-
# Apply tool injection
|
|
352
|
-
if tools and messages:
|
|
353
|
-
messages = messages.copy()
|
|
354
|
-
if messages and messages[0].get("role") == "system":
|
|
355
|
-
messages[0]["content"] = self._inject_tools_into_prompt(
|
|
356
|
-
messages[0]["content"], tools
|
|
357
|
-
)
|
|
358
|
-
|
|
359
|
-
# Prepare request
|
|
360
|
-
headers = {"Content-Type": "application/json"}
|
|
361
|
-
if self.auth_token:
|
|
362
|
-
headers["Authorization"] = f"Bearer {self.auth_token}"
|
|
363
|
-
|
|
364
|
-
# Apply temperature override
|
|
365
|
-
temp_override = self._get_temperature_override()
|
|
366
|
-
request_temp = temp_override if temp_override else lm_config.get("temperature", 0.7)
|
|
367
|
-
|
|
368
|
-
payload = {
|
|
369
|
-
"model": model, # Pass through the model name
|
|
370
|
-
"messages": messages,
|
|
371
|
-
"temperature": request_temp,
|
|
372
|
-
"stream": lm_config.get("stream", False),
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
timeout = self._get_timeout(lm_config)
|
|
376
|
-
|
|
377
|
-
# Make request with retry logic
|
|
378
|
-
for attempt in range(3):
|
|
379
|
-
try:
|
|
380
|
-
response = self.session.post(
|
|
381
|
-
self.chat_completions_url, json=payload, headers=headers, timeout=timeout
|
|
382
|
-
)
|
|
383
|
-
|
|
384
|
-
if response.status_code == 429:
|
|
385
|
-
self._handle_rate_limit(response)
|
|
386
|
-
|
|
387
|
-
response.raise_for_status()
|
|
388
|
-
|
|
389
|
-
response_data = response.json()
|
|
390
|
-
content = response_data["choices"][0]["message"]["content"]
|
|
391
|
-
|
|
392
|
-
# Extract tool calls
|
|
393
|
-
tool_calls, clean_content = self._extract_tool_calls(content, tools or [])
|
|
394
|
-
|
|
395
|
-
lm_response = BaseLMResponse(
|
|
396
|
-
raw_response=clean_content, structured_output=None, tool_calls=tool_calls
|
|
397
|
-
)
|
|
398
|
-
|
|
399
|
-
# Add to cache
|
|
400
|
-
used_cache_handler.add_to_managed_cache(
|
|
401
|
-
model, messages, lm_config=lm_config, output=lm_response, tools=tools
|
|
402
|
-
)
|
|
403
|
-
|
|
404
|
-
return lm_response
|
|
405
|
-
|
|
406
|
-
except (requests.RequestException, requests.Timeout):
|
|
407
|
-
if attempt == 2: # Last attempt
|
|
408
|
-
raise
|
|
409
|
-
time.sleep(self._exponential_backoff_with_jitter(attempt))
|
|
410
|
-
|
|
411
|
-
def __del__(self):
|
|
412
|
-
"""Cleanup resources."""
|
|
413
|
-
if hasattr(self, "session"):
|
|
414
|
-
self.session.close()
|
|
415
|
-
if hasattr(self, "async_client") and self.async_client:
|
|
416
|
-
# Schedule cleanup for async client
|
|
417
|
-
pass
|