verifiers 0.4.2.dev45__py3-none-any.whl → 0.4.2.dev46__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.
@@ -43,16 +43,8 @@ logger = get_logger(__name__)
43
43
  EFFECTIVELY_UNBOUNDED_SECONDS = 30 * 24 * 60 * 60
44
44
  """Safety deadline for APIs that require a finite bound. Normal execution remains
45
45
  bounded by idle detection or rollout cancellation; 30 days is above any real run."""
46
- # The SDK reads finished jobs' output through a bounded pool whose deadline includes time
47
- # spent queued; its defaults (20 reads, 45s) expire most reads when thousands of rollouts
48
- # finish a job at once (e.g. every harness's setup at a 3k-rollout start).
49
- _OUTPUT_READS = 100
50
- """Concurrent output reads on the shared client."""
51
- _OUTPUT_DEADLINE_SECONDS = 300
52
- """Deadline for one read of a finished job's output, queue time included."""
53
- _OUTPUT_RETRIES = 10
54
- """Re-reads of a finished job's output that the SDK still failed to fetch, before the
55
- exec is reported as failed."""
46
+ _OUTPUT_TAIL_BYTES = 10 * 1024 * 1024
47
+ """Maximum retained bytes per command output stream."""
56
48
  _PUBLIC_DOMAIN = "sandbox-v2-prod.pinfra.io"
57
49
  """Domain of the public URLs `https://<port>-<sandbox-id>.<domain>` that a LAN network's
58
50
  `internet` rule publishes ports at."""
@@ -69,8 +61,8 @@ class _SharedClient:
69
61
 
70
62
 
71
63
  # One `AsyncSandboxClient` per event loop, leased by every live runtime on it. The SDK
72
- # coalesces concurrent status polls per client into batched requests (up to 100 ids
73
- # each), so sharing a client turns N runtimes' creation/job polls into a few batch
64
+ # coalesces concurrent creation polls per client into batched requests (up to 100 ids
65
+ # each), so sharing a client turns N runtimes' creation polls into a few batch
74
66
  # calls. Keyed by loop (not plain process-global) so a client's tasks stay on the loop
75
67
  # that created it.
76
68
  _shared_clients: dict[asyncio.AbstractEventLoop, _SharedClient] = {}
@@ -82,9 +74,7 @@ def _lease_client() -> Any:
82
74
  loop = asyncio.get_running_loop()
83
75
  shared = _shared_clients.get(loop)
84
76
  if shared is None:
85
- shared = _shared_clients[loop] = _SharedClient(
86
- AsyncSandboxClient(background_job_output_concurrency=_OUTPUT_READS)
87
- )
77
+ shared = _shared_clients[loop] = _SharedClient(AsyncSandboxClient())
88
78
  shared.leases += 1
89
79
  return shared.client
90
80
 
@@ -339,46 +329,39 @@ class PrimeBackend(RuntimeBackend):
339
329
  async def run(
340
330
  self, runtime: Runtime, argv: list[str], env: dict[str, str]
341
331
  ) -> ProgramResult:
332
+ async def collect(stream: AsyncIterator[bytes]) -> bytes:
333
+ tail = bytearray()
334
+ async for chunk in stream:
335
+ tail.extend(chunk[-_OUTPUT_TAIL_BYTES:])
336
+ del tail[:-_OUTPUT_TAIL_BYTES]
337
+ return bytes(tail)
338
+
342
339
  try:
