verifiers 0.2.2.dev36__py3-none-any.whl → 0.2.2.dev38__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.
@@ -13,7 +13,7 @@ from dataclasses import dataclass
13
13
  from pathlib import PurePosixPath
14
14
  from typing import ClassVar, Self
15
15
 
16
- from pydantic import Field
16
+ from pydantic import Field, model_validator
17
17
  from pydantic_config import BaseConfig
18
18
 
19
19
  from verifiers.v1.errors import SandboxError
@@ -100,15 +100,32 @@ class NetworkPolicyConfig(BaseConfig):
100
100
  """Shared execution-time policy surface for runtimes that support it."""
101
101
 
102
102
  allow: list[str] = Field(default_factory=lambda: ["*"])
103
- """Destinations allowed during execution; `*` leaves egress unrestricted."""
103
+ """Destinations allowed during execution; `*` is unrestricted and `[]` is
104
+ framework-only."""
104
105
  block: list[str] = Field(default_factory=list)
105
- """Destinations denied during execution."""
106
+ """Destinations denied during execution; any `*` makes the policy framework-only."""
107
+
108
+ @model_validator(mode="after")
109
+ def _validate_network_policy(self) -> Self:
110
+ if not self.allow or "*" in self.block:
111
+ # Empty allowlists and wildcard blocks both mean framework-only access.
112
+ self.allow = []
113
+ self.block = ["*"]
114
+ elif self.allow != ["*"] and self.block:
115
+ raise ValueError(
116
+ "non-empty concrete allow and block egress lists are mutually exclusive"
117
+ )
118
+ return self
106
119
 
107
120
  @property
108
121
  def network_restricted(self) -> bool:
109
122
  return "*" not in self.allow or bool(self.block)
110
123
 
111
124
  def with_task_network_policy(self, allow: list[str], block: list[str]) -> Self:
125
+ values = self.model_dump()
126
+ if not allow or not self.allow or "*" in block:
127
+ # Framework-only access is absorbing; composition cannot widen either side.
128
+ return type(self).model_validate({**values, "allow": [], "block": ["*"]})
112
129
  if "*" not in allow:
