verifiers 0.3.2.dev207__py3-none-any.whl → 0.3.2.dev209__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.
@@ -50,7 +50,16 @@ async def ensure_installed(
50
50
  f"mkdir -p {shlex.quote(directory)} && "
51
51
  f'if l=$(command -v flock || command -v lockf); then "$l" {lock} {run}; else {spinlock}; fi'
52
52
  )
53
- result = await runtime.run(["sh", "-c", guarded], env)
53
+ if runtime.user is None:
54
+ result = await runtime.run(["sh", "-c", guarded], env)
55
+ else:
56
+ # Install as root (system packages), keeping uv's Python in `directory`, then
57
+ # open it to the agent user: some installers leave it private.
58
+ python_dir = {"UV_PYTHON_INSTALL_DIR": f"{directory}/python"}
59
+ shareable = f"{guarded} && chmod -R a+rX {shlex.quote(directory)}"
60
+ result = await runtime.with_user(None).run(
61
+ ["sh", "-c", shareable], {**python_dir, **env}
62
+ )
54
63
  if result.exit_code != 0:
55
64
  detail = (result.stderr.strip() or result.stdout.strip())[-500:]
56
65
  raise RuntimeError(f"{label} install failed: {detail}")
@@ -234,7 +234,9 @@ async def _cached_package(src: Path) -> tuple[str, bytes]:
234
234
  del _PACKAGE_BUILD_STATES[key]
235
235
 
236
236
 
237
- async def _install_in_sandbox(server: ServerBase, runtime: Runtime) -> str:
237
+ async def _install_in_sandbox(server: ServerBase, agent: Runtime) -> str:
238
+ # Install as root; the agent user only runs the server.
239
+ runtime = agent if agent.user is None else agent.with_user(None)
238
240
  # Prime VMs mount /tmp as a small tmpfs, while the runtime workdir lives on
239
241
  # the VM's root disk. Keep source, build scratch space, and uv's cache on the
240
242
  # durable runtime filesystem so ordinary dependency installs cannot exhaust
@@ -244,35 +246,51 @@ async def _install_in_sandbox(server: ServerBase, runtime: Runtime) -> str:
244
246
  temp = str(PurePosixPath(workdir) / ".vf-tmp")
245
247
  cache = str(PurePosixPath(workdir) / ".vf-uv-cache")
246
248
  venv = str(PurePosixPath(workdir) / ".vf-venv")
249
+ python_dir = str(PurePosixPath(workdir) / ".vf-python")
247
250
  root_q, temp_q, cache_q, venv_q = map(shlex.quote, (root, temp, cache, venv))
248
251
  # Colocated servers and borrowed views install into one physical environment.
249
252
  # Serialize its mutations and only remember sources after a successful install.
250
253
  async with runtime._mcp_install_lock:
251
254
  sources = dict.fromkeys((_package_dir(ServerBase), _package_dir(type(server))))
252
255
  pending = [source for source in sources if source not in runtime._mcp_sources]
