verifiers 0.4.1.dev3__py3-none-any.whl → 0.4.1.dev5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- verifiers/v1/runtimes/base.py +3 -0
- verifiers/v1/runtimes/prime.py +1 -0
- verifiers/v1/utils/loaders.py +13 -3
- {verifiers-0.4.1.dev3.dist-info → verifiers-0.4.1.dev5.dist-info}/METADATA +29 -1
- {verifiers-0.4.1.dev3.dist-info → verifiers-0.4.1.dev5.dist-info}/RECORD +8 -10
- {verifiers-0.4.1.dev3.dist-info → verifiers-0.4.1.dev5.dist-info}/entry_points.txt +0 -1
- verifiers/v1/cli/init.py +0 -252
- verifiers/v1/configs/cli/init.py +0 -17
- {verifiers-0.4.1.dev3.dist-info → verifiers-0.4.1.dev5.dist-info}/WHEEL +0 -0
- {verifiers-0.4.1.dev3.dist-info → verifiers-0.4.1.dev5.dist-info}/licenses/LICENSE +0 -0
verifiers/v1/runtimes/base.py
CHANGED
|
@@ -147,6 +147,9 @@ class Runtime(ABC):
|
|
|
147
147
|
use a host `Tunnel` inward plus `expose` outward."""
|
|
148
148
|
|
|
149
149
|
supports_user: ClassVar[bool] = False
|
|
150
|
+
supports_expose: ClassVar[bool] = True
|
|
151
|
+
"""Whether `expose` can publish a port inside this runtime to the outside, so a
|
|
152
|
+
server here is reachable from another runtime."""
|
|
150
153
|
"""Whether `with_user` can run this runtime's commands as another existing user."""
|
|
151
154
|
|
|
152
155
|
scripts_dir: ClassVar[str] = "/tmp/vf-scripts"
|
verifiers/v1/runtimes/prime.py
CHANGED
|
@@ -149,6 +149,7 @@ class PrimeProcess(RuntimeProcess):
|
|
|
149
149
|
|
|
150
150
|
class PrimeRuntime(Runtime):
|
|
151
151
|
supports_user: ClassVar[bool] = True
|
|
152
|
+
supports_expose: ClassVar[bool] = False
|
|
152
153
|
is_local: ClassVar[bool] = False
|
|
153
154
|
|
|
154
155
|
def __init__(self, config: PrimeConfig, name: str | None = None) -> None:
|
verifiers/v1/utils/loaders.py
CHANGED
|
@@ -27,11 +27,21 @@ from verifiers.v1.utils.generic import concrete_type, prefix_validation_error
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
def builtin_harness_ids() -> list[str]:
|
|
30
|
-
"""The harness ids that ship with verifiers
|
|
31
|
-
subpackages
|
|
30
|
+
"""The harness ids that ship with verifiers: the `verifiers.v1.harnesses`
|
|
31
|
+
subpackages that export a `Harness`, by their hyphenated id."""
|
|
32
32
|
from verifiers.v1 import harnesses
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
ids = []
|
|
35
|
+
for info in pkgutil.iter_modules(harnesses.__path__):
|
|
36
|
+
if not info.ispkg:
|
|
37
|
+
continue
|
|
38
|
+
module = importlib.import_module(f"{harnesses.__name__}.{info.name}")
|
|
39
|
+
try:
|
|
40
|
+
_plugin_class(module, Harness, "harness")
|
|
41
|
+
except (AttributeError, TypeError):
|
|
42
|
+
continue
|
|
43
|
+
ids.append(info.name.replace("_", "-"))
|
|
44
|
+
return sorted(ids)
|
|
35
45
|
|
|
36
46
|
|
|
37
47
|
def narrow_plugin_field(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: verifiers
|
|
3
|
-
Version: 0.4.1.
|
|
3
|
+
Version: 0.4.1.dev5
|
|
4
4
|
Summary: Verifiers: Environments for LLM Reinforcement Learning
|
|
5
5
|
Project-URL: Homepage, https://github.com/primeintellect-ai/verifiers
|
|
6
6
|
Project-URL: Documentation, https://github.com/primeintellect-ai/verifiers
|
|
@@ -91,6 +91,34 @@ uv tool install prime
|
|
|
91
91
|
- The [docs](docs/) contain short, human-written guides and overviews about the architecture.
|
|
92
92
|
- The [AGENTS.md](AGENTS.md) and [skills](skills/) are for coding agents and go into more details.
|
|
93
93
|
|
|
94
|
+
## Contributing
|
|
95
|
+
|
|
96
|
+
We welcome community contributions. We use [issues](https://github.com/PrimeIntellect-ai/verifiers/issues) to track bugs and feature requests. If you hit a bug, a pain point, or have an idea for a feature, please open an issue.
|
|
97
|
+
|
|
98
|
+
Contributions are welcome via PR. Please follow these guidelines:
|
|
99
|
+
|
|
100
|
+
1. Install the [pre-commit hooks](#pre-commit-hooks) so your code is formatted and type-checked.
|
|
101
|
+
2. Keep your PR in "Draft" until it is ready for review.
|
|
102
|
+
3. If your PR resolves an issue, link the issue in the PR description.
|
|
103
|
+
4. Run the [tests](#tests) for the areas you touched.
|
|
104
|
+
|
|
105
|
+
### Pre-commit hooks
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
uv run pre-commit install
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Tests
|
|
112
|
+
|
|
113
|
+
Unit tests run one component in isolation, with no network, and mirror the `verifiers/v1` layout. Integration tests run real evals: they need `PRIME_API_KEY` and skip without it.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
uv run pytest tests/unit -n auto # unit
|
|
117
|
+
uv run pytest tests/integration -n 8 # integration
|
|
118
|
+
uv run pytest tests/integration/test_single_turn.py # one behavior
|
|
119
|
+
uv run pytest tests/integration -m "docker and codex" # one runtime and harness
|
|
120
|
+
```
|
|
121
|
+
|
|
94
122
|
## Citation
|
|
95
123
|
|
|
96
124
|
Originally created by Will Brown ([@willccbb](https://github.com/willccbb)).
|
|
@@ -20,7 +20,6 @@ verifiers/v1/acp/runner.py,sha256=sFsg0UgWeDjpjihejUidIV2yTapVj1Ap0cDTaEktjkI,15
|
|
|
20
20
|
verifiers/v1/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
21
|
verifiers/v1/cli/debug.py,sha256=OgzXCW9HaTNruZil4f70WP5tR6toKliKaVvV98C5qzE,11665
|
|
22
22
|
verifiers/v1/cli/gepa.py,sha256=IyS3YZCCHVydb-OyPeGdtCYsz6OYqXXddXqYq8RLucM,4374
|
|
23
|
-
verifiers/v1/cli/init.py,sha256=k1wawdQBquiiepPrb0enBT-vdKvfSievgs4CiwSdFUc,7601
|
|
24
23
|
verifiers/v1/cli/output.py,sha256=4FRuQ6UIZCigMfUUO2nCFFJKxls3DtWDXswMCVTxjIA,5010
|
|
25
24
|
verifiers/v1/cli/replay.py,sha256=LkeaV8Sxa7kHue9JKHDg0V_N6KXOcjN_r6RmeQVcxfk,10396
|
|
26
25
|
verifiers/v1/cli/resolve.py,sha256=Q1EHM7wWQo0YkwJA898qtZbYLaIkjIVq3Q7kUp2YIxs,4346
|
|
@@ -57,7 +56,6 @@ verifiers/v1/configs/cli/__init__.py,sha256=YMDUPdbRlDJ77dhj3QqzmyRhqNgUvuQdpj_b
|
|
|
57
56
|
verifiers/v1/configs/cli/debug.py,sha256=CcUZ9MEcv0iAL9w2BkTfnZg20yWJ-Vn8P30-e5tuCic,2741
|
|
58
57
|
verifiers/v1/configs/cli/env.py,sha256=qg2LNOasAU0yg3b0xqXpx3cIj4nHbHSlK3Ldc3NhiT4,2667
|
|
59
58
|
verifiers/v1/configs/cli/eval.py,sha256=9Zw7mAUipMhoIcwRa_lgo5gII4rMmMEBAgzcPxPWPjw,6895
|
|
60
|
-
verifiers/v1/configs/cli/init.py,sha256=JvIUOdhfZfNOXg2wm2i06jLLHpb97tNMzZqmcK_9wVw,916
|
|
61
59
|
verifiers/v1/configs/cli/replay.py,sha256=vUCNs-9j1CXcAZhGozN1EaztcXK_dYVK3iN_fRmbSXw,2929
|
|
62
60
|
verifiers/v1/configs/cli/validate.py,sha256=m5ReEfF4-_hOlsvuCtCdeCDywXAfQoKR-NpH6Fzv1u0,3990
|
|
63
61
|
verifiers/v1/dialects/__init__.py,sha256=MNOYM2NdTlSxGK4VtoEjMtD5zya2MpjPDX5jMvZUWEo,736
|
|
@@ -143,12 +141,12 @@ verifiers/v1/mcp/server.py,sha256=Jqi8OMT8DnoZegXqM3UNNRzhVnbdrPEwx0DjOJo_K2A,13
|
|
|
143
141
|
verifiers/v1/mcp/toolset.py,sha256=G2wzNdEMGLXoQUcrwF0TartJkqokNPI3o7YUOAaaa6U,1007
|
|
144
142
|
verifiers/v1/runtimes/__init__.py,sha256=zOG9BYsK19VRNqvggqh3f6g1_UGIq7VjIBcK8kDlmnQ,3515
|
|
145
143
|
verifiers/v1/runtimes/apptainer.py,sha256=Ru9QJna_l0goIzg71G-4RU_D-7wZUNz139S5TEvbzog,8211
|
|
146
|
-
verifiers/v1/runtimes/base.py,sha256=
|
|
144
|
+
verifiers/v1/runtimes/base.py,sha256=4ma91e_M1KXOAx74dNBVPJoxrqnQaOuvbkSBlHMmujE,20128
|
|
147
145
|
verifiers/v1/runtimes/container.py,sha256=_hNhGOo1Zvorj7THSj2UrZTkgewySUVJe4Kd777-QnI,12563
|
|
148
146
|
verifiers/v1/runtimes/e2b.py,sha256=yBeocAutsv2l5x-C5IMqrlgBz6Cb-t6vWbX4qTjlztE,30306
|
|
149
147
|
verifiers/v1/runtimes/limiters.py,sha256=rOfQJcMdYcLSKq8AL9O09BfGOLqpYmNgrCxXXNcHLmU,2849
|
|
150
148
|
verifiers/v1/runtimes/modal.py,sha256=ZHA4vtNIZwTV-bnVUlambgc8l34j_ZulvtrwvvkE2Kg,17945
|
|
151
|
-
verifiers/v1/runtimes/prime.py,sha256=
|
|
149
|
+
verifiers/v1/runtimes/prime.py,sha256=xo9vFn6gNQRhG_8DFPcSyKcTCcZRf4n5UPS7cnbRFm8,20880
|
|
152
150
|
verifiers/v1/runtimes/subprocess.py,sha256=vnGVAI3J7pYmRei4MQ7MN4nb8SglLi70NtVTINMPVvQ,8855
|
|
153
151
|
verifiers/v1/runtimes/docker/__init__.py,sha256=QoFOTMgRjoWD--O25Jsft9eD2vjcrMpJQyhfQXqWraI,21828
|
|
154
152
|
verifiers/v1/runtimes/docker/egress.py,sha256=wtKWTL2_zFidxMR7lDRmfevQlOsl2Iyk88ebdO4Kqqw,24566
|
|
@@ -185,7 +183,7 @@ verifiers/v1/utils/generic.py,sha256=isejTTgRoFDJQOM18L3sWqfzBRQyYUkQvk-gNbrYAVc
|
|
|
185
183
|
verifiers/v1/utils/git.py,sha256=MTRinOvG4EddfjdahHkFZUihHmhJ37n5ROtgjzjE1NA,8366
|
|
186
184
|
verifiers/v1/utils/image.py,sha256=OFw_wdwVtbdwa8uJ3X3vYfhpUAi0CTH5HMBupjVsRRQ,282
|
|
187
185
|
verifiers/v1/utils/interrupt.py,sha256=F-KKhc5ndPJJfhd3SuMqyqhXhA32FhCRy5KWFJpEoM4,1179
|
|
188
|
-
verifiers/v1/utils/loaders.py,sha256=
|
|
186
|
+
verifiers/v1/utils/loaders.py,sha256=WhIHRnAXfFpfCEgH35J1XHd95KRarmg62nxUkUB4HME,12670
|
|
189
187
|
verifiers/v1/utils/logging.py,sha256=-zgaM-HZsgxumZ4wYNlRMZepp6JanCSjeL2wSVulwJM,2296
|
|
190
188
|
verifiers/v1/utils/memory.py,sha256=ZkIvGk6uITAH5sKon65LifKPbvZr8mJ__PVc23FZpOQ,1835
|
|
191
189
|
verifiers/v1/utils/paths.py,sha256=it_4JWf_8bPZe4TRcyvL7_KJ4fsbEsxhhIY_xA8Ikus,308
|
|
@@ -196,8 +194,8 @@ verifiers/v1/utils/scope.py,sha256=bzUEiWDOVdbj7dXOwGOlzsQ_-Xu0j9NR5TalQB-8TS8,8
|
|
|
196
194
|
verifiers/v1/utils/score.py,sha256=493yJVMw8teCu9JxapxMFPFzI0hNUqdo0Y2nGW4kckk,6200
|
|
197
195
|
verifiers/v1/utils/trace_store.py,sha256=RsCDonGR-bs-tvEstcppiJm3jFmAdIiG83fA5KtCbAw,2801
|
|
198
196
|
verifiers/v1/utils/version.py,sha256=-obEo_-l9-D8FLef4hYxncOe-uJpxrM1g2Hig_37Sgs,1607
|
|
199
|
-
verifiers-0.4.1.
|
|
200
|
-
verifiers-0.4.1.
|
|
201
|
-
verifiers-0.4.1.
|
|
202
|
-
verifiers-0.4.1.
|
|
203
|
-
verifiers-0.4.1.
|
|
197
|
+
verifiers-0.4.1.dev5.dist-info/METADATA,sha256=12xwkEJs-6xoBi01_gAkwto_zrPPL5Ps77wBUJ9UXNA,5361
|
|
198
|
+
verifiers-0.4.1.dev5.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
199
|
+
verifiers-0.4.1.dev5.dist-info/entry_points.txt,sha256=O1bIO0gyJWuLfWtTGF0h-JkNz6FkyXP7Z9iMFYnjeMI,222
|
|
200
|
+
verifiers-0.4.1.dev5.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
|
|
201
|
+
verifiers-0.4.1.dev5.dist-info/RECORD,,
|
verifiers/v1/cli/init.py
DELETED
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
"""Scaffold v1 environment packages."""
|
|
2
|
-
|
|
3
|
-
import sys
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
|
|
6
|
-
from pydantic_config import cli
|
|
7
|
-
|
|
8
|
-
from verifiers.v1.configs.cli.init import InitConfig
|
|
9
|
-
|
|
10
|
-
USAGE = (
|
|
11
|
-
"usage: uv run vf-init <name> [--path ./environments] [-T/--add-tool] "
|
|
12
|
-
"[-H/--add-harness]\n"
|
|
13
|
-
" scaffold a new environment package"
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def _names(name: str) -> tuple[str, str, str, str]:
|
|
18
|
-
dash = name.strip().strip("/").replace("_", "-").lower()
|
|
19
|
-
pkg = dash.replace("-", "_")
|
|
20
|
-
stem = pkg.removesuffix("_v1")
|
|
21
|
-
prefix = "".join(part[:1].upper() + part[1:] for part in stem.split("_") if part)
|
|
22
|
-
if not prefix or not prefix[0].isalpha():
|
|
23
|
-
prefix = f"Env{prefix}"
|
|
24
|
-
return dash, pkg, stem, prefix
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def _write(path: Path, content: str) -> None:
|
|
28
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
|
29
|
-
path.write_text(content)
|
|
30
|
-
print(f" write {path}")
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def _pyproject(dash: str, pkg: str) -> str:
|
|
34
|
-
return f"""\
|
|
35
|
-
[project]
|
|
36
|
-
name = "{dash}"
|
|
37
|
-
version = "0.1.0"
|
|
38
|
-
description = "{dash} — <one-line description>."
|
|
39
|
-
requires-python = ">=3.11"
|
|
40
|
-
dependencies = ["verifiers"]
|
|
41
|
-
|
|
42
|
-
[build-system]
|
|
43
|
-
requires = ["hatchling"]
|
|
44
|
-
build-backend = "hatchling.build"
|
|
45
|
-
|
|
46
|
-
[tool.hatch.build.targets.wheel]
|
|
47
|
-
packages = ["{pkg}"]
|
|
48
|
-
"""
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def _init_py(pkg: str, prefix: str, add_harness: bool) -> str:
|
|
52
|
-
lines = [f"from {pkg}.taskset import {prefix}Taskset"]
|
|
53
|
-
exports = [f"{prefix}Taskset"]
|
|
54
|
-
if add_harness:
|
|
55
|
-
lines.append(f"from {pkg}.harness import {prefix}Harness")
|
|
56
|
-
exports.append(f"{prefix}Harness")
|
|
57
|
-
exports_repr = ", ".join(f'"{e}"' for e in exports)
|
|
58
|
-
return "\n".join(lines) + f"\n\n__all__ = [{exports_repr}]\n"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def _taskset_py(pkg: str, prefix: str, *, add_tool: bool) -> str:
|
|
62
|
-
imports = "import verifiers.v1 as vf"
|
|
63
|
-
local_imports: list[str] = []
|
|
64
|
-
task_config_fields = ""
|
|
65
|
-
task_decls = ""
|
|
66
|
-
if add_tool:
|
|
67
|
-
local_imports.append(f"from {pkg}.servers.tool import {prefix}Toolset")
|
|
68
|
-
task_config_fields += "\n tools: vf.ToolsetConfig = vf.ToolsetConfig()"
|
|
69
|
-
task_decls += (
|
|
70
|
-
"\n\n @classmethod"
|
|
71
|
-
f"\n def toolsets(cls, config: {prefix}TaskConfig) -> list[vf.Toolset]:"
|
|
72
|
-
f"\n return [{prefix}Toolset(config.tools)]"
|
|
73
|
-
"\n"
|
|
74
|
-
)
|
|
75
|
-
if local_imports:
|
|
76
|
-
imports += "\n\n" + "\n".join(local_imports)
|
|
77
|
-
task_config = (
|
|
78
|
-
f"\n\nclass {prefix}TaskConfig(vf.TaskConfig):\n"
|
|
79
|
-
' """Knobs the task reads from ``self.config``; configure them under '
|
|
80
|
-
f'``--env.taskset.task.*``."""{task_config_fields}\n'
|
|
81
|
-
if add_tool
|
|
82
|
-
else ""
|
|
83
|
-
)
|
|
84
|
-
task_generic = (
|
|
85
|
-
f"{prefix}Data, vf.State, {prefix}TaskConfig" if add_tool else f"{prefix}Data"
|
|
86
|
-
)
|
|
87
|
-
config_body = ' num_tasks: int = 5\n """How many tasks to build."""\n' + (
|
|
88
|
-
f" task: {prefix}TaskConfig = {prefix}TaskConfig()\n" if add_tool else ""
|
|
89
|
-
)
|
|
90
|
-
return f'''\
|
|
91
|
-
{imports}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
class {prefix}Data(vf.TaskData):
|
|
95
|
-
"""One row's data. Add task-specific fields here, such as a reference answer."""
|
|
96
|
-
{task_config}
|
|
97
|
-
|
|
98
|
-
class {prefix}Task(vf.Task[{task_generic}]):
|
|
99
|
-
"""Rewards, hooks, and servers, with row data available on ``self.data``."""{task_decls}
|
|
100
|
-
@vf.reward(weight=1.0)
|
|
101
|
-
async def reward(self, trace: vf.Trace) -> float:
|
|
102
|
-
raise NotImplementedError("Score the rollout and return a float (e.g. in [0, 1]).")
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
class {prefix}Config(vf.TasksetConfig):
|
|
106
|
-
{config_body}
|
|
107
|
-
|
|
108
|
-
class {prefix}Taskset(vf.Taskset[{prefix}Task, {prefix}Config]):
|
|
109
|
-
def load(self) -> list[{prefix}Task]:
|
|
110
|
-
raise NotImplementedError(
|
|
111
|
-
"Return this taskset's tasks, e.g. "
|
|
112
|
-
"[{prefix}Task({prefix}Data(prompt=...), self.config.task) "
|
|
113
|
-
"for i in range(self.config.num_tasks)]."
|
|
114
|
-
)
|
|
115
|
-
'''
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def _tool_py(stem: str, prefix: str) -> str:
|
|
119
|
-
return f'''\
|
|
120
|
-
import verifiers.v1 as vf
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
class {prefix}Toolset(vf.Toolset[vf.ToolsetConfig]):
|
|
124
|
-
TOOL_PREFIX = "{stem}"
|
|
125
|
-
|
|
126
|
-
@vf.tool
|
|
127
|
-
def echo(self, text: str) -> str:
|
|
128
|
-
"""Return the given text unchanged (replace with a real tool)."""
|
|
129
|
-
return text
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if __name__ == "__main__":
|
|
133
|
-
{prefix}Toolset.run()
|
|
134
|
-
'''
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
def _harness_py(prefix: str) -> str:
|
|
138
|
-
return f'''\
|
|
139
|
-
import verifiers.v1 as vf
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
class {prefix}HarnessConfig(vf.HarnessConfig):
|
|
143
|
-
"""Run knobs for this harness. Add fields here (e.g. a CLI version to install)."""
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
class {prefix}Harness(vf.Harness[{prefix}HarnessConfig]):
|
|
147
|
-
APPENDS_SYSTEM_PROMPT = True
|
|
148
|
-
|
|
149
|
-
async def launch(
|
|
150
|
-
self,
|
|
151
|
-
ctx: vf.ModelContext,
|
|
152
|
-
trace: vf.Trace,
|
|
153
|
-
runtime: vf.Runtime,
|
|
154
|
-
endpoint: str,
|
|
155
|
-
secret: str,
|
|
156
|
-
mcp_urls: dict[str, str],
|
|
157
|
-
data: vf.TaskData,
|
|
158
|
-
) -> vf.ProgramResult:
|
|
159
|
-
raise NotImplementedError(
|
|
160
|
-
"Implement launch: run your agent in `runtime`, pointing its model calls at "
|
|
161
|
-
"`endpoint` with bearer token `secret`."
|
|
162
|
-
)
|
|
163
|
-
'''
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
def _readme(dash: str, pkg: str, *, add_tool: bool, add_harness: bool) -> str:
|
|
167
|
-
layout = [
|
|
168
|
-
(
|
|
169
|
-
f"- `{pkg}/taskset.py` — the task (`@reward` scoring + behavior) and the taskset: "
|
|
170
|
-
"`load` (data + prompts)."
|
|
171
|
-
)
|
|
172
|
-
]
|
|
173
|
-
if add_tool:
|
|
174
|
-
layout.append(
|
|
175
|
-
f"- `{pkg}/servers/tool.py` — a `vf.Toolset` tool server, constructed in `Task.toolsets`."
|
|
176
|
-
)
|
|
177
|
-
if add_harness:
|
|
178
|
-
layout.append(
|
|
179
|
-
f"- `{pkg}/harness.py` — a custom harness, selectable with `--env.agent.harness.id {dash}`."
|
|
180
|
-
)
|
|
181
|
-
layout_block = "\n".join(layout)
|
|
182
|
-
return f"""\
|
|
183
|
-
# {dash}
|
|
184
|
-
|
|
185
|
-
A v1 verifiers environment, scaffolded with `init`.
|
|
186
|
-
|
|
187
|
-
## Develop
|
|
188
|
-
|
|
189
|
-
1. Implement `load` and the `@reward` in `{pkg}/taskset.py` (see `environments/`).
|
|
190
|
-
2. Install + run:
|
|
191
|
-
|
|
192
|
-
```bash
|
|
193
|
-
uv pip install -e . # install this package (or register it in your project)
|
|
194
|
-
uv run vf-eval {dash} -n 3 # evaluate a few tasks with the bash harness
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
## Layout
|
|
198
|
-
|
|
199
|
-
{layout_block}
|
|
200
|
-
|
|
201
|
-
Tune knobs from the CLI: `--env.taskset.num-tasks 10`, `--model <id>`, `-n`, and `-r`.
|
|
202
|
-
"""
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
def scaffold(config: InitConfig) -> Path:
|
|
206
|
-
dash, pkg, stem, prefix = _names(config.name)
|
|
207
|
-
env_dir = Path(config.path) / pkg
|
|
208
|
-
pkg_dir = env_dir / pkg
|
|
209
|
-
if env_dir.exists() and not config.force:
|
|
210
|
-
raise SystemExit(
|
|
211
|
-
f"error: {env_dir} already exists - refusing to overwrite (pass --force to overwrite)"
|
|
212
|
-
)
|
|
213
|
-
print(f"scaffolding v1 environment {dash!r} in {env_dir}")
|
|
214
|
-
|
|
215
|
-
_write(env_dir / "pyproject.toml", _pyproject(dash, pkg))
|
|
216
|
-
_write(
|
|
217
|
-
env_dir / "README.md",
|
|
218
|
-
_readme(dash, pkg, add_tool=config.add_tool, add_harness=config.add_harness),
|
|
219
|
-
)
|
|
220
|
-
_write(pkg_dir / "__init__.py", _init_py(pkg, prefix, config.add_harness))
|
|
221
|
-
_write(
|
|
222
|
-
pkg_dir / "taskset.py",
|
|
223
|
-
_taskset_py(pkg, prefix, add_tool=config.add_tool),
|
|
224
|
-
)
|
|
225
|
-
if config.add_harness:
|
|
226
|
-
_write(pkg_dir / "harness.py", _harness_py(prefix))
|
|
227
|
-
if config.add_tool:
|
|
228
|
-
_write(pkg_dir / "servers" / "__init__.py", "")
|
|
229
|
-
_write(pkg_dir / "servers" / "tool.py", _tool_py(stem, prefix))
|
|
230
|
-
|
|
231
|
-
print(f"\ndone. next:\n uv pip install -e {env_dir}\n uv run vf-eval {dash} -n 3")
|
|
232
|
-
return env_dir
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
def main(argv: list[str] | None = None) -> None:
|
|
236
|
-
argv = list(sys.argv[1:]) if argv is None else list(argv)
|
|
237
|
-
if argv and not argv[0].startswith(("-", "@")):
|
|
238
|
-
argv = ["--name", argv[0], *argv[1:]]
|
|
239
|
-
|
|
240
|
-
if not argv or any(arg in ("-h", "--help") for arg in argv):
|
|
241
|
-
print(USAGE)
|
|
242
|
-
sys.argv = [sys.argv[0], "--help"]
|
|
243
|
-
cli(InitConfig)
|
|
244
|
-
return
|
|
245
|
-
|
|
246
|
-
sys.argv = [sys.argv[0], *argv]
|
|
247
|
-
config = cli(InitConfig)
|
|
248
|
-
scaffold(config)
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if __name__ == "__main__":
|
|
252
|
-
main()
|
verifiers/v1/configs/cli/init.py
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"""Environment-scaffold CLI configuration."""
|
|
2
|
-
|
|
3
|
-
from pydantic import AliasChoices, Field
|
|
4
|
-
from pydantic_config import BaseConfig
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class InitConfig(BaseConfig):
|
|
8
|
-
name: str = Field(min_length=1)
|
|
9
|
-
"""The new environment id, e.g. `my-task-v1` (positional: `init my-task-v1`)."""
|
|
10
|
-
path: str = Field("./environments", validation_alias=AliasChoices("path", "p"))
|
|
11
|
-
"""Parent directory the package is created in (default `./environments`)."""
|
|
12
|
-
add_tool: bool = Field(False, validation_alias=AliasChoices("add_tool", "T"))
|
|
13
|
-
"""Also scaffold a `vf.Toolset` declared on the task (`-T`)."""
|
|
14
|
-
add_harness: bool = Field(False, validation_alias=AliasChoices("add_harness", "H"))
|
|
15
|
-
"""Also scaffold a custom `vf.Harness` (`harness.py`), selectable via `--env.agent.harness.id <name>` (`-H`)."""
|
|
16
|
-
force: bool = False
|
|
17
|
-
"""Overwrite an existing environment package (default: refuse if it already exists)."""
|
|
File without changes
|
|
File without changes
|