113
130
  allow = (
114
131
  allow
@@ -118,9 +135,7 @@ class NetworkPolicyConfig(BaseConfig):
118
135
  else:
119
136
  allow = self.allow
120
137
  block = list(dict.fromkeys([*block, *self.block]))
121
- return type(self).model_validate(
122
- {**self.model_dump(), "allow": allow, "block": block}
123
- )
138
+ return type(self).model_validate({**values, "allow": allow, "block": block})
124
139
 
125
140
 
126
141
  class BaseRuntimeInfo(BaseConfig):
@@ -285,7 +300,7 @@ class Runtime(ABC):
285
300
 
286
301
  async def prepare_execution(self, routes: list[str]) -> None:
287
302
  """Last setup step, right before the agent starts. Restricted runtimes enforce
288
- their policy here while keeping the interception and MCP `routes` reachable."""
303
+ their policy here; `routes` identifies the interception and MCP endpoints."""
289
304
 
290
305
  @property
291
306
  def network_restricted(self) -> bool:
@@ -16,6 +16,7 @@ from pathlib import Path, PurePosixPath
16
16
  from typing import ClassVar, Literal
17
17
  from urllib.parse import urlsplit
18
18
 
19
+ from prime_sandboxes.models import validate_egress_lists
19
20
  from pydantic import Field, model_validator
20
21
 
21
22
  from verifiers.v1.errors import SandboxError
@@ -75,12 +76,12 @@ class PrimeConfig(NetworkPolicyConfig):
75
76
  raise ValueError(
76
77
  "Prime allow/block egress lists require a VM sandbox (vm=true)"
77
78
  )
78
- from prime_sandboxes.models import validate_egress_lists
79
-
80
- allow = None if self.allow == ["*"] else self.allow
81
- block = self.block or None
82
- if allow is not None or block != ["*"]:
83
- validate_egress_lists(allow, block)
79
+ if not self.allow:
80
+ return self
81
+ validate_egress_lists(
82
+ None if self.allow == ["*"] else self.allow,
83
+ self.block or None,
84
+ )
84
85
  return self
85
86
 
86
87
  @model_validator(mode="after")
@@ -185,13 +186,15 @@ class PrimeRuntime(Runtime):
185
186
  if not self.network_restricted:
186
187
  return
187
188
  try:
189
+ hosts = list(
190
+ dict.fromkeys(
191
+ h for h in (urlsplit(route).hostname for route in routes) if h
192
+ )
193
+ )
188
194
  if self.config.allow == ["*"]:
189
195
  policy = {"deny": self.config.block}
190
196
  else:
191
- hosts = [h for h in (urlsplit(route).hostname for route in routes) if h]
192
197
  entries = list(dict.fromkeys([*hosts, *self.config.allow]))
193
- from prime_sandboxes.models import validate_egress_lists
194
-
195
198
  validate_egress_lists(entries, None)
196
199
  policy = {"allow": entries} if entries else {"deny": ["*"]}
197
200
  status = await self._client.set_network(self.info.id, **policy)
verifiers/v1/task.py CHANGED
@@ -120,7 +120,8 @@ class TaskData(StrictBaseModel):
120
120
  entries. Prime runtimes accept host-level entries and require `vm=true`."""
121
121
  network_block: list[str] = Field(default_factory=list)
122
122
  """Execution-time destinations denied by this task and combined with runtime
123
- blocks. Prime runtimes cannot combine an allowlist and a blocklist."""
123
+ blocks. Non-empty concrete allowlists cannot be combined with blocklists. Docker
124
+ framework routes take precedence; ordinary Prime deny rules pass through unchanged."""
124
125
  timeout: TaskTimeout = TaskTimeout()
125
126
  resources: TaskResources = TaskResources()
126
127
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: verifiers
3
- Version: 0.2.2.dev36
3
+ Version: 0.2.2.dev38
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
@@ -184,7 +184,7 @@ verifiers/v1/rollout.py,sha256=eU01fZRf87lQ5LQUVIDN38SlcUE0svXxfyS0gryNboE,20503
184
184
  verifiers/v1/scoring.py,sha256=-R5Cog14r_tJ6Q_oOfGr5VPAm2CCUhofYZB6B9lm4wM,5787
185
185
  verifiers/v1/session.py,sha256=J6ZPuvsg6vMTJAs9dMUMtfdjCuvp6Hom877DVdKFKlY,6912
186
186
  verifiers/v1/state.py,sha256=R8tyQv8nsFV2pztrquDqCOa1Mk1fAp3w2GjqUugZwE0,689
187
- verifiers/v1/task.py,sha256=VSle6Y8zb3DLxzaoTwJR9-0ROnCTvPFuXie_BfaMoKE,10975
187
+ verifiers/v1/task.py,sha256=-NQVKoiRXn83Q5RM0fX0qFSTA0tWapkL2S1gFU1RDW0,11076
188
188
  verifiers/v1/taskset.py,sha256=PX1-skAVhSpGF07qjxcG0Ctmq1LiMftMxxok-uc8qRY,3939
189
189
  verifiers/v1/trace.py,sha256=bg-hFtn-m-lT676myUlUddk5GYyGcZbwKPupiMHMbGc,26618
190
190
  verifiers/v1/types.py,sha256=5tZyG4r4bLJ9a14oybHy7bSCpt5X5A17eRwmIszuRo8,9118
@@ -292,10 +292,10 @@ verifiers/v1/mcp/launch.py,sha256=lRtcl98BO7imC44bsxO2yljwRQR_KCvJ6P-bd_hS5L8,18
292
292
  verifiers/v1/mcp/server.py,sha256=uW8qddXQbtECxIPCU-lkOlFIv3VKWoFAeZFNhwPoyWo,10985
293
293
  verifiers/v1/mcp/toolset.py,sha256=tSPXgTNREZyaeCnoFVnDfXxFAj_pStZMPUIgyPrY_Dk,996
294
294
  verifiers/v1/runtimes/__init__.py,sha256=TqNtJVahzQuLS4fgCVeT9xdOzTkp0hRAPOkl7eFVDUg,2011
295
- verifiers/v1/runtimes/base.py,sha256=VU55o9YEak6fgYjQoL912nEETAOBYziL0utf0j60vUc,13411
295
+ verifiers/v1/runtimes/base.py,sha256=hv1McFrIZgymLwMLNYPAlsR4At0uz60haVo5eXrFbNU,14196
296
296
  verifiers/v1/runtimes/limiters.py,sha256=ZjjYUFEt20yH8ggL5uU9w9U500AOB44qSUTQ7bYyh0c,2730
297
297
  verifiers/v1/runtimes/modal.py,sha256=FnocoJd9lQVQS3V3CoBon7KpKXm1bKWWeU2FAkq2bKU,8825
298
- verifiers/v1/runtimes/prime.py,sha256=mJPp4dm-ApBX3MRlek__ntzBKmkgHnRR5XLS4kg65Rk,15120
298
+ verifiers/v1/runtimes/prime.py,sha256=wldpcZnKZHNRldpoubeMgHdl-ZlKWOyeulFu4nHNKwc,15110
299
299
  verifiers/v1/runtimes/subprocess.py,sha256=dOqYZycTO5wmXqg0Lg1h3l_CPh6Zok4PmTFcc-uE4WY,5989
300
300
  verifiers/v1/runtimes/docker/__init__.py,sha256=eC5hjfyPwvwEKaeZUeP9EN8tJkrl0HUxGMzjiK4tK4Q,14555
301
301
  verifiers/v1/runtimes/docker/egress.py,sha256=37UXgNX9gnoLxjMg4KZaJIGoApCAM6MK22eJGNoMi38,14514
@@ -327,8 +327,8 @@ verifiers/v1/utils/logging.py,sha256=OcMHA6NsYux3oIzjPuI95rDWmFBHNcHDjZeNIhXTX-Y
327
327
  verifiers/v1/utils/memory.py,sha256=ZkIvGk6uITAH5sKon65LifKPbvZr8mJ__PVc23FZpOQ,1835
328
328
  verifiers/v1/utils/sampling.py,sha256=JczGzBn6s3wsIrSY2Hy3hE8m6NreNgsNzhSjDikQqX0,1037
329
329
  verifiers/v1/utils/version.py,sha256=-obEo_-l9-D8FLef4hYxncOe-uJpxrM1g2Hig_37Sgs,1607
330
- verifiers-0.2.2.dev36.dist-info/METADATA,sha256=8W-AXmA5ITiRi1s2jGMZt0CVXr2iEBTrYd6pvxx7ZEI,4540
331
- verifiers-0.2.2.dev36.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
332
- verifiers-0.2.2.dev36.dist-info/entry_points.txt,sha256=dF82JUYEFslR1AOW8LZfuBWeZeQoyX4wCRrduklg8-I,551
333
- verifiers-0.2.2.dev36.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
334
- verifiers-0.2.2.dev36.dist-info/RECORD,,
330
+ verifiers-0.2.2.dev38.dist-info/METADATA,sha256=nNKqfDrRf0E27tQX765bwhTw913GLiOjcP-lSOgsK4c,4540
331
+ verifiers-0.2.2.dev38.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
332
+ verifiers-0.2.2.dev38.dist-info/entry_points.txt,sha256=dF82JUYEFslR1AOW8LZfuBWeZeQoyX4wCRrduklg8-I,551
333
+ verifiers-0.2.2.dev38.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
334
+ verifiers-0.2.2.dev38.dist-info/RECORD,,