253
- if not pending:
254
- return f"{venv}/bin/python"
255
- setup = (
256
- f"set -e; mkdir -p {root_q} {temp_q} {cache_q}; "
257
- f"export TMPDIR={temp_q} UV_CACHE_DIR={cache_q}; "
258
- 'export PATH="$HOME/.local/bin:$PATH"; '
259
- )
260
- if not runtime._mcp_sources:
261
- # Failed installs can leave the venv behind; retain it when retrying.
262
- setup += f"{_ENSURE_UV}; uv venv --allow-existing {venv_q}; "
263
- # Drain remote writes and installs before cancellation releases the lock.
264
- for source in pending:
265
- name, data = await _cached_package(Path(source))
266
- remote = f"{root}/{name}"
267
- await run_shielded(runtime.write(remote, data))
268
- setup += f"uv pip install --python {venv_q} {shlex.quote(remote)}; "
269
- result = await run_shielded(runtime.run(["sh", "-c", setup], {}))
270
- if result.exit_code != 0:
271
- raise ToolsetError(
272
- f"server {server.server_name!r} install failed in runtime: "
273
- f"{(result.stderr or result.stdout).strip()[-2000:]}"
256
+ if pending:
257
+ setup = (
258
+ f"set -e; mkdir -p {root_q} {temp_q} {cache_q}; "
259
+ f"export TMPDIR={temp_q} UV_CACHE_DIR={cache_q}; "
260
+ 'export PATH="$HOME/.local/bin:$PATH"; '
274
261
  )
275
- runtime._mcp_sources.update(pending)
262
+ if agent.user is not None:
263
+ setup += f"export UV_PYTHON_INSTALL_DIR={shlex.quote(python_dir)}; "
264
+ if not runtime._mcp_sources:
265
+ # Failed installs can leave the venv behind; retain it when retrying.
266
+ setup += f"{_ENSURE_UV}; uv venv --allow-existing {venv_q}; "
267
+ # Drain remote writes and installs before cancellation releases the lock.
268
+ for source in pending:
269
+ name, data = await _cached_package(Path(source))
270
+ remote = f"{root}/{name}"
271
+ await run_shielded(runtime.write(remote, data))
272
+ setup += f"uv pip install --python {venv_q} {shlex.quote(remote)}; "
273
+ result = await run_shielded(runtime.run(["sh", "-c", setup], {}))
274
+ if result.exit_code != 0:
275
+ raise ToolsetError(
276
+ f"server {server.server_name!r} install failed in runtime: "
277
+ f"{(result.stderr or result.stdout).strip()[-2000:]}"
278
+ )
279
+ runtime._mcp_sources.update(pending)
280
+ if agent.user is not None:
281
+ # Root's uv lives in its home; copy it into the venv, open to the agent.
282
+ python_q = shlex.quote(python_dir)
283
+ share = (
284
+ 'set -e; export PATH="$HOME/.local/bin:$PATH"; '
285
+ f'cp "$(command -v uv)" {venv_q}/bin/uv; chmod -R a+rX {venv_q}; '
286
+ f"[ ! -d {python_q} ] || chmod -R a+rX {python_q}"
287
+ )
288
+ result = await run_shielded(runtime.run(["sh", "-c", share], {}))
289
+ if result.exit_code != 0:
290
+ raise ToolsetError(
291
+ f"server {server.server_name!r} could not be shared with "
292
+ f"{agent.user!r}: {(result.stderr or result.stdout).strip()[-2000:]}"
293
+ )
276
294
  return f"{venv}/bin/python"
277
295
 
278
296
 
@@ -338,12 +356,18 @@ async def serve_in_runtime(
338
356
  command = [python, "-m", type(server).__module__]
339
357
  if runtime.type != "subprocess":
340
358
  # Providers may invoke uv after the install shell exits, so preserve its PATH.
359
+ path = "$HOME/.local/bin:$PATH"
360
+ if runtime.user is not None:
361
+ path = f"{PurePosixPath(python).parent}:{path}"
341
362
  command = [
342
363
  "sh",
343
364
  "-c",
344
- f'export PATH="$HOME/.local/bin:$PATH"; exec {shlex.join(command)}',
365
+ f'export PATH="{path}"; exec {shlex.join(command)}',
345
366
  ]
346
367
  log = f"vf_tool_{server.server_name}.log"
368
+ if runtime.user is not None:
369
+ # The agent user may not be able to write the workdir.
370
+ log = f"/tmp/vf_tool_{server.server_name}-{uuid.uuid4().hex[:8]}.log"
347
371
  await runtime.run_background(command, env, log)
348
372
  if fixed is not None:
349
373
  port = fixed
verifiers/v1/rollout.py CHANGED
@@ -59,7 +59,7 @@ _HOME_PROBE = (
59
59
  )
60
60
 
61
61
 
62
- async def agent_runtime(runtime: Runtime, user: str | None) -> Runtime:
62
+ async def resolve_agent_runtime(runtime: Runtime, user: str | None) -> Runtime:
63
63
  """The runtime the harness runs on: `runtime` itself, or a view running as `user`
64
64
  with `HOME` set to its home. `user` must exist with a home directory it can write
65
65
  (task authors ship it in the image), and the view must really run as it, so a
@@ -72,8 +72,7 @@ async def agent_runtime(runtime: Runtime, user: str | None) -> Runtime:
72
72
  raise TaskError(f"agent_user {user!r} does not exist in the image")
73
73
  if lookup.exit_code != 0:
74
74
  raise TaskError(f"agent_user {user!r} has no home directory ({home})")
75
- view = runtime.with_user(user)
76
- view = view.with_env({**view.env, "HOME": home})
75
+ view = runtime.with_user(user, home=home)
77
76
  probe = await view.run(["sh", "-c", 'id -un; test -w "$HOME" && echo writable'], {})
78
77
  effective, *rest = probe.stdout.split() or [""]
79
78
  if effective != user:
@@ -168,6 +167,7 @@ class Rollout:
168
167
  self._endpoint: str | None = None
169
168
  self._urls: dict[str, str] = {}
170
169
  self._harness_session: HarnessSession | None = None
170
+ self._agent_runtime: Runtime | None = None
171
171
  self.deadline_at: float | None = None
172
172
  """The active harness segment's absolute deadline (event-loop clock), or
173
173
  None between segments / when unbounded. An interaction spends one cumulative
@@ -279,7 +279,13 @@ class Rollout:
279
279
  asyncio.timeout_at(setup_deadline) as setup_timeout,
280
280
  boundary(HarnessError, "harness setup"),
281
281
  ):
282
- await self.harness.setup(runtime)
282
+ # The harness, its colocated tools, and its session run as the task's
283
+ # `agent_user` (just `runtime` when unset). Task setup and scoring,
284
+ # interception, and the execution policy keep the default `runtime`.
285
+ self._agent_runtime = await resolve_agent_runtime(
286
+ runtime, self.task.data.agent_user
287
+ )
288
+ await self.harness.setup(self._agent_runtime)
283
289
  async with boundary(ToolsetError, "building tool servers"):
284
290
  toolsets = self.task.toolsets(self.task.config)
285
291
  # `base_url` is the interception server's reachable URL for this rollout.
@@ -304,7 +310,7 @@ class Rollout:
304
310
  self._urls = await self._stack.enter_async_context(
305
311
  serve_tools(
306
312
  toolsets,
307
- runtime,
313
+ self._agent_runtime,
308
314
  shared=self._shared_tools,
309
315
  state_secret=state_secret,
310
316
  state_route=self.trace.id,
@@ -415,7 +421,7 @@ class Rollout:
415
421
  self._harness_session = await self.harness.session(
416
422
  self.ctx,
417
423
  self.trace,
418
- await agent_runtime(runtime, harness_data.agent_user),
424
+ self._agent_runtime,
419
425
  self._endpoint,
420
426
  self._secret,
421
427
  self._urls,
@@ -606,7 +612,7 @@ class Rollout:
606
612
  # Cross-trace judgement runs later, after the runtime is gone.
607
613
  await asyncio.gather(
608
614
  self.task.score(trace, runtime),
609
- self.harness.score(trace, runtime),
615
+ self.harness.score(trace, self._agent_runtime or runtime),
610
616
  )
611
617
  except TimeoutError:
612
618
  self.timeout("scoring")
@@ -24,8 +24,8 @@ from verifiers.v1.utils.aio import run_shielded
24
24
 
25
25
  logger = logging.getLogger(__name__)
26
26
 
27
- # Ensure `uv` is available for our PEP 723 scripts: keep one already on PATH (an image that
28
- # pre-installs it, or an earlier rollout's install on the same box); otherwise prefer pip on
27
+ # Ensure `uv` supports both script commands used below. Reuse a compatible installation;
28
+ # upgrade older binaries bundled in task images. Prefer pip on
29
29
  # Python images, then fall back to the standalone installer (curl/wget), installing curl + CA
30
30
  # certs when a bare image has no downloader. Both install paths land in ~/.local/bin, which we
31
31
  # prepend to PATH first. (Installing needs network + one of pip / curl / wget / apt-get / apk.)
@@ -40,9 +40,12 @@ _DOWNLOAD_UV = (
40
40
  )
41
41
  _ENSURE_UV = (
42
42
  'export PATH="$HOME/.local/bin:$PATH" UV_INSTALL_DIR="$HOME/.local/bin"; '
43
- "command -v uv >/dev/null 2>&1 "
44
- "|| pip install -q -U --user uv 2>/dev/null "
45
- f"|| {{ {_INSTALL_CURL}; {_DOWNLOAD_UV}; }}"
43
+ "uv_supports_scripts() { "
44
+ "uv sync --help 2>/dev/null | grep -q -- '--script' "
45
+ "&& uv python find --help 2>/dev/null | grep -q -- '--script'; }; "
46
+ "uv_supports_scripts "
47
+ "|| { pip install -q -U --user uv 2>/dev/null && hash -r && uv_supports_scripts; } "
48
+ f"|| {{ {{ {_INSTALL_CURL}; {_DOWNLOAD_UV}; }} && hash -r && uv_supports_scripts; }}"
46
49
  )
47
50
 
48
51
  # The single port a sandbox runtime forwards out for a server hosted in it: a public URL on
@@ -136,7 +139,7 @@ class BaseRuntimeInfo(BaseConfig):
136
139
 
137
140
 
138
141
  class Runtime(ABC):
139
- __slots__ = ("env", "user")
142
+ __slots__ = ("env", "home", "user")
140
143
 
141
144
  is_local: bool = True
142
145
  """Whether this runtime exchanges host-local URLs without a public tunnel. True for
@@ -164,11 +167,14 @@ class Runtime(ABC):
164
167
  self.env: dict[str, str] = {}
165
168
  self.user: str | None = None
166
169
  """Existing user this view runs commands as; None uses the runtime's default."""
170
+ self.home: str | None = None
171
+ """`HOME` for `user`'s processes; None leaves the runtime's own."""
167
172
  self._uv_interpreters: dict[str, str] = {}
168
173
  self._uv_script_locks: dict[str, asyncio.Lock] = {}
169
174
  self._mcp_sources: set[str] = set()
170
175
  self._mcp_install_lock = asyncio.Lock()
171
176
  self._setup_claimed = False
177
+ self._curl_ready = False
172
178
  self.stopped = False
173
179
  """Whether teardown has begun (set by `stop`). A stopped runtime is dead: a rollout
174
180
  refuses to borrow one — the owner tore it down, so any use is a lifetime bug in the
@@ -210,7 +216,8 @@ class Runtime(ABC):
210
216
 
211
217
  def process_env(self, env: dict[str, str]) -> dict[str, str]:
212
218
  """Combine the task's runtime-wide environment with one process's values."""
213
- return {**self.env, **env}
219
+ home = {} if self.home is None else {"HOME": self.home}
220
+ return {**self.env, **home, **env}
214
221
 
215
222
  def with_env(self, env: dict[str, str]) -> "Runtime":
216
223
  """Share this physical runtime through a view with its own process environment."""
@@ -220,10 +227,9 @@ class Runtime(ABC):
220
227
  runtime.env = dict(env)
221
228
  return runtime
222
229
 
223
- def with_user(self, user: str | None) -> "Runtime":
224
- """Share this physical runtime through a view that runs commands as `user`, an
225
- existing user in the box (None keeps the default). Only the view runs as `user`:
226
- setup, collection, and grading keep using the original runtime."""
230
+ def with_user(self, user: str | None, home: str | None = None) -> "Runtime":
231
+ """A view of this runtime whose commands and file I/O run as `user` (an existing
232
+ user in the box) with `HOME` set to `home`; None returns the default user."""
227
233
  if user is not None and not self.supports_user:
228
234
  raise ValueError(
229
235
  f"{type(self).__name__} cannot run commands as another user"
@@ -231,6 +237,7 @@ class Runtime(ABC):
231
237
  runtime = copy.copy(self)
232
238
  runtime.__dict__ = self.__dict__
233
239
  runtime.user = user
240
+ runtime.home = home if user is not None else None
234
241
  return runtime
235
242
 
236
243
  async def alive(self) -> bool:
@@ -283,10 +290,20 @@ class Runtime(ABC):
283
290
  """
284
291
  data = script.encode() if isinstance(script, str) else script
285
292
  digest = hashlib.sha256(data).hexdigest()
286
- path = f"{self.scripts_dir}/{digest}.py"
287
- if digest not in self._uv_interpreters:
288
- async with self._uv_script_locks.setdefault(digest, asyncio.Lock()):
289
- if digest not in self._uv_interpreters:
293
+ # Each user needs its own writable script dir and uv environment.
294
+ directory = (
295
+ self.scripts_dir if self.user is None else f"{self.scripts_dir}-{self.user}"
296
+ )
297
+ path = f"{directory}/{digest}.py"
298
+ if path not in self._uv_interpreters:
299
+ async with self._uv_script_locks.setdefault(path, asyncio.Lock()):
300
+ if self.user is not None and not self._curl_ready:
301
+ # Only root can install a downloader for the user's uv bootstrap.
302
+ curl = await self.with_user(None).run(
303
+ ["sh", "-c", _INSTALL_CURL], {}
304
+ )
305
+ self._curl_ready = curl.exit_code == 0
306
+ if path not in self._uv_interpreters:
290
307
  tmp = f"{path}.{uuid.uuid4().hex}.tmp"
291
308
  await self.write(tmp, data)
292
309
  command = (
@@ -305,10 +322,8 @@ class Runtime(ABC):
305
322
  "failed to prepare uv script: "
306
323
  f"{result.stderr.strip()[-2000:]}"
307
324
  )
308
- self._uv_interpreters[digest] = result.stdout.strip().splitlines()[
309
- -1
310
- ]
311
- interpreter = self._uv_interpreters[digest]
325
+ self._uv_interpreters[path] = result.stdout.strip().splitlines()[-1]
326
+ interpreter = self._uv_interpreters[path]
312
327
  if not activate:
313
328
  return [interpreter, path]
314
329
  venv = str(PurePosixPath(interpreter).parent.parent)
@@ -7,6 +7,7 @@ import logging
7
7
  import math
8
8
  import shlex
9
9
  import tempfile
10
+ import uuid
10
11
  from collections.abc import AsyncIterator
11
12
  from dataclasses import dataclass
12
13
  from pathlib import Path, PurePosixPath
@@ -374,13 +375,15 @@ class PrimeRuntime(Runtime):
374
375
  raise SandboxError(f"prime background launch failed: {e}") from e
375
376
 
376
377
  async def _read(self, path: str, max_bytes: int | None = None) -> bytes:
377
- if max_bytes is not None:
378
+ # The file API acts as the default user; a user view reads through exec.
379
+ if max_bytes is not None or self.user is not None:
380
+ reader = "cat" if max_bytes is None else f"head -c {max_bytes}"
378
381
  try:
379
382
  # Stream binary output: execute_command buffers base64 text for the
380
383
  # entire file. Bound the source read and the host buffer independently.
381
384
  process = await self._client.open_process(
382
385
  self.info.id,
383
- f"head -c {max_bytes} -- {shlex.quote(path)}",
386
+ f"{reader} -- {shlex.quote(path)}",
384
387
  working_dir=self.config.workdir,
385
388
  env=self.process_env({}),
386
389
  user=self.user,
@@ -388,7 +391,10 @@ class PrimeRuntime(Runtime):
388
391
  async with contextlib.aclosing(process):
389
392
  with io.BytesIO() as data:
390
393
  async for chunk in process.stdout:
391
- if data.tell() + len(chunk) > max_bytes:
394
+ if (
395
+ max_bytes is not None
396
+ and data.tell() + len(chunk) > max_bytes
397
+ ):
392
398
  raise SandboxError(
393
399
  "read stream exceeded its byte limit"
394
400
  )
@@ -424,12 +430,26 @@ class PrimeRuntime(Runtime):
424
430
  if path.startswith("/")
425
431
  else f"{self.config.workdir.rstrip('/')}/{path}"
426
432
  )
433
+ if self.user is None:
434
+ try:
435
+ await self._client.upload_bytes(
436
+ self.info.id, target, data, filename=PurePosixPath(target).name
437
+ )
438
+ except Exception as e:
439
+ raise SandboxError(f"write {path!r}: {e}") from e
440
+ return
441
+ # Uploads act as the default user: stage the bytes, then copy them in as the user.
442
+ root = self.with_user(None)
443
+ staged = f"/tmp/vf-write-{uuid.uuid4().hex}"
427
444
  try:
428
- await self._client.upload_bytes(
429
- self.info.id, target, data, filename=PurePosixPath(target).name
430
- )
431
- except Exception as e:
432
- raise SandboxError(f"write {path!r}: {e}") from e
445
+ await root.write(staged, data)
446
+ await root.run(["chmod", "644", staged], {})
447
+ copy = 'mkdir -p "$(dirname "$1")" && cat -- "$2" > "$1"'
448
+ result = await self.run(["sh", "-c", copy, "sh", target, staged], {})
449
+ finally:
450
+ await root.run(["rm", "-f", staged], {})
451
+ if result.exit_code != 0:
452
+ raise SandboxError(f"write {path!r}: {result.stderr.strip()[-500:]}")
433
453
 
434
454
  def cleanup(self) -> None:
435
455
  # Synchronous atexit backstop (the async client can't run once the loop is gone): delete
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: verifiers
3
- Version: 0.3.2.dev207
3
+ Version: 0.3.2.dev209
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
@@ -7,7 +7,7 @@ verifiers/v1/errors.py,sha256=nNabzi55J5aHmAmW9UHZVpI7kcBfy4Xcyt4cQthZbM8,5875
7
7
  verifiers/v1/graph.py,sha256=LW0pJRxCCOXZa2KwB0edHIIqmRrzLFBDNyEeOFVskl8,41502
8
8
  verifiers/v1/harness.py,sha256=4hnAh7tjiXfXoEYAzn8XhHy8sJ3PhZ0Tti5VqwxUQDs,16251
9
9
  verifiers/v1/judge.py,sha256=uq9Ddm_le_m-YIMO8AyLr4AbuQicnZamfenzsiXc95c,10466
10
- verifiers/v1/rollout.py,sha256=kYJMreIYzhyZicogMyvltqsdJqK9vQsc2EbK_FidWxA,29647
10
+ verifiers/v1/rollout.py,sha256=Az7nXs66Av4SuNkloDAQkz6V9v9iys63nm3h6N2Z2uI,30072
11
11
  verifiers/v1/semantic.py,sha256=tX8FYEceuMYauuB3Bc8jLDMS2eR06JjLjTo66R190Fg,4053
12
12
  verifiers/v1/session.py,sha256=p3Rm0MU-6fPsJLjQcIMg-NOIV-8_tsqcXNTftJ94brY,28555
13
13
  verifiers/v1/state.py,sha256=EckF2bWp-vV4b1jYJ9sLI5xrfGuI5spIgYYwW926toI,595
@@ -120,7 +120,7 @@ verifiers/v1/harnesses/terminus_2/program.py,sha256=X8MZdyItU3gbXGXnGOlJ9LWcUTnq
120
120
  verifiers/v1/harnesses/utils/__init__.py,sha256=eTS-Ft2HwoLiYn5u1t_KueLmaZB_W12cdYmcVsE-G5A,364
121
121
  verifiers/v1/harnesses/utils/compaction.py,sha256=DeY6CYLEsv7-vJm26sT2mRaPHu3W2ywiZhvFr_pi6Hg,10495
122
122
  verifiers/v1/harnesses/utils/core.py,sha256=29Usc55cbLQE0vA8y05yk06sbjJMwYjOo2TmdwjPLE8,20397
123
- verifiers/v1/harnesses/utils/install.py,sha256=BDkkUVZ1brSzCrbQOvMO5mVIE2DsV2pE7rTC5yROYUw,2992
123
+ verifiers/v1/harnesses/utils/install.py,sha256=20YFtGZ9cNViHffeI11OJrhJ6_y49gPEHIhs9VUn2FY,3458
124
124
  verifiers/v1/harnesses/utils/launch.py,sha256=Kg6x4Fl5y48pSgPiupSBj5ehQkkupk5vihUUvHtpcO8,2894
125
125
  verifiers/v1/harnesses/utils/mcp.py,sha256=EtDraHEqgsOB6xKvcF2z9C6HlQyKoST0ZDvmy47NWgM,7450
126
126
  verifiers/v1/interception/__init__.py,sha256=5Kvo7tcBUVaa65s9A1NiOH3CPpzw-P5btXwxB4Nbbvs,4251
@@ -138,17 +138,17 @@ verifiers/v1/judges/reference.txt,sha256=Ej35kGXiT2uJ0LcHIeez49rCS_9uHmCQKoVdn93
138
138
  verifiers/v1/judges/rubric.py,sha256=HGQYI3xdq8I84Ce0_sDeNgk5JM597es8rOVPipjCyxU,12025
139
139
  verifiers/v1/judges/rubric.txt,sha256=3KA2ZeYYdcDweJhUGopxu9EFgARhu2aWft5S5cj8Bc8,323
140
140
  verifiers/v1/mcp/__init__.py,sha256=pm8ZWBiL1q1tY4wHvJzM_QrZ9oR8aGm-bIRWiRJsgHI,408
141
- verifiers/v1/mcp/launch.py,sha256=r2j1hxMCZtOOjbOFBCZpt1_Zpo56e83HFMg_4sB_kA4,25916
141
+ verifiers/v1/mcp/launch.py,sha256=a_hlziAC5L9I10fXqigGC1d32hBqbA6oSEuupp6mlZY,27319
142
142
  verifiers/v1/mcp/server.py,sha256=Jqi8OMT8DnoZegXqM3UNNRzhVnbdrPEwx0DjOJo_K2A,13256
143
143
  verifiers/v1/mcp/toolset.py,sha256=G2wzNdEMGLXoQUcrwF0TartJkqokNPI3o7YUOAaaa6U,1007
144
144
  verifiers/v1/runtimes/__init__.py,sha256=zOG9BYsK19VRNqvggqh3f6g1_UGIq7VjIBcK8kDlmnQ,3515
145
145
  verifiers/v1/runtimes/apptainer.py,sha256=Ru9QJna_l0goIzg71G-4RU_D-7wZUNz139S5TEvbzog,8211
146
- verifiers/v1/runtimes/base.py,sha256=2ShKZypScklVl9r0ZgN9LjdZB1e471plTxLyHg7-Tyo,19035
146
+ verifiers/v1/runtimes/base.py,sha256=5tRDqGGnYvpy2qDa-V6K5EuwLKjEeI9U4gZV_8TJQZE,19947
147
147
  verifiers/v1/runtimes/container.py,sha256=_hNhGOo1Zvorj7THSj2UrZTkgewySUVJe4Kd777-QnI,12563
148
148
  verifiers/v1/runtimes/e2b.py,sha256=yBeocAutsv2l5x-C5IMqrlgBz6Cb-t6vWbX4qTjlztE,30306
149
149
  verifiers/v1/runtimes/limiters.py,sha256=rOfQJcMdYcLSKq8AL9O09BfGOLqpYmNgrCxXXNcHLmU,2849
150
150
  verifiers/v1/runtimes/modal.py,sha256=ZHA4vtNIZwTV-bnVUlambgc8l34j_ZulvtrwvvkE2Kg,17945
151
- verifiers/v1/runtimes/prime.py,sha256=hGjkR8KsBy1OiUeJwcgmN8-twKnCVKk5IkUvm3-eWbs,19827
151
+ verifiers/v1/runtimes/prime.py,sha256=EzKfjtBIfH8ehjrvOI4khm6BIEZ87r84B5gmgFJQvU4,20836
152
152
  verifiers/v1/runtimes/subprocess.py,sha256=vnGVAI3J7pYmRei4MQ7MN4nb8SglLi70NtVTINMPVvQ,8855
153
153
  verifiers/v1/runtimes/docker/__init__.py,sha256=QoFOTMgRjoWD--O25Jsft9eD2vjcrMpJQyhfQXqWraI,21828
154
154
  verifiers/v1/runtimes/docker/egress.py,sha256=wtKWTL2_zFidxMR7lDRmfevQlOsl2Iyk88ebdO4Kqqw,24566
@@ -196,8 +196,8 @@ verifiers/v1/utils/scope.py,sha256=bzUEiWDOVdbj7dXOwGOlzsQ_-Xu0j9NR5TalQB-8TS8,8
196
196
  verifiers/v1/utils/score.py,sha256=493yJVMw8teCu9JxapxMFPFzI0hNUqdo0Y2nGW4kckk,6200
197
197
  verifiers/v1/utils/trace_store.py,sha256=RsCDonGR-bs-tvEstcppiJm3jFmAdIiG83fA5KtCbAw,2801
198
198
  verifiers/v1/utils/version.py,sha256=-obEo_-l9-D8FLef4hYxncOe-uJpxrM1g2Hig_37Sgs,1607
199
- verifiers-0.3.2.dev207.dist-info/METADATA,sha256=q2UCf3W6Qsdb08TKVBhfuBuRjK1YXa54Ubfz-GDSpDk,4228
200
- verifiers-0.3.2.dev207.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
201
- verifiers-0.3.2.dev207.dist-info/entry_points.txt,sha256=iugElcdWPKbQM7uFF0lZ8iUpHsNr17-BwEAAjJWxV3U,259
202
- verifiers-0.3.2.dev207.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
203
- verifiers-0.3.2.dev207.dist-info/RECORD,,
199
+ verifiers-0.3.2.dev209.dist-info/METADATA,sha256=xpcOGyiLj_NTlSRM6TSHVPHgJwfDRzRQZrgvuR3PwuA,4228
200
+ verifiers-0.3.2.dev209.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
201
+ verifiers-0.3.2.dev209.dist-info/entry_points.txt,sha256=iugElcdWPKbQM7uFF0lZ8iUpHsNr17-BwEAAjJWxV3U,259
202
+ verifiers-0.3.2.dev209.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
203
+ verifiers-0.3.2.dev209.dist-info/RECORD,,