343
- # Poll directly so rollout cancellation owns the execution timeout.
344
- job = await self._client.start_background_job(
340
+ # Command sessions survive task cleanup of shared scratch directories.
341
+ # Close stdin explicitly: the live-process API keeps it open by default.
342
+ process = await self._client.open_process(
345
343
  self.info.id,
346
- shlex.join(argv),
344
+ "exec "
345
+ + shlex.join(["sh", "-c", 'exec "$@" < /dev/null', "sh", *argv]),
347
346
  working_dir=self.config.workdir,
348
347
  env=runtime.process_env(env),
349
348
  user=runtime.user,
350
349
  )
351
- delay = 0.1
352
- output_retries = 0
353
- missing = None
354
- while True:
355
- result = await self._client.get_background_job(
356
- self.info.id, job, timeout=_OUTPUT_DEADLINE_SECONDS
350
+ try:
351
+ stdout, stderr, exit_code = await asyncio.gather(
352
+ collect(process.stdout), collect(process.stderr), process.wait()
357
353
  )
358
- # Under load the SDK can see a job finish yet miss its output (its bounded
359
- # output reads expire while queued) and reports that as `*_error`. The job
360
- # is done, so asking again re-reads the output.
361
- missing = result.stdout_error or result.stderr_error
362
- if result.completed and (
363
- missing is None or output_retries == _OUTPUT_RETRIES
364
- ):
365
- break
366
- if result.completed:
367
- output_retries += 1
368
- await asyncio.sleep(delay)
369
- delay = min(delay * 2, 3)
354
+ finally:
355
+ # Closing signals and reaps a running process, then releases its stream.
356
+ await run_shielded(process.aclose())
370
357
  except (
371
358
  Exception
372
359
  ) as e: # a sandbox/API failure is one rollout's problem, not the eval's
373
360
  raise SandboxError(f"prime exec failed: {e}") from e
374
- if missing is not None:
375
- raise SandboxError(f"prime exec output unavailable: {missing}")
376
- if result.exit_code is None:
377
- raise SandboxError("prime exec completed without an exit code")
378
361
  return ProgramResult(
379
- exit_code=result.exit_code,
380
- stdout=result.stdout or "",
381
- stderr=result.stderr or "",
362
+ exit_code=exit_code,
363
+ stdout=stdout.decode(errors="replace"),
364
+ stderr=stderr.decode(errors="replace"),
382
365
  )
383
366
 
384
367
  async def exec(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: verifiers
3
- Version: 0.4.2.dev45
3
+ Version: 0.4.2.dev46
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
@@ -149,7 +149,7 @@ verifiers/v1/runtimes/runtime.py,sha256=-CvhH42y0F0dPeNgDRVBeajkRK_vZYp2qxKY1XVf
149
149
  verifiers/v1/runtimes/strategies.py,sha256=WtIrIpKmvjvqpUfwLUwDNJcgRLE8d-2sx7reks2S2PA,8765
150
150
  verifiers/v1/runtimes/backends/custom.py,sha256=Iz1Brd4dBTpO1zYVc2KA0u5sxz5ZUROY_Cdme5W33hM,2875
151
151
  verifiers/v1/runtimes/backends/docker.py,sha256=uOjmENxhdQ9GPrvtQCXi1-6TL3fSRcflg6sENBOTM-w,31591
152
- verifiers/v1/runtimes/backends/prime.py,sha256=qTTIrmMbEluKIwHQ4kwRnKXn6RIT-P3mZtkxgh_wJ-4,24758
152
+ verifiers/v1/runtimes/backends/prime.py,sha256=vMD3d1JxyKWO5Zbd1c0DJ2I4DjdIFhi4XlgYabd1v4A,23884
153
153
  verifiers/v1/runtimes/backends/subprocess.py,sha256=naOWJGmcaOlu2ZdRbUwhJicJdxASDRAUhDT0jzDff3w,8591
154
154
  verifiers/v1/tasksets/__init__.py,sha256=2ijE3qIlLoUA02g6iysOwWQylyBBQL1GhSpjv8_bp0w,521
155
155
  verifiers/v1/tasksets/harbor/__init__.py,sha256=FjW4tM3rgGALMK-8p7ux26G4-d4ZFVmaAmO6Fni6e_g,214
@@ -187,8 +187,8 @@ verifiers/v1/utils/scope.py,sha256=zbs4pj6AVk4jywlAJ3AX0Q0_kzB9dBB02nY-9H4ELdQ,8
187
187
  verifiers/v1/utils/score.py,sha256=493yJVMw8teCu9JxapxMFPFzI0hNUqdo0Y2nGW4kckk,6200
188
188
  verifiers/v1/utils/trace_store.py,sha256=Qo9qvsJAl8PoRUavjQAfUB2VNxmUtYQtU2ejLKPzY9c,3382
189
189
  verifiers/v1/utils/version.py,sha256=-obEo_-l9-D8FLef4hYxncOe-uJpxrM1g2Hig_37Sgs,1607
190
- verifiers-0.4.2.dev45.dist-info/METADATA,sha256=wZz6cLSWz0rOYnRlEYL5sc7bBKaNpS6VzjnSaS6RXTk,5115
191
- verifiers-0.4.2.dev45.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
192
- verifiers-0.4.2.dev45.dist-info/entry_points.txt,sha256=qdMg7ajiFpDsHf7tuPMRclJXizu1J6LTWawS5YS0B0I,137
193
- verifiers-0.4.2.dev45.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
194
- verifiers-0.4.2.dev45.dist-info/RECORD,,
190
+ verifiers-0.4.2.dev46.dist-info/METADATA,sha256=OTP5cYrKTTt2rIGIAZceZC14T36z-qgm_1MPcs2bVok,5115
191
+ verifiers-0.4.2.dev46.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
192
+ verifiers-0.4.2.dev46.dist-info/entry_points.txt,sha256=qdMg7ajiFpDsHf7tuPMRclJXizu1J6LTWawS5YS0B0I,137
193
+ verifiers-0.4.2.dev46.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
194
+ verifiers-0.4.2.dev46.dist-info/RECORD,,