synth-optimizers 0.2.16__tar.gz → 0.2.22__tar.gz
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_optimizers-0.2.16 → synth_optimizers-0.2.22}/Cargo.lock +5 -5
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/Cargo.toml +10 -2
- synth_optimizers-0.2.16/README.md → synth_optimizers-0.2.22/PKG-INFO +92 -46
- synth_optimizers-0.2.16/PKG-INFO → synth_optimizers-0.2.22/README.md +55 -69
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/pyproject.toml +16 -3
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/Cargo.toml +3 -0
- synth_optimizers-0.2.22/rust/crates/synth_gepa/src/codex_app_server/cost_tests.rs +31 -0
- synth_optimizers-0.2.22/rust/crates/synth_gepa/src/codex_app_server/openrouter_usage.rs +24 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/src/codex_app_server.rs +15 -40
- synth_optimizers-0.2.22/rust/crates/synth_gepa/src/global_gepa_run_index_tests.rs +49 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/src/identities.rs +2 -1
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/src/jesterky_workflow.rs +6 -22
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/src/leakage.rs +3 -2
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/src/lib.rs +133 -177
- synth_optimizers-0.2.22/rust/crates/synth_gepa/src/reported_cost_tests.rs +61 -0
- synth_optimizers-0.2.22/rust/crates/synth_gepa/src/run_loop_terminalization_tests.rs +73 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/src/runtime.rs +11 -22
- synth_optimizers-0.2.22/rust/crates/synth_gepa/src/service/create_run.rs +126 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/src/service.rs +96 -6
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/src/service_ownership.rs +419 -60
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/Cargo.toml +3 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/daytona.rs +4 -8
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/role_agent.rs +1 -12
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/cache.rs +27 -0
- synth_optimizers-0.2.22/rust/crates/synth_optimizer_platform/src/cispo_contract/attempts.rs +452 -0
- synth_optimizers-0.2.22/rust/crates/synth_optimizer_platform/src/cispo_contract/capabilities.rs +548 -0
- synth_optimizers-0.2.22/rust/crates/synth_optimizer_platform/src/cispo_contract/handshake.rs +389 -0
- synth_optimizers-0.2.22/rust/crates/synth_optimizer_platform/src/cispo_contract.rs +1024 -0
- synth_optimizers-0.2.22/rust/crates/synth_optimizer_platform/src/config/env_authority.rs +208 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/config.rs +33 -240
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/container_contract.rs +32 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/event_visualization.rs +4 -6
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/http.rs +5 -5
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/levers.rs +5 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/lib.rs +24 -1
- synth_optimizers-0.2.22/rust/crates/synth_optimizer_platform/src/observability.rs +1061 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/process.rs +5 -4
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/runtime_records.rs +7 -1
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/storage_maintenance.rs +1 -1
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/workspace.rs +184 -7
- synth_optimizers-0.2.22/rust/crates/synth_optimizer_platform/tests/file_size_cap.rs +141 -0
- synth_optimizers-0.2.22/rust/crates/synth_optimizer_platform/tests/proposer_cache_identity.rs +31 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizers_py/Cargo.toml +3 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/__init__.py +38 -2
- synth_optimizers-0.2.22/src/synth_optimizers/cispo.py +145 -0
- synth_optimizers-0.2.22/src/synth_optimizers/cispo_cli.py +201 -0
- synth_optimizers-0.2.22/src/synth_optimizers/cispo_executor.py +801 -0
- synth_optimizers-0.2.22/src/synth_optimizers/cispo_service.py +571 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/cli.py +44 -160
- synth_optimizers-0.2.22/src/synth_optimizers/contracts/__init__.py +55 -0
- synth_optimizers-0.2.22/src/synth_optimizers/contracts/checkpoint_plan.py +124 -0
- synth_optimizers-0.2.22/src/synth_optimizers/contracts/rl_clauses.py +133 -0
- synth_optimizers-0.2.22/src/synth_optimizers/contracts/rl_identity.py +401 -0
- synth_optimizers-0.2.22/src/synth_optimizers/contracts/rl_records.py +623 -0
- synth_optimizers-0.2.22/src/synth_optimizers/contracts/training_schemas.py +401 -0
- synth_optimizers-0.2.22/src/synth_optimizers/eval/catalog/eval.craftax.mlx-local-policy.smoke.v1.toml +70 -0
- synth_optimizers-0.2.22/src/synth_optimizers/eval/catalog/eval.tinker.checkpoint.gsm8k.v1.toml +56 -0
- synth_optimizers-0.2.22/src/synth_optimizers/eval/checkpoint_authority.py +230 -0
- synth_optimizers-0.2.22/src/synth_optimizers/eval/checkpoint_gateway.py +89 -0
- synth_optimizers-0.2.22/src/synth_optimizers/eval/checkpoint_trace.py +78 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/executor.py +5 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/runner.py +36 -4
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/gepa.py +75 -16
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/hosted.py +4 -4
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/o11y.py +148 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/__init__.py +63 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/protocols.py +213 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/__init__.py +24 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/capabilities.py +51 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/checkpoints.py +46 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/client.py +360 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/errors.py +24 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/fake.py +133 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/models.py +16 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/prime.py +140 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/receipts.py +37 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/sampling.py +31 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/sdk.py +522 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/tokenize.py +110 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/training.py +59 -0
- synth_optimizers-0.2.22/src/synth_optimizers/providers/tinker/validation.py +71 -0
- synth_optimizers-0.2.22/src/synth_optimizers/read_models.py +248 -0
- synth_optimizers-0.2.22/src/synth_optimizers/recipes/__init__.py +19 -0
- synth_optimizers-0.2.22/src/synth_optimizers/recipes/banking77.py +229 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/__init__.py +6 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/assembly.py +777 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/benchmark_server.py +187 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/binder.py +789 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/budget.py +261 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/capabilities.py +932 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/catalog.py +1955 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/catalog_events.py +148 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/cli.py +994 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/config.py +933 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/contract.py +623 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/credit.py +436 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/daytona_binary_grader.py +45 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/daytona_substrate.py +322 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/daytona_workspace_control.py +125 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/evaluation.py +1073 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/evaluation_store.py +79 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/evidence.py +50 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/executor.py +1794 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/experiment.py +353 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/experiment_driver.py +171 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/experiment_runner.py +86 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/experiment_service.py +183 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/gateway.py +1658 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/grading.py +70 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/handshake.py +1019 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/leases.py +227 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/lifecycle.py +460 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/objective.py +291 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/plan.py +622 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/plane.py +940 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/policy_sets.py +894 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/ports.py +215 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/probe.py +335 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/queues.py +705 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/read_api.py +79 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/reducer.py +281 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/replay.py +263 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/resolver.py +840 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/runtime_adapters.py +155 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/screening.py +360 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/session.py +1369 -0
- synth_optimizers-0.2.22/src/synth_optimizers/rl/store.py +1318 -0
- synth_optimizers-0.2.22/src/synth_optimizers/runtime/__init__.py +40 -0
- synth_optimizers-0.2.22/src/synth_optimizers/runtime/jobs.py +618 -0
- synth_optimizers-0.2.22/src/synth_optimizers/runtime/operations.py +238 -0
- synth_optimizers-0.2.22/src/synth_optimizers/runtime/projections.py +180 -0
- synth_optimizers-0.2.22/src/synth_optimizers/runtime/stream.py +105 -0
- synth_optimizers-0.2.22/src/synth_optimizers/runtime/training_budget.py +56 -0
- synth_optimizers-0.2.22/src/synth_optimizers/runtime/worker.py +79 -0
- synth_optimizers-0.2.22/src/synth_optimizers/runtime/workshop.py +141 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/sft.py +276 -247
- synth_optimizers-0.2.22/src/synth_optimizers/sft_cli.py +152 -0
- synth_optimizers-0.2.22/src/synth_optimizers/sft_dataset.py +348 -0
- synth_optimizers-0.2.22/src/synth_optimizers/sft_executor.py +637 -0
- synth_optimizers-0.2.22/src/synth_optimizers/training_eval.py +308 -0
- synth_optimizers-0.2.16/rust/crates/synth_optimizer_platform/src/observability.rs +0 -449
- synth_optimizers-0.2.16/src/synth_optimizers/eval/catalog/eval.craftax.llm-policy.smoke.v1.toml +0 -71
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/README.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/openapi/gepa-service-v1.yaml +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/src/machines.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/src/pipeline.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/src/planner.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/src/prompting_best_practices.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/README.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/README.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/app_server.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/codex_home.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/docker.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/jsonrpc_read_window.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/limits.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/local.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/mod.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/nano.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/session.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/substrate.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/supervisor.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/agent_runtime/usage.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/artifact_store.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/artifacts.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/candidates.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/checkpoints.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/configured_limits.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/correlation.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/data_models.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/disk_budget.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/error.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/events.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/evidence.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/failures.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/fsm.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/invariants.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/jesterky.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/jobs.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/limit_engine.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/limits.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/operations.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/projections.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/prompt_program.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/registry.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/resources.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/rollouts.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/scores.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/sensors.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/state_machine.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/stopper.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizer_platform/src/usage.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizers_py/README.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_optimizers_py/src/lib.rs +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/README.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/_synth_optimizers.pyi +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/board_server.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/checkpoints.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/discovery.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gelo/00-index.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gelo/10-cli.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gelo/20-sdk.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gelo/30-hosted.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gelo/containers/00-overview.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gelo/containers/20-contract.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gepa/00-index.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gepa/10-cli.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gepa/20-sdk.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gepa/algorithms/00-overview.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gepa/algorithms/10-pipeline-modes.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gepa/algorithms/20-proposer-and-policies.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gepa/assets/synth-logo.png +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gepa/containers/00-overview.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gepa/containers/10-catalog.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs/gepa/containers/20-contract.md +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/docs_server.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/__init__.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/__main__.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/catalog/eval.craftax.code-policy.smoke.v1.toml +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/catalog/eval.fixture.policy-smoke.v1.toml +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/catalog/eval.gamebench.craftax-code-policy.confirm.v1.toml +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/catalog/eval.gamebench.llm-policy.confirm.v1.toml +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/catalog/eval.mlx.local-policy.smoke.v1.toml +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/commands.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/home.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/models.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/recipes.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/scoring.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/semaphore.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval/staging.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/eval_stats.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/experiment/__init__.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/experiment/__main__.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/experiment/adapters/__init__.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/experiment/adapters/base.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/experiment/adapters/eval_runtime.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/experiment/adapters/gepa_cli.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/experiment/analysis.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/experiment/commands.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/experiment/models.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/experiment/outcomes.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/experiment/plan.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/experiment/runner.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/experiment/spec.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/future_algorithms.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/gelo.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/hosted_config.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/model_catalog.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/observability.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/py.typed +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/sdk.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/training.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/tunnels.py +0 -0
- {synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/src/synth_optimizers/victorialogs.py +0 -0
|
@@ -1306,7 +1306,7 @@ dependencies = [
|
|
|
1306
1306
|
|
|
1307
1307
|
[[package]]
|
|
1308
1308
|
name = "synth_gepa"
|
|
1309
|
-
version = "0.2.
|
|
1309
|
+
version = "0.2.22"
|
|
1310
1310
|
dependencies = [
|
|
1311
1311
|
"base64",
|
|
1312
1312
|
"fs2",
|
|
@@ -1322,7 +1322,7 @@ dependencies = [
|
|
|
1322
1322
|
|
|
1323
1323
|
[[package]]
|
|
1324
1324
|
name = "synth_mapo"
|
|
1325
|
-
version = "0.2.
|
|
1325
|
+
version = "0.2.22"
|
|
1326
1326
|
dependencies = [
|
|
1327
1327
|
"serde",
|
|
1328
1328
|
"serde_json",
|
|
@@ -1334,7 +1334,7 @@ dependencies = [
|
|
|
1334
1334
|
|
|
1335
1335
|
[[package]]
|
|
1336
1336
|
name = "synth_marl_promptopt"
|
|
1337
|
-
version = "0.2.
|
|
1337
|
+
version = "0.2.22"
|
|
1338
1338
|
dependencies = [
|
|
1339
1339
|
"clap",
|
|
1340
1340
|
"serde",
|
|
@@ -1348,7 +1348,7 @@ dependencies = [
|
|
|
1348
1348
|
|
|
1349
1349
|
[[package]]
|
|
1350
1350
|
name = "synth_optimizer_platform"
|
|
1351
|
-
version = "0.2.
|
|
1351
|
+
version = "0.2.22"
|
|
1352
1352
|
dependencies = [
|
|
1353
1353
|
"fs2",
|
|
1354
1354
|
"libc",
|
|
@@ -1365,7 +1365,7 @@ dependencies = [
|
|
|
1365
1365
|
|
|
1366
1366
|
[[package]]
|
|
1367
1367
|
name = "synth_optimizers_py"
|
|
1368
|
-
version = "0.2.
|
|
1368
|
+
version = "0.2.22"
|
|
1369
1369
|
dependencies = [
|
|
1370
1370
|
"pyo3",
|
|
1371
1371
|
"serde_json",
|
|
@@ -3,11 +3,11 @@ members = ["rust/crates/synth_optimizer_platform", "rust/crates/synth_gepa", "ru
|
|
|
3
3
|
resolver = "2"
|
|
4
4
|
|
|
5
5
|
[workspace.package]
|
|
6
|
-
version = "0.2.
|
|
6
|
+
version = "0.2.22"
|
|
7
7
|
edition = "2021"
|
|
8
8
|
license = "Apache-2.0"
|
|
9
9
|
authors = ["Synth Laboratories <josh@usesynth.ai>"]
|
|
10
|
-
repository = "https://github.com/synth-laboratories/
|
|
10
|
+
repository = "https://github.com/synth-laboratories/optimizers"
|
|
11
11
|
|
|
12
12
|
[workspace.dependencies]
|
|
13
13
|
anyhow = "1.0"
|
|
@@ -26,3 +26,11 @@ thiserror = "1.0"
|
|
|
26
26
|
time = { version = "0.3", features = ["formatting", "macros", "parsing"] }
|
|
27
27
|
toml = "0.8"
|
|
28
28
|
uuid = { version = "1.10", features = ["v4"] }
|
|
29
|
+
|
|
30
|
+
# Several constructors and snapshot builders take eight or more distinct domain
|
|
31
|
+
# values. Bundling them into parameter structs would only move the arity into a
|
|
32
|
+
# literal at every call site, and the alternative -- an attribute per function --
|
|
33
|
+
# grows source files that the file-size ratchet in
|
|
34
|
+
# `synth_optimizer_platform/tests/file_size_cap.rs` allows only to shrink.
|
|
35
|
+
[workspace.lints.clippy]
|
|
36
|
+
too_many_arguments = "allow"
|
|
@@ -1,3 +1,39 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: synth-optimizers
|
|
3
|
+
Version: 0.2.22
|
|
4
|
+
Requires-Dist: pydantic>=2.0.0
|
|
5
|
+
Requires-Dist: synth-containers==0.4.3
|
|
6
|
+
Requires-Dist: websocket-client>=1.8.0
|
|
7
|
+
Requires-Dist: datasets>=2.19.0 ; extra == 'banking77'
|
|
8
|
+
Requires-Dist: openai>=1.0.0 ; extra == 'banking77'
|
|
9
|
+
Requires-Dist: fastapi>=0.115 ; extra == 'benchmark-server'
|
|
10
|
+
Requires-Dist: uvicorn>=0.30 ; extra == 'benchmark-server'
|
|
11
|
+
Requires-Dist: httpx>=0.27 ; extra == 'benchmark-server'
|
|
12
|
+
Requires-Dist: daytona==0.210.0 ; extra == 'daytona'
|
|
13
|
+
Requires-Dist: maturin>=1.7.0 ; extra == 'dev'
|
|
14
|
+
Requires-Dist: numpy>=2.0 ; extra == 'dev'
|
|
15
|
+
Requires-Dist: pytest>=8.0.0 ; extra == 'dev'
|
|
16
|
+
Requires-Dist: ruff>=0.6.0 ; extra == 'dev'
|
|
17
|
+
Requires-Dist: ty>=0.0.32 ; extra == 'dev'
|
|
18
|
+
Requires-Dist: pyarrow>=17 ; extra == 'eval-target-build'
|
|
19
|
+
Requires-Dist: huggingface-hub>=0.24 ; extra == 'eval-target-build'
|
|
20
|
+
Requires-Dist: tinker ; extra == 'tinker'
|
|
21
|
+
Requires-Dist: renderers>=0.1.9 ; extra == 'tinker'
|
|
22
|
+
Provides-Extra: banking77
|
|
23
|
+
Provides-Extra: benchmark-server
|
|
24
|
+
Provides-Extra: daytona
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Provides-Extra: eval-target-build
|
|
27
|
+
Provides-Extra: tinker
|
|
28
|
+
Summary: Public Synth optimizer tooling with a Rust GEPA core.
|
|
29
|
+
Author-email: Synth Laboratories <josh@usesynth.ai>
|
|
30
|
+
License-Expression: Apache-2.0
|
|
31
|
+
Requires-Python: >=3.11
|
|
32
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
33
|
+
Project-URL: Homepage, https://github.com/synth-laboratories/optimizers
|
|
34
|
+
Project-URL: Issues, https://github.com/synth-laboratories/optimizers/issues
|
|
35
|
+
Project-URL: Repository, https://github.com/synth-laboratories/optimizers
|
|
36
|
+
|
|
1
37
|
<h1 align="center">synth-optimizers</h1>
|
|
2
38
|
<p align="center">A shared optimizer platform for AI applications — starting with open-source GEPA on a language-agnostic task contract.</p>
|
|
3
39
|
<p align="center">
|
|
@@ -19,31 +55,28 @@ contract.
|
|
|
19
55
|
|
|
20
56
|
| Algorithm | Status | In this repo | Paper & docs |
|
|
21
57
|
| --- | --- | --- | --- |
|
|
22
|
-
| **GEPA** — reflective prompt evolution | Supported | [`rust/crates/synth_gepa/`](rust/crates/synth_gepa/) (Rust engine + service), [`src/synth_optimizers/gepa.py`](src/synth_optimizers/gepa.py) (Python API), [`skills/gepa/SKILL.md`](skills/gepa/SKILL.md) (agent runbook) | [Paper](https://arxiv.org/abs/2507.19457) · [gepa-ai docs](https://gepa-ai.github.io/gepa/) · bundled HTML via `gepa console` |
|
|
23
|
-
| **GELO** — Go-Explore in prompt space (hosted) | Hosted submit | [`src/synth_optimizers/gelo.py`](src/synth_optimizers/gelo.py), [`skills/gelo/SKILL.md`](skills/gelo/SKILL.md), [`GELO_HOSTED_SDK_CLI_SPEC.md`](GELO_HOSTED_SDK_CLI_SPEC.md) | Bundled HTML via `gelo console` — [`src/synth_optimizers/docs/gelo/`](src/synth_optimizers/docs/gelo/) |
|
|
24
|
-
| **SFT** — supervised fine-tuning
|
|
58
|
+
| **GEPA** — reflective prompt evolution | Supported | [`rust/crates/synth_gepa/`](rust/crates/synth_gepa/) (Rust engine + service), [`src/synth_optimizers/gepa.py`](src/synth_optimizers/gepa.py) (Python API), [`skills/gepa/SKILL.md`](skills/gepa/SKILL.md) (agent runbook) | [Paper](https://arxiv.org/abs/2507.19457) · [gepa-ai docs](https://gepa-ai.github.io/gepa/) · bundled HTML via `synth-optimizers gepa console` |
|
|
59
|
+
| **GELO** — Go-Explore in prompt space (hosted) | Hosted submit | [`src/synth_optimizers/gelo.py`](src/synth_optimizers/gelo.py), [`skills/gelo/SKILL.md`](skills/gelo/SKILL.md), [`GELO_HOSTED_SDK_CLI_SPEC.md`](GELO_HOSTED_SDK_CLI_SPEC.md) | Bundled HTML via `synth-optimizers gelo console` — [`src/synth_optimizers/docs/gelo/`](src/synth_optimizers/docs/gelo/) |
|
|
60
|
+
| **SFT** — supervised fine-tuning | Local + hosted submit | `HostedOptimizerClient.submit_sft()` / `SftService` / `TinkerSftExecutor` | In-process Tinker executor in this repo. Default model `openai/gpt-oss-20b`. |
|
|
61
|
+
| **CISPO** — `cispo.slime.v1` | Local + hosted submit | `HostedOptimizerClient.submit_cispo()` / `TinkerCispoExecutor` | True slime CISPO only. Generic importance sampling is not CISPO. |
|
|
25
62
|
|
|
26
63
|
The shared [`synth_optimizer_platform`](rust/crates/synth_optimizer_platform/)
|
|
27
64
|
crate is the substrate for optimizer implementations; GEPA is the first public
|
|
28
|
-
local algorithm
|
|
29
|
-
|
|
30
|
-
|
|
65
|
+
local algorithm. GELO remains hosted-only. Standalone SFT and CISPO execute in
|
|
66
|
+
this repository against Tinker. Hosted submission is covered in
|
|
67
|
+
[`docs/hosted-optimizers.md`](docs/hosted-optimizers.md). Identity rules are in
|
|
68
|
+
[`docs/sft-cispo-identity.md`](docs/sft-cispo-identity.md).
|
|
31
69
|
|
|
32
|
-
###
|
|
70
|
+
### SFT control plane
|
|
33
71
|
|
|
34
|
-
SFT is served by `synth-optimizers
|
|
35
|
-
|
|
36
|
-
start the public façade:
|
|
72
|
+
SFT is served by `synth-optimizers` with an in-process Tinker executor. No
|
|
73
|
+
`optimizers-beta` process, URL, or service token is required.
|
|
37
74
|
|
|
38
75
|
```bash
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
# In this checkout:
|
|
44
|
-
export SYNTH_OPTIMIZERS_BETA_URL=http://127.0.0.1:8879
|
|
45
|
-
export OPTIMIZERS_BETA_SERVICE_TOKEN=local-dev-token # held only by the façade
|
|
46
|
-
export SYNTH_OPTIMIZERS_SFT_SERVICE_TOKEN=local-qa-token # Workshop / CLI callers
|
|
76
|
+
export TINKER_API_KEY=...
|
|
77
|
+
export SYNTH_OPTIMIZERS_SFT_SERVICE_TOKEN=local-qa-token
|
|
78
|
+
# Fixture-only local QA without paid Tinker work:
|
|
79
|
+
export SYNTH_OPTIMIZERS_SFT_FIXTURE=1
|
|
47
80
|
synth-optimizers sft service --db .sft/service.sqlite --bind 127.0.0.1:8878
|
|
48
81
|
```
|
|
49
82
|
|
|
@@ -76,13 +109,18 @@ pip install synth-optimizers
|
|
|
76
109
|
uv add synth-optimizers
|
|
77
110
|
```
|
|
78
111
|
|
|
112
|
+
This source targets `synth-optimizers==0.2.22` with `synth-containers==0.4.2`.
|
|
113
|
+
For an unpublished candidate, build from a checkout as shown below; published
|
|
114
|
+
versions are listed on PyPI.
|
|
115
|
+
|
|
79
116
|
Install [`uv`](https://github.com/astral-sh/uv) for local development and editable installs.
|
|
80
117
|
|
|
81
118
|
## Local development
|
|
82
119
|
|
|
83
|
-
|
|
120
|
+
Clone the repo and install the local Python/Rust extension in editable mode:
|
|
84
121
|
|
|
85
122
|
```bash
|
|
123
|
+
git clone https://github.com/synth-laboratories/optimizers.git
|
|
86
124
|
cd optimizers
|
|
87
125
|
uv sync --group dev
|
|
88
126
|
uv pip install -e .
|
|
@@ -105,39 +143,31 @@ target_modules = ["stage2_system"]
|
|
|
105
143
|
[seed_candidate]
|
|
106
144
|
stage2_system = "Classify the query into exactly one Banking77 intent. Return only the label."
|
|
107
145
|
|
|
108
|
-
[
|
|
109
|
-
|
|
110
|
-
|
|
146
|
+
[taskset]
|
|
147
|
+
train_ids = ["train:0", "train:1", "train:2", "train:3"]
|
|
148
|
+
heldout_ids = ["test:100", "test:101"]
|
|
149
|
+
|
|
150
|
+
[gepa.task_pools]
|
|
151
|
+
pareto = ["train:0", "train:1", "train:2", "train:3"]
|
|
152
|
+
minibatch = ["train:0", "train:1"]
|
|
153
|
+
reflection = ["train:0", "train:1", "train:2", "train:3"]
|
|
154
|
+
heldout = ["test:100", "test:101"]
|
|
111
155
|
```
|
|
112
156
|
|
|
113
157
|
```python
|
|
114
|
-
from
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
with container.serve() as handle:
|
|
120
|
-
result = OptimizerRun(
|
|
121
|
-
GepaConfig(
|
|
122
|
-
container=handle.connection(),
|
|
123
|
-
taskset=TasksetSelection(train_ids=["train:0", "train:1"], heldout_ids=["test:100"]),
|
|
124
|
-
task_pools=GepaTaskPools(
|
|
125
|
-
pareto=["train:0"],
|
|
126
|
-
minibatch=["train:0"],
|
|
127
|
-
reflection=["train:0", "train:1"],
|
|
128
|
-
heldout=["test:100"],
|
|
129
|
-
),
|
|
130
|
-
program=None,
|
|
131
|
-
objectives=None,
|
|
132
|
-
policy=None,
|
|
133
|
-
)
|
|
134
|
-
).execute()
|
|
158
|
+
from synth_optimizers import GepaRun
|
|
159
|
+
|
|
160
|
+
# Use a complete cookbook config with its task service, policy, and proposer.
|
|
161
|
+
# Configure authorized provider credentials before executing a paid run.
|
|
162
|
+
result = GepaRun.from_toml("gepa.toml").execute()
|
|
135
163
|
|
|
136
164
|
print(result.best_candidate)
|
|
137
165
|
print("cost: unknown" if result.cost_usd is None else f"cost: ${result.cost_usd:.2f}")
|
|
138
166
|
```
|
|
139
167
|
|
|
140
|
-
|
|
168
|
+
The TOML above illustrates task selection, not a standalone task server. Run it
|
|
169
|
+
from the GEPA cookbook directory and add the recipe's policy/proposer settings.
|
|
170
|
+
The legacy `[dataset]` seed selection is not the current GEPA schema.
|
|
141
171
|
|
|
142
172
|
CLI:
|
|
143
173
|
|
|
@@ -147,8 +177,23 @@ synth-optimizers gepa service --db service.sqlite
|
|
|
147
177
|
synth-optimizers events compare --left a.jsonl --right b.jsonl
|
|
148
178
|
```
|
|
149
179
|
|
|
150
|
-
Runnable task examples
|
|
151
|
-
|
|
180
|
+
Runnable task examples are **not in this repository**. They live in the separate
|
|
181
|
+
public repo
|
|
182
|
+
[`synth-laboratories/synth-cookbooks-public`](https://github.com/synth-laboratories/synth-cookbooks-public/tree/main/cookbooks/optimizers/gepa)
|
|
183
|
+
— Banking77, HotpotQA, MiniGrid, and Crafter. TBLite is optional evaluation
|
|
184
|
+
infrastructure. HealthBench is parked because Containers 0.4.2 does not include
|
|
185
|
+
its runtime. Config-relative paths resolve against the config file's directory.
|
|
186
|
+
Follow the selected cookbook's setup instructions before launching:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
git clone https://github.com/synth-laboratories/synth-cookbooks-public.git
|
|
190
|
+
cd synth-cookbooks-public/cookbooks/optimizers/gepa/banking77_container
|
|
191
|
+
synth-optimizers gepa run --config gepa.toml
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
The cookbook configs published there still declare the legacy `[dataset]` seed
|
|
195
|
+
selection, which `0.2.22` ignores; add `[taskset]` and `[gepa.task_pools]`
|
|
196
|
+
blocks like the ones in the quickstart above before one of them will load.
|
|
152
197
|
|
|
153
198
|
<details>
|
|
154
199
|
<summary><strong>Authentication and models</strong></summary>
|
|
@@ -213,3 +258,4 @@ Agent docs: [skills/gepa/SKILL.md](skills/gepa/SKILL.md).
|
|
|
213
258
|
## License
|
|
214
259
|
|
|
215
260
|
Apache-2.0
|
|
261
|
+
|
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: synth-optimizers
|
|
3
|
-
Version: 0.2.16
|
|
4
|
-
Requires-Dist: pydantic>=2.0.0
|
|
5
|
-
Requires-Dist: synth-containers==0.4.1
|
|
6
|
-
Requires-Dist: websocket-client>=1.8.0
|
|
7
|
-
Requires-Dist: datasets>=2.19.0 ; extra == 'banking77'
|
|
8
|
-
Requires-Dist: openai>=1.0.0 ; extra == 'banking77'
|
|
9
|
-
Requires-Dist: maturin>=1.7.0 ; extra == 'dev'
|
|
10
|
-
Requires-Dist: ruff>=0.6.0 ; extra == 'dev'
|
|
11
|
-
Requires-Dist: ty>=0.0.32 ; extra == 'dev'
|
|
12
|
-
Provides-Extra: banking77
|
|
13
|
-
Provides-Extra: dev
|
|
14
|
-
Summary: Public Synth optimizer tooling with a Rust GEPA core.
|
|
15
|
-
Author-email: Synth Laboratories <josh@usesynth.ai>
|
|
16
|
-
License-Expression: Apache-2.0
|
|
17
|
-
Requires-Python: >=3.11
|
|
18
|
-
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
19
|
-
Project-URL: Homepage, https://github.com/synth-laboratories/optimizers
|
|
20
|
-
Project-URL: Issues, https://github.com/synth-laboratories/optimizers/issues
|
|
21
|
-
Project-URL: Repository, https://github.com/synth-laboratories/optimizers
|
|
22
|
-
|
|
23
1
|
<h1 align="center">synth-optimizers</h1>
|
|
24
2
|
<p align="center">A shared optimizer platform for AI applications — starting with open-source GEPA on a language-agnostic task contract.</p>
|
|
25
3
|
<p align="center">
|
|
@@ -41,31 +19,28 @@ contract.
|
|
|
41
19
|
|
|
42
20
|
| Algorithm | Status | In this repo | Paper & docs |
|
|
43
21
|
| --- | --- | --- | --- |
|
|
44
|
-
| **GEPA** — reflective prompt evolution | Supported | [`rust/crates/synth_gepa/`](rust/crates/synth_gepa/) (Rust engine + service), [`src/synth_optimizers/gepa.py`](src/synth_optimizers/gepa.py) (Python API), [`skills/gepa/SKILL.md`](skills/gepa/SKILL.md) (agent runbook) | [Paper](https://arxiv.org/abs/2507.19457) · [gepa-ai docs](https://gepa-ai.github.io/gepa/) · bundled HTML via `gepa console` |
|
|
45
|
-
| **GELO** — Go-Explore in prompt space (hosted) | Hosted submit | [`src/synth_optimizers/gelo.py`](src/synth_optimizers/gelo.py), [`skills/gelo/SKILL.md`](skills/gelo/SKILL.md), [`GELO_HOSTED_SDK_CLI_SPEC.md`](GELO_HOSTED_SDK_CLI_SPEC.md) | Bundled HTML via `gelo console` — [`src/synth_optimizers/docs/gelo/`](src/synth_optimizers/docs/gelo/) |
|
|
46
|
-
| **SFT** — supervised fine-tuning
|
|
22
|
+
| **GEPA** — reflective prompt evolution | Supported | [`rust/crates/synth_gepa/`](rust/crates/synth_gepa/) (Rust engine + service), [`src/synth_optimizers/gepa.py`](src/synth_optimizers/gepa.py) (Python API), [`skills/gepa/SKILL.md`](skills/gepa/SKILL.md) (agent runbook) | [Paper](https://arxiv.org/abs/2507.19457) · [gepa-ai docs](https://gepa-ai.github.io/gepa/) · bundled HTML via `synth-optimizers gepa console` |
|
|
23
|
+
| **GELO** — Go-Explore in prompt space (hosted) | Hosted submit | [`src/synth_optimizers/gelo.py`](src/synth_optimizers/gelo.py), [`skills/gelo/SKILL.md`](skills/gelo/SKILL.md), [`GELO_HOSTED_SDK_CLI_SPEC.md`](GELO_HOSTED_SDK_CLI_SPEC.md) | Bundled HTML via `synth-optimizers gelo console` — [`src/synth_optimizers/docs/gelo/`](src/synth_optimizers/docs/gelo/) |
|
|
24
|
+
| **SFT** — supervised fine-tuning | Local + hosted submit | `HostedOptimizerClient.submit_sft()` / `SftService` / `TinkerSftExecutor` | In-process Tinker executor in this repo. Default model `openai/gpt-oss-20b`. |
|
|
25
|
+
| **CISPO** — `cispo.slime.v1` | Local + hosted submit | `HostedOptimizerClient.submit_cispo()` / `TinkerCispoExecutor` | True slime CISPO only. Generic importance sampling is not CISPO. |
|
|
47
26
|
|
|
48
27
|
The shared [`synth_optimizer_platform`](rust/crates/synth_optimizer_platform/)
|
|
49
28
|
crate is the substrate for optimizer implementations; GEPA is the first public
|
|
50
|
-
local algorithm
|
|
51
|
-
|
|
52
|
-
|
|
29
|
+
local algorithm. GELO remains hosted-only. Standalone SFT and CISPO execute in
|
|
30
|
+
this repository against Tinker. Hosted submission is covered in
|
|
31
|
+
[`docs/hosted-optimizers.md`](docs/hosted-optimizers.md). Identity rules are in
|
|
32
|
+
[`docs/sft-cispo-identity.md`](docs/sft-cispo-identity.md).
|
|
53
33
|
|
|
54
|
-
###
|
|
34
|
+
### SFT control plane
|
|
55
35
|
|
|
56
|
-
SFT is served by `synth-optimizers
|
|
57
|
-
|
|
58
|
-
start the public façade:
|
|
36
|
+
SFT is served by `synth-optimizers` with an in-process Tinker executor. No
|
|
37
|
+
`optimizers-beta` process, URL, or service token is required.
|
|
59
38
|
|
|
60
39
|
```bash
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
# In this checkout:
|
|
66
|
-
export SYNTH_OPTIMIZERS_BETA_URL=http://127.0.0.1:8879
|
|
67
|
-
export OPTIMIZERS_BETA_SERVICE_TOKEN=local-dev-token # held only by the façade
|
|
68
|
-
export SYNTH_OPTIMIZERS_SFT_SERVICE_TOKEN=local-qa-token # Workshop / CLI callers
|
|
40
|
+
export TINKER_API_KEY=...
|
|
41
|
+
export SYNTH_OPTIMIZERS_SFT_SERVICE_TOKEN=local-qa-token
|
|
42
|
+
# Fixture-only local QA without paid Tinker work:
|
|
43
|
+
export SYNTH_OPTIMIZERS_SFT_FIXTURE=1
|
|
69
44
|
synth-optimizers sft service --db .sft/service.sqlite --bind 127.0.0.1:8878
|
|
70
45
|
```
|
|
71
46
|
|
|
@@ -98,13 +73,18 @@ pip install synth-optimizers
|
|
|
98
73
|
uv add synth-optimizers
|
|
99
74
|
```
|
|
100
75
|
|
|
76
|
+
This source targets `synth-optimizers==0.2.22` with `synth-containers==0.4.2`.
|
|
77
|
+
For an unpublished candidate, build from a checkout as shown below; published
|
|
78
|
+
versions are listed on PyPI.
|
|
79
|
+
|
|
101
80
|
Install [`uv`](https://github.com/astral-sh/uv) for local development and editable installs.
|
|
102
81
|
|
|
103
82
|
## Local development
|
|
104
83
|
|
|
105
|
-
|
|
84
|
+
Clone the repo and install the local Python/Rust extension in editable mode:
|
|
106
85
|
|
|
107
86
|
```bash
|
|
87
|
+
git clone https://github.com/synth-laboratories/optimizers.git
|
|
108
88
|
cd optimizers
|
|
109
89
|
uv sync --group dev
|
|
110
90
|
uv pip install -e .
|
|
@@ -127,39 +107,31 @@ target_modules = ["stage2_system"]
|
|
|
127
107
|
[seed_candidate]
|
|
128
108
|
stage2_system = "Classify the query into exactly one Banking77 intent. Return only the label."
|
|
129
109
|
|
|
130
|
-
[
|
|
131
|
-
|
|
132
|
-
|
|
110
|
+
[taskset]
|
|
111
|
+
train_ids = ["train:0", "train:1", "train:2", "train:3"]
|
|
112
|
+
heldout_ids = ["test:100", "test:101"]
|
|
113
|
+
|
|
114
|
+
[gepa.task_pools]
|
|
115
|
+
pareto = ["train:0", "train:1", "train:2", "train:3"]
|
|
116
|
+
minibatch = ["train:0", "train:1"]
|
|
117
|
+
reflection = ["train:0", "train:1", "train:2", "train:3"]
|
|
118
|
+
heldout = ["test:100", "test:101"]
|
|
133
119
|
```
|
|
134
120
|
|
|
135
121
|
```python
|
|
136
|
-
from
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
with container.serve() as handle:
|
|
142
|
-
result = OptimizerRun(
|
|
143
|
-
GepaConfig(
|
|
144
|
-
container=handle.connection(),
|
|
145
|
-
taskset=TasksetSelection(train_ids=["train:0", "train:1"], heldout_ids=["test:100"]),
|
|
146
|
-
task_pools=GepaTaskPools(
|
|
147
|
-
pareto=["train:0"],
|
|
148
|
-
minibatch=["train:0"],
|
|
149
|
-
reflection=["train:0", "train:1"],
|
|
150
|
-
heldout=["test:100"],
|
|
151
|
-
),
|
|
152
|
-
program=None,
|
|
153
|
-
objectives=None,
|
|
154
|
-
policy=None,
|
|
155
|
-
)
|
|
156
|
-
).execute()
|
|
122
|
+
from synth_optimizers import GepaRun
|
|
123
|
+
|
|
124
|
+
# Use a complete cookbook config with its task service, policy, and proposer.
|
|
125
|
+
# Configure authorized provider credentials before executing a paid run.
|
|
126
|
+
result = GepaRun.from_toml("gepa.toml").execute()
|
|
157
127
|
|
|
158
128
|
print(result.best_candidate)
|
|
159
129
|
print("cost: unknown" if result.cost_usd is None else f"cost: ${result.cost_usd:.2f}")
|
|
160
130
|
```
|
|
161
131
|
|
|
162
|
-
|
|
132
|
+
The TOML above illustrates task selection, not a standalone task server. Run it
|
|
133
|
+
from the GEPA cookbook directory and add the recipe's policy/proposer settings.
|
|
134
|
+
The legacy `[dataset]` seed selection is not the current GEPA schema.
|
|
163
135
|
|
|
164
136
|
CLI:
|
|
165
137
|
|
|
@@ -169,8 +141,23 @@ synth-optimizers gepa service --db service.sqlite
|
|
|
169
141
|
synth-optimizers events compare --left a.jsonl --right b.jsonl
|
|
170
142
|
```
|
|
171
143
|
|
|
172
|
-
Runnable task examples
|
|
173
|
-
|
|
144
|
+
Runnable task examples are **not in this repository**. They live in the separate
|
|
145
|
+
public repo
|
|
146
|
+
[`synth-laboratories/synth-cookbooks-public`](https://github.com/synth-laboratories/synth-cookbooks-public/tree/main/cookbooks/optimizers/gepa)
|
|
147
|
+
— Banking77, HotpotQA, MiniGrid, and Crafter. TBLite is optional evaluation
|
|
148
|
+
infrastructure. HealthBench is parked because Containers 0.4.2 does not include
|
|
149
|
+
its runtime. Config-relative paths resolve against the config file's directory.
|
|
150
|
+
Follow the selected cookbook's setup instructions before launching:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
git clone https://github.com/synth-laboratories/synth-cookbooks-public.git
|
|
154
|
+
cd synth-cookbooks-public/cookbooks/optimizers/gepa/banking77_container
|
|
155
|
+
synth-optimizers gepa run --config gepa.toml
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The cookbook configs published there still declare the legacy `[dataset]` seed
|
|
159
|
+
selection, which `0.2.22` ignores; add `[taskset]` and `[gepa.task_pools]`
|
|
160
|
+
blocks like the ones in the quickstart above before one of them will load.
|
|
174
161
|
|
|
175
162
|
<details>
|
|
176
163
|
<summary><strong>Authentication and models</strong></summary>
|
|
@@ -235,4 +222,3 @@ Agent docs: [skills/gepa/SKILL.md](skills/gepa/SKILL.md).
|
|
|
235
222
|
## License
|
|
236
223
|
|
|
237
224
|
Apache-2.0
|
|
238
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "synth-optimizers"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.22"
|
|
4
4
|
description = "Public Synth optimizer tooling with a Rust GEPA core."
|
|
5
5
|
authors = [{name = "Synth Laboratories", email = "josh@usesynth.ai"}]
|
|
6
6
|
readme = "README.md"
|
|
@@ -8,17 +8,26 @@ requires-python = ">=3.11"
|
|
|
8
8
|
license = "Apache-2.0"
|
|
9
9
|
dependencies = [
|
|
10
10
|
"pydantic>=2.0.0",
|
|
11
|
-
"synth-containers==0.4.
|
|
11
|
+
"synth-containers==0.4.3",
|
|
12
12
|
"websocket-client>=1.8.0",
|
|
13
13
|
]
|
|
14
14
|
|
|
15
15
|
[project.optional-dependencies]
|
|
16
|
+
eval-target-build = ["pyarrow>=17", "huggingface-hub>=0.24"]
|
|
17
|
+
daytona = ["daytona==0.210.0"]
|
|
18
|
+
benchmark-server = ["fastapi>=0.115", "uvicorn>=0.30", "httpx>=0.27"]
|
|
16
19
|
banking77 = [
|
|
17
20
|
"datasets>=2.19.0",
|
|
18
21
|
"openai>=1.0.0",
|
|
19
22
|
]
|
|
23
|
+
tinker = [
|
|
24
|
+
"tinker",
|
|
25
|
+
"renderers>=0.1.9",
|
|
26
|
+
]
|
|
20
27
|
dev = [
|
|
21
28
|
"maturin>=1.7.0",
|
|
29
|
+
"numpy>=2.0",
|
|
30
|
+
"pytest>=8.0.0",
|
|
22
31
|
"ruff>=0.6.0",
|
|
23
32
|
"ty>=0.0.32",
|
|
24
33
|
]
|
|
@@ -26,12 +35,15 @@ dev = [
|
|
|
26
35
|
[dependency-groups]
|
|
27
36
|
dev = [
|
|
28
37
|
"maturin>=1.7.0",
|
|
38
|
+
"numpy>=2.0",
|
|
39
|
+
"pytest>=8.0.0",
|
|
29
40
|
"ruff>=0.6.0",
|
|
30
41
|
"ty>=0.0.32",
|
|
31
42
|
]
|
|
32
43
|
|
|
33
44
|
[project.scripts]
|
|
34
45
|
synth-optimizers = "synth_optimizers.cli:main"
|
|
46
|
+
synth-optimizers-cispo = "synth_optimizers.cispo_cli:main"
|
|
35
47
|
|
|
36
48
|
[project.urls]
|
|
37
49
|
Homepage = "https://github.com/synth-laboratories/optimizers"
|
|
@@ -54,7 +66,8 @@ include = ["src/synth_optimizers/docs/**/*", "src/synth_optimizers/eval/catalog/
|
|
|
54
66
|
package = true
|
|
55
67
|
|
|
56
68
|
[tool.uv.sources]
|
|
57
|
-
|
|
69
|
+
# Coordinated-release candidate; no sibling checkout is required by uv users.
|
|
70
|
+
synth-containers = { path = "vendor/synth-containers/synth_containers-0.4.3-py3-none-any.whl" }
|
|
58
71
|
|
|
59
72
|
[tool.ruff]
|
|
60
73
|
line-length = 100
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
use super::*;
|
|
2
|
+
|
|
3
|
+
#[test]
|
|
4
|
+
fn chatgpt_proposer_emits_explicit_zero_incremental_api_cost() {
|
|
5
|
+
let mut config = SynthOptimizerConfig::default();
|
|
6
|
+
config.proposer.auth_mode = "chatgpt".to_string();
|
|
7
|
+
let usage = normalize_proposer_usage(
|
|
8
|
+
&config,
|
|
9
|
+
"gpt-5.6-luna",
|
|
10
|
+
json!({"prompt_tokens": 100, "completion_tokens": 20, "total_tokens": 120}),
|
|
11
|
+
);
|
|
12
|
+
assert_eq!(usage.get("cost_usd"), Some(&json!(0.0)));
|
|
13
|
+
assert_eq!(
|
|
14
|
+
usage.get("cost_source"),
|
|
15
|
+
Some(&json!("chatgpt_subscription_no_incremental_api_charge"))
|
|
16
|
+
);
|
|
17
|
+
assert_eq!(usage.get("provider"), Some(&json!("chatgpt_subscription")));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
#[test]
|
|
21
|
+
fn chatgpt_proposer_preserves_an_explicit_cost_receipt() {
|
|
22
|
+
let mut config = SynthOptimizerConfig::default();
|
|
23
|
+
config.proposer.auth_mode = "chatgpt".to_string();
|
|
24
|
+
let usage = normalize_proposer_usage(
|
|
25
|
+
&config,
|
|
26
|
+
"gpt-5.6-luna",
|
|
27
|
+
json!({"cost_usd": 0.25, "cost_source": "provider"}),
|
|
28
|
+
);
|
|
29
|
+
assert_eq!(usage.get("cost_usd"), Some(&json!(0.25)));
|
|
30
|
+
assert_eq!(usage.get("cost_source"), Some(&json!("provider")));
|
|
31
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
use serde_json::{json, Map, Value};
|
|
2
|
+
|
|
3
|
+
pub(super) fn normalize(
|
|
4
|
+
model: &str,
|
|
5
|
+
mut usage: Map<String, Value>,
|
|
6
|
+
reported_cost: Option<f64>,
|
|
7
|
+
) -> Value {
|
|
8
|
+
usage.insert("provider".into(), Value::String("openrouter".into()));
|
|
9
|
+
usage.insert("model".into(), Value::String(model.into()));
|
|
10
|
+
if reported_cost.is_none() {
|
|
11
|
+
let cost = usage
|
|
12
|
+
.get("cost")
|
|
13
|
+
.and_then(Value::as_f64)
|
|
14
|
+
.filter(|value| value.is_finite() && *value >= 0.0);
|
|
15
|
+
if let Some(cost) = cost {
|
|
16
|
+
usage.insert("cost_usd".into(), json!(cost));
|
|
17
|
+
usage.insert(
|
|
18
|
+
"cost_source".into(),
|
|
19
|
+
Value::String("openrouter_provider_billed".into()),
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
Value::Object(usage)
|
|
24
|
+
}
|
{synth_optimizers-0.2.16 → synth_optimizers-0.2.22}/rust/crates/synth_gepa/src/codex_app_server.rs
RENAMED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
use std::
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
use std::{
|
|
2
|
+
collections::{BTreeMap, BTreeSet},
|
|
3
|
+
env, fs,
|
|
4
|
+
path::{Path, PathBuf},
|
|
5
|
+
sync::{Mutex, OnceLock},
|
|
6
|
+
time::Duration,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
mod openrouter_usage;
|
|
7
10
|
|
|
8
11
|
use crate::{CandidateRecord, RolloutScore};
|
|
9
12
|
use reqwest::blocking::Client;
|
|
@@ -168,9 +171,10 @@ pub(crate) fn run_deepseek_chat_proposer(input: CodexProposerInput<'_>) -> Resul
|
|
|
168
171
|
"gpt-4.1-mini",
|
|
169
172
|
false,
|
|
170
173
|
),
|
|
174
|
+
"openrouter" => ("https://openrouter.ai/api/v1", "OPENROUTER_API_KEY", "openai/gpt-5.6-luna", false),
|
|
171
175
|
other => {
|
|
172
176
|
return Err(OptimizerError::Config(format!(
|
|
173
|
-
"chat-completions proposer backend requires proposer.provider = \"deepseek\", \"nvidia\", or \"
|
|
177
|
+
"chat-completions proposer backend requires proposer.provider = \"deepseek\", \"nvidia\", \"openai\", or \"openrouter\"; got {other:?}"
|
|
174
178
|
)))
|
|
175
179
|
}
|
|
176
180
|
};
|
|
@@ -579,6 +583,9 @@ fn normalize_proposer_usage(config: &SynthOptimizerConfig, model: &str, usage: V
|
|
|
579
583
|
if provider.eq_ignore_ascii_case("openrouter") && model_lower == OPENROUTER_GROK43_MODEL {
|
|
580
584
|
return normalize_openrouter_grok43_usage(model, usage_map);
|
|
581
585
|
}
|
|
586
|
+
if provider.eq_ignore_ascii_case("openrouter") {
|
|
587
|
+
return openrouter_usage::normalize(model, usage_map, reported_cost);
|
|
588
|
+
}
|
|
582
589
|
if provider.eq_ignore_ascii_case("deepseek") || model_lower.contains("deepseek") {
|
|
583
590
|
usage_map.insert(
|
|
584
591
|
"provider".to_string(),
|
|
@@ -3399,36 +3406,4 @@ fn non_empty(value: Option<&str>) -> Option<&str> {
|
|
|
3399
3406
|
}
|
|
3400
3407
|
|
|
3401
3408
|
#[cfg(test)]
|
|
3402
|
-
mod cost_tests
|
|
3403
|
-
use super::*;
|
|
3404
|
-
|
|
3405
|
-
#[test]
|
|
3406
|
-
fn chatgpt_proposer_emits_explicit_zero_incremental_api_cost() {
|
|
3407
|
-
let mut config = SynthOptimizerConfig::default();
|
|
3408
|
-
config.proposer.auth_mode = "chatgpt".to_string();
|
|
3409
|
-
let usage = normalize_proposer_usage(
|
|
3410
|
-
&config,
|
|
3411
|
-
"gpt-5.6-luna",
|
|
3412
|
-
json!({"prompt_tokens": 100, "completion_tokens": 20, "total_tokens": 120}),
|
|
3413
|
-
);
|
|
3414
|
-
assert_eq!(usage.get("cost_usd"), Some(&json!(0.0)));
|
|
3415
|
-
assert_eq!(
|
|
3416
|
-
usage.get("cost_source"),
|
|
3417
|
-
Some(&json!("chatgpt_subscription_no_incremental_api_charge"))
|
|
3418
|
-
);
|
|
3419
|
-
assert_eq!(usage.get("provider"), Some(&json!("chatgpt_subscription")));
|
|
3420
|
-
}
|
|
3421
|
-
|
|
3422
|
-
#[test]
|
|
3423
|
-
fn chatgpt_proposer_preserves_an_explicit_cost_receipt() {
|
|
3424
|
-
let mut config = SynthOptimizerConfig::default();
|
|
3425
|
-
config.proposer.auth_mode = "chatgpt".to_string();
|
|
3426
|
-
let usage = normalize_proposer_usage(
|
|
3427
|
-
&config,
|
|
3428
|
-
"gpt-5.6-luna",
|
|
3429
|
-
json!({"cost_usd": 0.25, "cost_source": "provider"}),
|
|
3430
|
-
);
|
|
3431
|
-
assert_eq!(usage.get("cost_usd"), Some(&json!(0.25)));
|
|
3432
|
-
assert_eq!(usage.get("cost_source"), Some(&json!("provider")));
|
|
3433
|
-
}
|
|
3434
|
-
}
|
|
3409
|
+
mod cost_tests;
|