verifiers 0.3.2.dev208__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")
@@ -139,7 +139,7 @@ class BaseRuntimeInfo(BaseConfig):
139
139
 
140
140
 
141
141
  class Runtime(ABC):
142
- __slots__ = ("env", "user")
142
+ __slots__ = ("env", "home", "user")
143
143
 
144
144
  is_local: bool = True
145
145
  """Whether this runtime exchanges host-local URLs without a public tunnel. True for
@@ -167,11 +167,14 @@ class Runtime(ABC):
167
167
  self.env: dict[str, str] = {}
168
168
  self.user: str | None = None
169
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."""
170
172
  self._uv_interpreters: dict[str, str] = {}
171
173
  self._uv_script_locks: dict[str, asyncio.Lock] = {}
172
174
  self._mcp_sources: set[str] = set()
173
175
  self._mcp_install_lock = asyncio.Lock()
174
176
  self._setup_claimed = False
177
+ self._curl_ready = False
175
178
  self.stopped = False
176
179
  """Whether teardown has begun (set by `stop`). A stopped runtime is dead: a rollout
177
180
  refuses to borrow one — the owner tore it down, so any use is a lifetime bug in the
@@ -213,7 +216,8 @@ class Runtime(ABC):
213
216
 
214
217
  def process_env(self, env: dict[str, str]) -> dict[str, str]:
215
218
  """Combine the task's runtime-wide environment with one process's values."""
216
- return {**self.env, **env}
219
+ home = {} if self.home is None else {"HOME": self.home}
220
+ return {**self.env, **home, **env}
217
221
 
218
222
  def with_env(self, env: dict[str, str]) -> "Runtime":
219
223
  """Share this physical runtime through a view with its own process environment."""
@@ -223,10 +227,9 @@ class Runtime(ABC):
223
227
  runtime.env = dict(env)
224
228
  return runtime
225
229
 
226
- def with_user(self, user: str | None) -> "Runtime":
227
- """Share this physical runtime through a view that runs commands as `user`, an
228
- existing user in the box (None keeps the default). Only the view runs as `user`:
229
- 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."""
230
233
  if user is not None and not self.supports_user:
231
234
  raise ValueError(
232
235
  f"{type(self).__name__} cannot run commands as another user"
@@ -234,6 +237,7 @@ class Runtime(ABC):
234
237
  runtime = copy.copy(self)
235
238
  runtime.__dict__ = self.__dict__
236
239
  runtime.user = user
240
+ runtime.home = home if user is not None else None
237
241
  return runtime
238
242
 
239
243
  async def alive(self) -> bool:
@@ -286,10 +290,20 @@ class Runtime(ABC):
286
290
  """
287
291
  data = script.encode() if isinstance(script, str) else script
288
292
  digest = hashlib.sha256(data).hexdigest()
289
- path = f"{self.scripts_dir}/{digest}.py"
290
- if digest not in self._uv_interpreters:
291
- async with self._uv_script_locks.setdefault(digest, asyncio.Lock()):
292
- 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:
293
307
  tmp = f"{path}.{uuid.uuid4().hex}.tmp"
294
308
  await self.write(tmp, data)
295
309
  command = (
@@ -308,10 +322,8 @@ class Runtime(ABC):
308
322
  "failed to prepare uv script: "
309
323
  f"{result.stderr.strip()[-2000:]}"
310
324
  )
311
- self._uv_interpreters[digest] = result.stdout.strip().splitlines()[
312
- -1
313
- ]
314
- interpreter = self._uv_interpreters[digest]
325
+ self._uv_interpreters[path] = result.stdout.strip().splitlines()[-1]
326
+ interpreter = self._uv_interpreters[path]
315
327
  if not activate:
316
328
  return [interpreter, path]
317
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.dev208
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=8t_cYcJaps3zeCrUyFLQgisJljTd0vp0gL-ZwF0Iqok,19233
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.dev208.dist-info/METADATA,sha256=-39HRF8OYwWEEeAQQnPQ3eObdXV3Dqv6PE-9gz-1ATo,4228
200
- verifiers-0.3.2.dev208.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
201
- verifiers-0.3.2.dev208.dist-info/entry_points.txt,sha256=iugElcdWPKbQM7uFF0lZ8iUpHsNr17-BwEAAjJWxV3U,259
202
- verifiers-0.3.2.dev208.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
203
- verifiers-0.3.2.dev208.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,,