synth-optimizers 0.2.12.dev20260816__tar.gz → 0.2.13__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.12.dev20260816 → synth_optimizers-0.2.13}/PKG-INFO +31 -1
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/README.md +30 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/pyproject.toml +2 -2
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/workspace.rs +55 -9
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/__init__.py +20 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/cli.py +156 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/__init__.py +118 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/__main__.py +10 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/catalog/eval.craftax.code-policy.smoke.v1.toml +55 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/catalog/eval.craftax.llm-policy.smoke.v1.toml +71 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/catalog/eval.fixture.policy-smoke.v1.toml +53 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/catalog/eval.gamebench.craftax-code-policy.confirm.v1.toml +62 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/catalog/eval.gamebench.llm-policy.confirm.v1.toml +71 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/commands.py +205 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/executor.py +285 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/home.py +205 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/models.py +873 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/recipes.py +196 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/runner.py +895 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/scoring.py +283 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/semaphore.py +177 -0
- synth_optimizers-0.2.13/src/synth_optimizers/eval/staging.py +114 -0
- synth_optimizers-0.2.13/src/synth_optimizers/sft.py +649 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/Cargo.lock +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/Cargo.toml +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_gepa/Cargo.toml +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_gepa/README.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_gepa/openapi/gepa-service-v1.yaml +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_gepa/src/codex_app_server.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_gepa/src/jesterky_workflow.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_gepa/src/lib.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_gepa/src/machines.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_gepa/src/pipeline.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_gepa/src/planner.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_gepa/src/prompting_best_practices.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_gepa/src/runtime.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_gepa/src/service.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/Cargo.toml +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/README.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/README.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/app_server.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/codex_home.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/daytona.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/docker.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/jsonrpc_read_window.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/limits.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/local.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/mod.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/nano.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/role_agent.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/session.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/substrate.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/supervisor.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/agent_runtime/usage.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/artifact_store.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/artifacts.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/cache.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/candidates.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/checkpoints.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/config.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/configured_limits.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/container_contract.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/data_models.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/disk_budget.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/error.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/event_visualization.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/events.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/evidence.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/failures.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/fsm.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/http.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/invariants.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/jesterky.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/jobs.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/levers.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/lib.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/limit_engine.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/limits.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/observability.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/operations.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/process.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/projections.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/prompt_program.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/registry.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/resources.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/rollouts.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/runtime_records.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/scores.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/sensors.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/state_machine.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/stopper.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/storage_maintenance.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizer_platform/src/usage.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizers_py/Cargo.toml +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizers_py/README.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/rust/crates/synth_optimizers_py/src/lib.rs +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/README.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/_synth_optimizers.pyi +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/board_server.py +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/discovery.py +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gelo/00-index.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gelo/10-cli.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gelo/20-sdk.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gelo/30-hosted.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gelo/containers/00-overview.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gelo/containers/20-contract.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gepa/00-index.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gepa/10-cli.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gepa/20-sdk.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gepa/algorithms/00-overview.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gepa/algorithms/10-pipeline-modes.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gepa/algorithms/20-proposer-and-policies.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gepa/assets/synth-logo.png +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gepa/containers/00-overview.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gepa/containers/10-catalog.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs/gepa/containers/20-contract.md +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/docs_server.py +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/eval_stats.py +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/future_algorithms.py +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/gelo.py +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/gepa.py +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/hosted.py +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/hosted_config.py +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/o11y.py +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/observability.py +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/py.typed +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/sdk.py +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/tunnels.py +0 -0
- {synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/victorialogs.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: synth-optimizers
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.13
|
|
4
4
|
Requires-Dist: pydantic>=2.0.0
|
|
5
5
|
Requires-Dist: synth-containers==0.4.1.dev20260814
|
|
6
6
|
Requires-Dist: websocket-client>=1.8.0
|
|
@@ -51,6 +51,36 @@ local algorithm; GELO and SFT are hosted-only in the public package and run on
|
|
|
51
51
|
Synth hosted optimizer infrastructure. Hosted GEPA, GELO, and SFT submission is
|
|
52
52
|
covered in [`docs/hosted-optimizers.md`](docs/hosted-optimizers.md).
|
|
53
53
|
|
|
54
|
+
### Hosted SFT control plane
|
|
55
|
+
|
|
56
|
+
SFT is served by `synth-optimizers`; Optimizers-beta is an internal training executor,
|
|
57
|
+
not a Workshop-facing API. For local QA, start beta with its executor token and then
|
|
58
|
+
start the public façade:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# In the Optimizers-beta checkout:
|
|
62
|
+
OPTIMIZERS_BETA_SERVICE_TOKEN=local-dev-token \
|
|
63
|
+
cargo run --bin optimizers-beta -- serve --bind 127.0.0.1:8879
|
|
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
|
|
69
|
+
synth-optimizers sft service --db .sft/service.sqlite --bind 127.0.0.1:8878
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Submit, inspect, and cancel only through the façade:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
synth-optimizers sft validate --config sft.toml
|
|
76
|
+
synth-optimizers sft submit --config sft.toml --follow
|
|
77
|
+
synth-optimizers sft watch RUN_ID --events
|
|
78
|
+
synth-optimizers sft cancel RUN_ID
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The façade keeps executor-only workspace paths and service credentials private. Its
|
|
82
|
+
artifact proxy is available at `/v1/runs/RUN_ID/artifacts/{manifest,events}`.
|
|
83
|
+
|
|
54
84
|
## Future hosted-algorithm compatibility
|
|
55
85
|
|
|
56
86
|
MAPO, OHCO, Online Reflexion, and MARL prompt-optimization identifiers are retained
|
|
@@ -29,6 +29,36 @@ local algorithm; GELO and SFT are hosted-only in the public package and run on
|
|
|
29
29
|
Synth hosted optimizer infrastructure. Hosted GEPA, GELO, and SFT submission is
|
|
30
30
|
covered in [`docs/hosted-optimizers.md`](docs/hosted-optimizers.md).
|
|
31
31
|
|
|
32
|
+
### Hosted SFT control plane
|
|
33
|
+
|
|
34
|
+
SFT is served by `synth-optimizers`; Optimizers-beta is an internal training executor,
|
|
35
|
+
not a Workshop-facing API. For local QA, start beta with its executor token and then
|
|
36
|
+
start the public façade:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# In the Optimizers-beta checkout:
|
|
40
|
+
OPTIMIZERS_BETA_SERVICE_TOKEN=local-dev-token \
|
|
41
|
+
cargo run --bin optimizers-beta -- serve --bind 127.0.0.1:8879
|
|
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
|
|
47
|
+
synth-optimizers sft service --db .sft/service.sqlite --bind 127.0.0.1:8878
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Submit, inspect, and cancel only through the façade:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
synth-optimizers sft validate --config sft.toml
|
|
54
|
+
synth-optimizers sft submit --config sft.toml --follow
|
|
55
|
+
synth-optimizers sft watch RUN_ID --events
|
|
56
|
+
synth-optimizers sft cancel RUN_ID
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The façade keeps executor-only workspace paths and service credentials private. Its
|
|
60
|
+
artifact proxy is available at `/v1/runs/RUN_ID/artifacts/{manifest,events}`.
|
|
61
|
+
|
|
32
62
|
## Future hosted-algorithm compatibility
|
|
33
63
|
|
|
34
64
|
MAPO, OHCO, Online Reflexion, and MARL prompt-optimization identifiers are retained
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "synth-optimizers"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.13"
|
|
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"
|
|
@@ -48,7 +48,7 @@ module-name = "synth_optimizers._synth_optimizers"
|
|
|
48
48
|
python-source = "src"
|
|
49
49
|
# Ship the bundled console docs (markdown + logo) as package data so a
|
|
50
50
|
# pip-installed `gepa console` can serve them without a repo checkout.
|
|
51
|
-
include = ["src/synth_optimizers/docs/**/*"]
|
|
51
|
+
include = ["src/synth_optimizers/docs/**/*", "src/synth_optimizers/eval/catalog/*.toml"]
|
|
52
52
|
|
|
53
53
|
[tool.uv]
|
|
54
54
|
package = true
|
|
@@ -4819,15 +4819,7 @@ impl WorkspaceStore {
|
|
|
4819
4819
|
let mut stmt = self.conn.prepare(
|
|
4820
4820
|
r#"
|
|
4821
4821
|
SELECT run_id, frame_json
|
|
4822
|
-
FROM sensor_frames
|
|
4823
|
-
WHERE NOT EXISTS (
|
|
4824
|
-
SELECT 1
|
|
4825
|
-
FROM candidate_seed_rewards csr
|
|
4826
|
-
WHERE csr.run_id = sf.run_id
|
|
4827
|
-
AND csr.candidate_id = sf.candidate_id
|
|
4828
|
-
AND csr.evaluation_stage = sf.evaluation_stage
|
|
4829
|
-
AND csr.seed_id = sf.task_id
|
|
4830
|
-
)
|
|
4822
|
+
FROM sensor_frames
|
|
4831
4823
|
"#,
|
|
4832
4824
|
)?;
|
|
4833
4825
|
let mut rows = stmt.query([])?;
|
|
@@ -4860,6 +4852,10 @@ impl WorkspaceStore {
|
|
|
4860
4852
|
}
|
|
4861
4853
|
|
|
4862
4854
|
fn ensure_runtime_schema(&self) -> Result<()> {
|
|
4855
|
+
// v0.2.0 workspaces called this identity `seed`. The v0.2.12
|
|
4856
|
+
// backfill used `task_id` before migrating the column, which made the
|
|
4857
|
+
// sidecar fail during startup even when the legacy table was empty.
|
|
4858
|
+
self.ensure_column("sensor_frames", "task_id", "TEXT NOT NULL DEFAULT ''")?;
|
|
4863
4859
|
self.ensure_column(
|
|
4864
4860
|
"budget_commits",
|
|
4865
4861
|
"wall_seconds",
|
|
@@ -9351,4 +9347,54 @@ mod nullable_cost_migration_tests {
|
|
|
9351
9347
|
let _ = fs::remove_file(path.with_extension("sqlite-wal"));
|
|
9352
9348
|
let _ = fs::remove_file(path.with_extension("sqlite-shm"));
|
|
9353
9349
|
}
|
|
9350
|
+
|
|
9351
|
+
#[test]
|
|
9352
|
+
fn opening_legacy_workspace_adds_sensor_frame_task_identity_before_backfill() {
|
|
9353
|
+
let path = std::env::temp_dir().join(format!(
|
|
9354
|
+
"synth-sensor-frame-migration-{}-{}.sqlite",
|
|
9355
|
+
std::process::id(),
|
|
9356
|
+
OffsetDateTime::now_utc().unix_timestamp_nanos()
|
|
9357
|
+
));
|
|
9358
|
+
let conn = Connection::open(&path).unwrap();
|
|
9359
|
+
conn.execute_batch(
|
|
9360
|
+
r#"
|
|
9361
|
+
CREATE TABLE sensor_frames (
|
|
9362
|
+
run_id TEXT NOT NULL,
|
|
9363
|
+
sensor_frame_id TEXT NOT NULL,
|
|
9364
|
+
candidate_id TEXT NOT NULL,
|
|
9365
|
+
rollout_id TEXT,
|
|
9366
|
+
example_id TEXT NOT NULL,
|
|
9367
|
+
seed INTEGER NOT NULL,
|
|
9368
|
+
split TEXT NOT NULL,
|
|
9369
|
+
evaluation_stage TEXT NOT NULL,
|
|
9370
|
+
reward REAL NOT NULL,
|
|
9371
|
+
status TEXT NOT NULL,
|
|
9372
|
+
trace_digest_json TEXT,
|
|
9373
|
+
usage_json TEXT NOT NULL,
|
|
9374
|
+
failure_json TEXT,
|
|
9375
|
+
frame_json TEXT NOT NULL,
|
|
9376
|
+
updated_at TEXT NOT NULL,
|
|
9377
|
+
PRIMARY KEY(run_id, sensor_frame_id)
|
|
9378
|
+
);
|
|
9379
|
+
"#,
|
|
9380
|
+
)
|
|
9381
|
+
.unwrap();
|
|
9382
|
+
drop(conn);
|
|
9383
|
+
|
|
9384
|
+
let store = WorkspaceStore::open_existing(&path).unwrap();
|
|
9385
|
+
let mut columns = store
|
|
9386
|
+
.conn
|
|
9387
|
+
.prepare("PRAGMA table_info(sensor_frames)")
|
|
9388
|
+
.unwrap();
|
|
9389
|
+
let task_id = columns
|
|
9390
|
+
.query_map([], |row| row.get::<_, String>(1))
|
|
9391
|
+
.unwrap()
|
|
9392
|
+
.any(|name| name.unwrap() == "task_id");
|
|
9393
|
+
assert!(task_id);
|
|
9394
|
+
drop(columns);
|
|
9395
|
+
drop(store);
|
|
9396
|
+
let _ = fs::remove_file(&path);
|
|
9397
|
+
let _ = fs::remove_file(path.with_extension("sqlite-wal"));
|
|
9398
|
+
let _ = fs::remove_file(path.with_extension("sqlite-shm"));
|
|
9399
|
+
}
|
|
9354
9400
|
}
|
{synth_optimizers-0.2.12.dev20260816 → synth_optimizers-0.2.13}/src/synth_optimizers/__init__.py
RENAMED
|
@@ -84,6 +84,17 @@ from .hosted import (
|
|
|
84
84
|
validate_online_reflexion_evidence_notes,
|
|
85
85
|
)
|
|
86
86
|
from .hosted_config import HostedOptimizerConfig
|
|
87
|
+
from .sft import (
|
|
88
|
+
SFT_ALGORITHM_ID,
|
|
89
|
+
BetaSftExecutorClient,
|
|
90
|
+
SftArtifact,
|
|
91
|
+
SftConfig,
|
|
92
|
+
SftPublicServiceClient,
|
|
93
|
+
SftService,
|
|
94
|
+
SftServiceError,
|
|
95
|
+
create_sft_http_server,
|
|
96
|
+
serve_sft_service,
|
|
97
|
+
)
|
|
87
98
|
from .future_algorithms import (
|
|
88
99
|
FUTURE_HOSTED_ALGORITHMS,
|
|
89
100
|
FutureHostedAlgorithm,
|
|
@@ -226,6 +237,15 @@ __all__ = [
|
|
|
226
237
|
"HostedOptimizerClient",
|
|
227
238
|
"HostedOptimizerError",
|
|
228
239
|
"HostedOptimizerConfig",
|
|
240
|
+
"SFT_ALGORITHM_ID",
|
|
241
|
+
"BetaSftExecutorClient",
|
|
242
|
+
"SftArtifact",
|
|
243
|
+
"SftConfig",
|
|
244
|
+
"SftPublicServiceClient",
|
|
245
|
+
"SftService",
|
|
246
|
+
"SftServiceError",
|
|
247
|
+
"create_sft_http_server",
|
|
248
|
+
"serve_sft_service",
|
|
229
249
|
"FUTURE_HOSTED_ALGORITHMS",
|
|
230
250
|
"FutureHostedAlgorithm",
|
|
231
251
|
"FutureHostedAlgorithmSlug",
|
|
@@ -34,6 +34,7 @@ from .hosted import (
|
|
|
34
34
|
HostedOptimizerError,
|
|
35
35
|
validate_online_reflexion_evidence_notes,
|
|
36
36
|
)
|
|
37
|
+
from .sft import SftConfig, SftPublicServiceClient, SftServiceError, serve_sft_service
|
|
37
38
|
from .tunnels import TunnelError, TunnelProvider
|
|
38
39
|
from .victorialogs import project_gepa_run_artifacts, project_gepa_run_started
|
|
39
40
|
|
|
@@ -751,6 +752,97 @@ def _config_file_object(path: str) -> dict:
|
|
|
751
752
|
return data
|
|
752
753
|
|
|
753
754
|
|
|
755
|
+
def _sft_service_client(args: argparse.Namespace) -> SftPublicServiceClient:
|
|
756
|
+
token = os.environ.get(args.service_token_env) if args.service_token_env else None
|
|
757
|
+
return SftPublicServiceClient(args.service_url, token, timeout_seconds=args.timeout_seconds)
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
def _sft_validate(args: argparse.Namespace) -> int:
|
|
761
|
+
try:
|
|
762
|
+
config = SftConfig.from_toml(
|
|
763
|
+
Path(args.config).read_text(encoding="utf-8"), run_id=args.run_id
|
|
764
|
+
)
|
|
765
|
+
except OSError as exc:
|
|
766
|
+
raise SystemExit(f"cannot read {args.config}: {exc}") from exc
|
|
767
|
+
except SftServiceError as exc:
|
|
768
|
+
raise SystemExit(str(exc)) from exc
|
|
769
|
+
payload = {
|
|
770
|
+
"algorithm": "sft",
|
|
771
|
+
"run_id": config.run_id,
|
|
772
|
+
"backend": config.backend,
|
|
773
|
+
"base_model": config.base_model,
|
|
774
|
+
"checkpoint_steps": list(config.checkpoint_steps),
|
|
775
|
+
"accelerator_slots": config.accelerator_slots,
|
|
776
|
+
}
|
|
777
|
+
print(
|
|
778
|
+
json.dumps(payload, indent=2, sort_keys=True)
|
|
779
|
+
if args.json
|
|
780
|
+
else f"valid SFT config run_id={config.run_id} backend={config.backend}"
|
|
781
|
+
)
|
|
782
|
+
return 0
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
def _sft_submit(args: argparse.Namespace) -> int:
|
|
786
|
+
try:
|
|
787
|
+
config_toml = Path(args.config).read_text(encoding="utf-8")
|
|
788
|
+
client = _sft_service_client(args)
|
|
789
|
+
submitted = client.submit_toml(
|
|
790
|
+
config_toml,
|
|
791
|
+
run_id=args.run_id,
|
|
792
|
+
idempotency_key=args.idempotency_key,
|
|
793
|
+
)
|
|
794
|
+
if args.json and not args.follow:
|
|
795
|
+
print(json.dumps(submitted, indent=2, sort_keys=True))
|
|
796
|
+
return 0
|
|
797
|
+
run_id = str(submitted["run_id"])
|
|
798
|
+
print(f"submitted run_id={run_id} status={submitted.get('status', 'queued')}")
|
|
799
|
+
if not args.follow:
|
|
800
|
+
return 0
|
|
801
|
+
while True:
|
|
802
|
+
record = client.get(run_id)
|
|
803
|
+
status = str(record.get("status", "unknown"))
|
|
804
|
+
print(f"status={status}")
|
|
805
|
+
if status in {"succeeded", "failed", "cancelled"}:
|
|
806
|
+
if args.json:
|
|
807
|
+
print(json.dumps(record, indent=2, sort_keys=True))
|
|
808
|
+
return 1 if status == "failed" else 0
|
|
809
|
+
time.sleep(args.poll_seconds)
|
|
810
|
+
except (OSError, SftServiceError) as exc:
|
|
811
|
+
raise SystemExit(str(exc)) from exc
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
def _sft_watch(args: argparse.Namespace) -> int:
|
|
815
|
+
try:
|
|
816
|
+
client = _sft_service_client(args)
|
|
817
|
+
record = client.get(args.run_id)
|
|
818
|
+
if args.events:
|
|
819
|
+
page = client.optimizer_events(
|
|
820
|
+
args.run_id, after_sequence=args.after_seq, limit=args.limit
|
|
821
|
+
)
|
|
822
|
+
record["events"] = page.get("events", [])
|
|
823
|
+
print(
|
|
824
|
+
json.dumps(record, indent=2, sort_keys=True)
|
|
825
|
+
if args.json
|
|
826
|
+
else f"run_id={args.run_id} status={record.get('status')}"
|
|
827
|
+
)
|
|
828
|
+
return 1 if record.get("status") == "failed" else 0
|
|
829
|
+
except SftServiceError as exc:
|
|
830
|
+
raise SystemExit(str(exc)) from exc
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
def _sft_cancel(args: argparse.Namespace) -> int:
|
|
834
|
+
try:
|
|
835
|
+
record = _sft_service_client(args).cancel(args.run_id)
|
|
836
|
+
except SftServiceError as exc:
|
|
837
|
+
raise SystemExit(str(exc)) from exc
|
|
838
|
+
print(
|
|
839
|
+
json.dumps(record, indent=2, sort_keys=True)
|
|
840
|
+
if args.json
|
|
841
|
+
else f"run_id={args.run_id} status={record.get('status')}"
|
|
842
|
+
)
|
|
843
|
+
return 0
|
|
844
|
+
|
|
845
|
+
|
|
754
846
|
def _submit_hosted_gelo(args: argparse.Namespace) -> int:
|
|
755
847
|
tunnel: Any | None = None
|
|
756
848
|
try:
|
|
@@ -1577,6 +1669,45 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
1577
1669
|
"--docs-set", default="gelo", help="Bundled docs set to serve (default: gelo)."
|
|
1578
1670
|
)
|
|
1579
1671
|
|
|
1672
|
+
sft = subcommands.add_parser("sft", help="Operate the public SFT control-plane service.")
|
|
1673
|
+
sft_subcommands = sft.add_subparsers(dest="sft_command", required=True)
|
|
1674
|
+
sft_validate = sft_subcommands.add_parser("validate")
|
|
1675
|
+
sft_validate.add_argument("--config", required=True)
|
|
1676
|
+
sft_validate.add_argument("--run-id")
|
|
1677
|
+
sft_validate.add_argument("--json", action="store_true")
|
|
1678
|
+
|
|
1679
|
+
sft_service = sft_subcommands.add_parser("service")
|
|
1680
|
+
sft_service.add_argument("--db", default=".sft/service.sqlite")
|
|
1681
|
+
sft_service.add_argument("--bind", default="127.0.0.1:8878")
|
|
1682
|
+
sft_service.add_argument(
|
|
1683
|
+
"--service-token-env",
|
|
1684
|
+
default="SYNTH_OPTIMIZERS_SFT_SERVICE_TOKEN",
|
|
1685
|
+
help="Optional inbound bearer-token environment variable.",
|
|
1686
|
+
)
|
|
1687
|
+
|
|
1688
|
+
for command_name in ("submit", "watch", "cancel"):
|
|
1689
|
+
command = sft_subcommands.add_parser(command_name)
|
|
1690
|
+
command.add_argument(
|
|
1691
|
+
"--service-url",
|
|
1692
|
+
default=os.environ.get("SYNTH_OPTIMIZERS_SFT_SERVICE_URL", "http://127.0.0.1:8878"),
|
|
1693
|
+
)
|
|
1694
|
+
command.add_argument("--service-token-env", default="SYNTH_OPTIMIZERS_SFT_SERVICE_TOKEN")
|
|
1695
|
+
command.add_argument("--timeout-seconds", type=float, default=300.0)
|
|
1696
|
+
command.add_argument("--json", action="store_true")
|
|
1697
|
+
sft_submit = sft_subcommands.choices["submit"]
|
|
1698
|
+
sft_submit.add_argument("--config", required=True)
|
|
1699
|
+
sft_submit.add_argument("--run-id")
|
|
1700
|
+
sft_submit.add_argument("--idempotency-key")
|
|
1701
|
+
sft_submit.add_argument("--follow", action="store_true")
|
|
1702
|
+
sft_submit.add_argument("--poll-seconds", type=float, default=1.0)
|
|
1703
|
+
sft_watch = sft_subcommands.choices["watch"]
|
|
1704
|
+
sft_watch.add_argument("run_id")
|
|
1705
|
+
sft_watch.add_argument("--events", action="store_true")
|
|
1706
|
+
sft_watch.add_argument("--after-seq", type=int, default=0)
|
|
1707
|
+
sft_watch.add_argument("--limit", type=int, default=500)
|
|
1708
|
+
sft_cancel = sft_subcommands.choices["cancel"]
|
|
1709
|
+
sft_cancel.add_argument("run_id")
|
|
1710
|
+
|
|
1580
1711
|
mapo = subcommands.add_parser("mapo")
|
|
1581
1712
|
mapo_subcommands = mapo.add_subparsers(dest="mapo_command", required=True)
|
|
1582
1713
|
mapo_startup = mapo_subcommands.add_parser("startup")
|
|
@@ -2087,6 +2218,10 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
2087
2218
|
gepa_runs_delete.add_argument("--yes", action="store_true", help="Apply the deletion.")
|
|
2088
2219
|
gepa_runs_delete.add_argument("--json", action="store_true")
|
|
2089
2220
|
|
|
2221
|
+
from .eval.commands import register as register_eval
|
|
2222
|
+
|
|
2223
|
+
register_eval(subcommands)
|
|
2224
|
+
|
|
2090
2225
|
events = subcommands.add_parser("events")
|
|
2091
2226
|
events_subcommands = events.add_subparsers(dest="events_command", required=True)
|
|
2092
2227
|
replay = events_subcommands.add_parser("replay")
|
|
@@ -2100,6 +2235,15 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
2100
2235
|
|
|
2101
2236
|
def main(argv: Sequence[str] | None = None) -> int:
|
|
2102
2237
|
args = build_parser().parse_args(argv)
|
|
2238
|
+
if args.command == "eval":
|
|
2239
|
+
from .eval.commands import dispatch as dispatch_eval
|
|
2240
|
+
from .eval.models import EvalContractError
|
|
2241
|
+
|
|
2242
|
+
try:
|
|
2243
|
+
return dispatch_eval(args)
|
|
2244
|
+
except EvalContractError as exc:
|
|
2245
|
+
print(f"error: {exc}", file=sys.stderr)
|
|
2246
|
+
return 1
|
|
2103
2247
|
if args.command == "gepa" and args.gepa_command == "run":
|
|
2104
2248
|
from .gepa import GepaRun, UsageRegistrationConfig
|
|
2105
2249
|
|
|
@@ -2200,6 +2344,18 @@ def main(argv: Sequence[str] | None = None) -> int:
|
|
|
2200
2344
|
docs = DocsSource([docs_root], title=args.title)
|
|
2201
2345
|
serve_console(board, docs, host=args.host, port=args.port)
|
|
2202
2346
|
return 0
|
|
2347
|
+
if args.command == "sft" and args.sft_command == "validate":
|
|
2348
|
+
return _sft_validate(args)
|
|
2349
|
+
if args.command == "sft" and args.sft_command == "submit":
|
|
2350
|
+
return _sft_submit(args)
|
|
2351
|
+
if args.command == "sft" and args.sft_command == "watch":
|
|
2352
|
+
return _sft_watch(args)
|
|
2353
|
+
if args.command == "sft" and args.sft_command == "cancel":
|
|
2354
|
+
return _sft_cancel(args)
|
|
2355
|
+
if args.command == "sft" and args.sft_command == "service":
|
|
2356
|
+
token = os.environ.get(args.service_token_env) if args.service_token_env else None
|
|
2357
|
+
serve_sft_service(args.db, args.bind, service_token=token)
|
|
2358
|
+
return 0
|
|
2203
2359
|
if args.command == "mapo" and args.mapo_command == "startup":
|
|
2204
2360
|
return _gelo_startup(args)
|
|
2205
2361
|
if args.command == "mapo" and args.mapo_command == "submit":
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""`eval`: a local Optimizers algorithm that scores policy candidates.
|
|
2
|
+
|
|
3
|
+
`eval` takes an immutable set of policy candidates and an allowlisted recipe,
|
|
4
|
+
expands them into a fair `candidate × seed × scenario` matrix, runs each trial
|
|
5
|
+
in the recipe's pinned container, and returns a promotable winner only when the
|
|
6
|
+
declared gates pass.
|
|
7
|
+
|
|
8
|
+
It is deliberately local. `eval` is not a hosted algorithm and must never be
|
|
9
|
+
added to `synth_optimizers.hosted.OptimizerAlgorithmSlug` or to
|
|
10
|
+
`future_algorithms.py`: that enum describes hosted API compatibility, which
|
|
11
|
+
this is not.
|
|
12
|
+
|
|
13
|
+
There are no Craftax-, GameBench-, or Harbor-specific execution paths here.
|
|
14
|
+
Those are containers implementing one standard contract, `eval.target.v1`.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from .executor import (
|
|
20
|
+
ContainerRuntimeError,
|
|
21
|
+
OciTrialExecutor,
|
|
22
|
+
TrialExecution,
|
|
23
|
+
TrialExecutor,
|
|
24
|
+
TrialRunRequest,
|
|
25
|
+
)
|
|
26
|
+
from .home import EvalHome, RuntimeConfig
|
|
27
|
+
from .models import (
|
|
28
|
+
BENCHMARK_STATUSES,
|
|
29
|
+
CANDIDATE_SET_SCHEMA,
|
|
30
|
+
CONTAINER_RESULT_SCHEMA,
|
|
31
|
+
CONTAINER_STATUSES,
|
|
32
|
+
EVAL_ALGORITHM_ID,
|
|
33
|
+
EVAL_ALGORITHM_VERSION,
|
|
34
|
+
POLICY_CANDIDATE_SCHEMA,
|
|
35
|
+
RUN_MANIFEST_SCHEMA,
|
|
36
|
+
SEED_LEDGER_SCHEMA,
|
|
37
|
+
SELECTION_STATUSES,
|
|
38
|
+
TARGET_MANIFEST_SCHEMA,
|
|
39
|
+
TRIAL_MANIFEST_SCHEMA,
|
|
40
|
+
TRIAL_RECORD_SCHEMA,
|
|
41
|
+
TRIAL_STATUSES,
|
|
42
|
+
WORKER_EVENT_SCHEMA,
|
|
43
|
+
WORKER_MANIFEST_SCHEMA,
|
|
44
|
+
CandidateScorecard,
|
|
45
|
+
CandidateSet,
|
|
46
|
+
ContainerResult,
|
|
47
|
+
EvalContractError,
|
|
48
|
+
MetricSpec,
|
|
49
|
+
PolicyCandidate,
|
|
50
|
+
SeedLedger,
|
|
51
|
+
SelectionDecision,
|
|
52
|
+
SelectionSpec,
|
|
53
|
+
TargetManifest,
|
|
54
|
+
TrialKey,
|
|
55
|
+
TrialLimits,
|
|
56
|
+
TrialRecord,
|
|
57
|
+
digest_of,
|
|
58
|
+
digest_of_tree,
|
|
59
|
+
)
|
|
60
|
+
from .recipes import EvalRecipe, catalog, get_recipe
|
|
61
|
+
from .runner import EvalRunner, WorkerManifest, request_cancel, run_worker
|
|
62
|
+
from .scoring import apply_elimination, decide, paired_lift, summarize_candidate
|
|
63
|
+
from .semaphore import Lease, SemaphoreTimeout, TrialSemaphore
|
|
64
|
+
|
|
65
|
+
__all__ = [
|
|
66
|
+
"BENCHMARK_STATUSES",
|
|
67
|
+
"CANDIDATE_SET_SCHEMA",
|
|
68
|
+
"CONTAINER_RESULT_SCHEMA",
|
|
69
|
+
"CONTAINER_STATUSES",
|
|
70
|
+
"EVAL_ALGORITHM_ID",
|
|
71
|
+
"EVAL_ALGORITHM_VERSION",
|
|
72
|
+
"POLICY_CANDIDATE_SCHEMA",
|
|
73
|
+
"RUN_MANIFEST_SCHEMA",
|
|
74
|
+
"SEED_LEDGER_SCHEMA",
|
|
75
|
+
"SELECTION_STATUSES",
|
|
76
|
+
"TARGET_MANIFEST_SCHEMA",
|
|
77
|
+
"TRIAL_MANIFEST_SCHEMA",
|
|
78
|
+
"TRIAL_RECORD_SCHEMA",
|
|
79
|
+
"TRIAL_STATUSES",
|
|
80
|
+
"WORKER_EVENT_SCHEMA",
|
|
81
|
+
"WORKER_MANIFEST_SCHEMA",
|
|
82
|
+
"CandidateScorecard",
|
|
83
|
+
"CandidateSet",
|
|
84
|
+
"ContainerResult",
|
|
85
|
+
"ContainerRuntimeError",
|
|
86
|
+
"EvalContractError",
|
|
87
|
+
"EvalHome",
|
|
88
|
+
"EvalRecipe",
|
|
89
|
+
"EvalRunner",
|
|
90
|
+
"Lease",
|
|
91
|
+
"MetricSpec",
|
|
92
|
+
"OciTrialExecutor",
|
|
93
|
+
"PolicyCandidate",
|
|
94
|
+
"RuntimeConfig",
|
|
95
|
+
"SeedLedger",
|
|
96
|
+
"SelectionDecision",
|
|
97
|
+
"SelectionSpec",
|
|
98
|
+
"SemaphoreTimeout",
|
|
99
|
+
"TargetManifest",
|
|
100
|
+
"TrialExecution",
|
|
101
|
+
"TrialExecutor",
|
|
102
|
+
"TrialKey",
|
|
103
|
+
"TrialLimits",
|
|
104
|
+
"TrialRecord",
|
|
105
|
+
"TrialRunRequest",
|
|
106
|
+
"TrialSemaphore",
|
|
107
|
+
"WorkerManifest",
|
|
108
|
+
"apply_elimination",
|
|
109
|
+
"catalog",
|
|
110
|
+
"decide",
|
|
111
|
+
"digest_of",
|
|
112
|
+
"digest_of_tree",
|
|
113
|
+
"get_recipe",
|
|
114
|
+
"paired_lift",
|
|
115
|
+
"request_cancel",
|
|
116
|
+
"run_worker",
|
|
117
|
+
"summarize_candidate",
|
|
118
|
+
]
|
synth_optimizers-0.2.13/src/synth_optimizers/eval/catalog/eval.craftax.code-policy.smoke.v1.toml
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Craftax native code-policy smoke. Report-only: it never promotes, so a green
|
|
2
|
+
# run means "the rig and the three policies produced valid evidence", not "a
|
|
3
|
+
# winner was found".
|
|
4
|
+
#
|
|
5
|
+
# `image_digest` is intentionally absent until craftax-eval-target is published
|
|
6
|
+
# and pinned; the recipe reports `unavailable` rather than pretending to a tag.
|
|
7
|
+
|
|
8
|
+
[recipe]
|
|
9
|
+
id = "eval.craftax.code-policy.smoke.v1"
|
|
10
|
+
title = "Craftax code-policy smoke"
|
|
11
|
+
description = "Score staged Craftax code policies on one pinned world, report only."
|
|
12
|
+
task = "craftax"
|
|
13
|
+
policy_kind = "python-code.craftax-choose-actions.v1"
|
|
14
|
+
image = "craftax-eval-target"
|
|
15
|
+
prerequisites = [
|
|
16
|
+
"Published craftax-eval-target image pinned by digest",
|
|
17
|
+
"OCI runtime available to the Desktop app",
|
|
18
|
+
]
|
|
19
|
+
scenarios = ["craftax-default-48x48"]
|
|
20
|
+
screening_seeds = [101, 102]
|
|
21
|
+
confirmation_seeds = []
|
|
22
|
+
secrets = []
|
|
23
|
+
|
|
24
|
+
[recipe.target]
|
|
25
|
+
schema_version = "eval.target.v1"
|
|
26
|
+
policy_kinds = ["python-code.craftax-choose-actions.v1"]
|
|
27
|
+
trial_mode = "one-policy-one-seed"
|
|
28
|
+
required_gates = ["policy_loaded", "verifier_completed"]
|
|
29
|
+
required_artifacts = ["trace"]
|
|
30
|
+
supports_live_events = true
|
|
31
|
+
network = "none"
|
|
32
|
+
|
|
33
|
+
[[recipe.target.metrics]]
|
|
34
|
+
id = "reward"
|
|
35
|
+
direction = "maximize"
|
|
36
|
+
|
|
37
|
+
[[recipe.target.metrics]]
|
|
38
|
+
id = "achievements"
|
|
39
|
+
direction = "maximize"
|
|
40
|
+
|
|
41
|
+
[recipe.selection]
|
|
42
|
+
primary_metric = "reward"
|
|
43
|
+
min_lift = 0.0
|
|
44
|
+
min_valid_trials = 2
|
|
45
|
+
decision_mode = "report_only"
|
|
46
|
+
|
|
47
|
+
[recipe.selection.elimination]
|
|
48
|
+
kind = "none"
|
|
49
|
+
|
|
50
|
+
[recipe.limits]
|
|
51
|
+
max_parallel_trials = 2
|
|
52
|
+
timeout_seconds = 300
|
|
53
|
+
cpus = 2.0
|
|
54
|
+
memory_mb = 4096
|
|
55
|
+
max_output_bytes = 268435456
|
synth_optimizers-0.2.13/src/synth_optimizers/eval/catalog/eval.craftax.llm-policy.smoke.v1.toml
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Craftax LLM code-policy smoke. The candidate is data — an allowlisted model
|
|
2
|
+
# and reasoning effort — so comparing two efforts is a candidate set, not a
|
|
3
|
+
# code change.
|
|
4
|
+
#
|
|
5
|
+
# `network = "bridge"` and one declared secret are the minimum a paid policy
|
|
6
|
+
# needs; the route, the rates, and the caps stay recipe-owned so a candidate
|
|
7
|
+
# cannot bill against an endpoint the product did not name.
|
|
8
|
+
|
|
9
|
+
[recipe]
|
|
10
|
+
id = "eval.craftax.llm-policy.smoke.v1"
|
|
11
|
+
title = "Craftax LLM policy smoke"
|
|
12
|
+
description = "Score allowlisted LLM policies on one pinned Craftax world, report only."
|
|
13
|
+
task = "craftax"
|
|
14
|
+
policy_kind = "llm-policy.v1"
|
|
15
|
+
image = "craftax-eval-target"
|
|
16
|
+
prerequisites = [
|
|
17
|
+
"Published craftax-eval-target image pinned by digest",
|
|
18
|
+
"OPENAI_API_KEY in the eval home's secrets.toml",
|
|
19
|
+
]
|
|
20
|
+
scenarios = ["craftax-default-48x48"]
|
|
21
|
+
screening_seeds = [101, 102]
|
|
22
|
+
confirmation_seeds = []
|
|
23
|
+
secrets = ["OPENAI_API_KEY"]
|
|
24
|
+
|
|
25
|
+
[recipe.budget]
|
|
26
|
+
max_llm_calls = 20
|
|
27
|
+
max_usd = 0.30
|
|
28
|
+
|
|
29
|
+
[[recipe.models]]
|
|
30
|
+
id = "gpt-5.6-luna"
|
|
31
|
+
route = "https://api.openai.com/v1/chat/completions"
|
|
32
|
+
secret = "OPENAI_API_KEY"
|
|
33
|
+
efforts = ["none", "low", "medium", "high"]
|
|
34
|
+
usd_per_1m_input = 0.2
|
|
35
|
+
usd_per_1m_output = 1.2
|
|
36
|
+
usd_per_1m_cached_input = 0.02
|
|
37
|
+
price_source = "https://developers.openai.com/api/docs/pricing (standard tier)"
|
|
38
|
+
price_as_of = "2026-07-30"
|
|
39
|
+
|
|
40
|
+
[recipe.target]
|
|
41
|
+
schema_version = "eval.target.v1"
|
|
42
|
+
policy_kinds = ["llm-policy.v1"]
|
|
43
|
+
trial_mode = "one-policy-one-seed"
|
|
44
|
+
required_gates = ["policy_loaded", "verifier_completed"]
|
|
45
|
+
required_artifacts = ["trace"]
|
|
46
|
+
supports_live_events = true
|
|
47
|
+
network = "bridge"
|
|
48
|
+
|
|
49
|
+
[[recipe.target.metrics]]
|
|
50
|
+
id = "reward"
|
|
51
|
+
direction = "maximize"
|
|
52
|
+
|
|
53
|
+
[[recipe.target.metrics]]
|
|
54
|
+
id = "achievements"
|
|
55
|
+
direction = "maximize"
|
|
56
|
+
|
|
57
|
+
[recipe.selection]
|
|
58
|
+
primary_metric = "reward"
|
|
59
|
+
min_lift = 0.0
|
|
60
|
+
min_valid_trials = 2
|
|
61
|
+
decision_mode = "report_only"
|
|
62
|
+
|
|
63
|
+
[recipe.selection.elimination]
|
|
64
|
+
kind = "none"
|
|
65
|
+
|
|
66
|
+
[recipe.limits]
|
|
67
|
+
max_parallel_trials = 4
|
|
68
|
+
timeout_seconds = 1800
|
|
69
|
+
cpus = 2.0
|
|
70
|
+
memory_mb = 4096
|
|
71
|
+
max_output_bytes = 268435456
|