Skip to content

perf: encode json with orjson in prime-runs and prime-traces - #1109

Merged
mikasenghaas merged 3 commits into
mainfrom
perf/orjson
Oct 27, 2026
Merged

mikasenghaas merged 3 commits into
mainfrom
perf/orjson

Conversation

@mikasenghaas

@mikasenghaas mikasenghaas commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Summary

  • prime-traces: _encode_record writes trace lines with orjson, using OPT_SERIALIZE_NUMPY | OPT_NON_STR_KEYS | OPT_APPEND_NEWLINE.
    • Records may hold C-contiguous numpy arrays, so the caller does not copy them into lists first.
  • prime-runs: encode_json (request bodies and sample batches) and the Parquet JSON columns use orjson.
    • Both accept numpy arrays. The training viewer's info column embeds the episode record.
  • Add orjson>=3.10.0 to both packages. prime-rl already depends on it. verifiers adds it in perf: keep record streams as numpy arrays verifiers#2980.
  • Scope: the record encode path in prime-runs and prime-traces only. Small payloads (the config file read, the upload metadata part) and the other packages keep the stdlib json.

Why: today to_record() builds a Python list for every per-token stream, and the stdlib encodes each element. That takes 114.7 ms per real training episode. PrimeIntellect-ai/verifiers#2980 makes to_record() return the streams as numpy arrays, which the stdlib encoder cannot write. With this change, orjson writes them in one pass, and verifiers and prime-rl keep passing the episodes as they are.

Breaking

  • NaN and ±Infinity in trace records and request bodies now go out as null. Before, they raised ValueError before the request. orjson has no allow_nan=False.
    • The sample projections already wrote these values as null. Trace records and request bodies now do the same.
    • test_records_reject_nonfinite_json_instead_of_sending_an_opaque_400 is now test_records_send_nonfinite_floats_as_null_instead_of_an_opaque_400 and checks for null.
  • Some floats encode to different bytes, for example 1e-05 becomes 0.00001. The same records can therefore get a different content-addressed upload ID than with an older SDK.
  • Integers over 64 bits raise TypeError during encoding. The stdlib encoder wrote them.

Verification

Real data: 512 training episodes, each passed as is to _encode_record(stamp_run(to_mapping(episode), ...)), as prime-rl does.

Per episode Before After
Trace line encode 114.7 ms 12.2 ms
  • Before: verifiers main and the released SDK (prime-runs 0.1.4, prime-traces 0.0.10). to_record() builds Python lists, and the stdlib encodes them.
  • After: perf: keep record streams as numpy arrays verifiers#2980 and this branch. to_record() keeps the streams as numpy arrays, and orjson writes them.
  • Both runs produce the same content: the sha256 over each line parsed and re-encoded with sorted keys matches. Total size is 1,980 MB in both runs.
  • prime-runs (all extras, with numpy): 300 passed. prime-traces: 183 passed.
  • New test: the viewer table encodes an episode whose record holds a numpy stream. It fails without this change (TypeError: Type is not JSON serializable: numpy.ndarray).

🤖 Generated with Claude Code


Note

Medium Risk
Breaking serialization semantics (non-finite floats, float formatting, large integers) affect upload idempotency keys and API payloads; otherwise limited to encode paths with broad downstream impact on training/eval uploads.

Overview
prime-traces and prime-runs now serialize hot JSON paths with orjson (>=3.10.0) instead of the stdlib json module, using OPT_SERIALIZE_NUMPY and OPT_NON_STR_KEYS so episode/trace records can include numpy arrays without a list copy first.

Trace JSONL encoding (_encode_record), HTTP bodies (encode_json), and Parquet JSON columns (_json_column) all go through orjson. Upload metadata and other small payloads still use stdlib json.

Behavior changes: non-finite floats are emitted as JSON null (flush no longer raises ValueError on NaN). Some numeric literals may encode differently, so content-addressed trace upload IDs can change vs older SDKs. Integers wider than 64 bits now fail at encode time with TypeError.

Tests were updated for NaN→null on eval samples and a new Parquet test covers numpy token_ids in embedded episode records.

Reviewed by Cursor Bugbot for commit 7dbeaaf. Bugbot is set up for automated code reviews on this repo. Configure here.

Trace records, sample batches and request bodies now go through orjson
instead of the stdlib encoder. Records may hold numpy arrays, so a
caller like verifiers can hand over its per-token streams without first
copying them into Python lists.

orjson has no allow_nan=False: NaN and infinity now go out as null
instead of raising. The sample projections already nulled them; trace
records and request bodies now match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-25T19:21:57.448912Z 1df533b PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1df533bee2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1df533b. Configure here.

Episode.to_record() returns its per-token streams as numpy arrays, and
the training viewer table embeds the record in the info column.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The config file read, the upload metadata part and the tests' decoding
handle small payloads, where orjson gains nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mikasenghaas
mikasenghaas merged commit adf8d25 into main Oct 27, 2026
27 checks passed
@mikasenghaas
mikasenghaas deleted the perf/orjson branch October 27, 2026 15:46
mikasenghaas added a commit to PrimeIntellect-ai/verifiers that referenced this pull request Oct 27, 2026
…prime#1109

The SDK encodes the numpy record streams with orjson from #1109 on. TODO: replace the git pin
with the PyPI release asap and raise the prime-runs minimum to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mikasenghaas added a commit to PrimeIntellect-ai/prime-rl that referenced this pull request Oct 27, 2026
…ime main

Verifiers moves to verifiers#2980 merged with verifiers main (4ae941f9c). prime-runs and
prime-traces come from prime main at PrimeIntellect-ai/prime#1109's merge commit until a release has
it. TODO: replace the git pins with the PyPI release asap and raise the prime-runs minimum.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mikasenghaas added a commit to PrimeIntellect-ai/verifiers that referenced this pull request Oct 27, 2026
## Summary

- `Episode.to_record()` and `Trace.to_record()` return the per-token
node streams as C-contiguous numpy arrays. That covers `token_ids`,
`mask`, `is_content`, the rounded float streams and `loss_weights`.
  - Floats are float64, and the rounded streams use `np.round`.
  - orjson with `OPT_SERIALIZE_NUMPY` writes each stream in one pass.
- Before, each stream became a Python list, each float went through
`round()`, and pydantic serialized every element.
- `to_record()` dumps the model without the streams, then adds them as
arrays. Pydantic's JSON mode cannot emit numpy arrays, and its own
encoder (`model_dump_json`) is 3.5x slower on real episodes (see
Verification).
  - The streams now come last in each node record.
- Add `Episode.to_json()` and `Trace.to_json()`: `to_record()` encoded
with orjson, as compact UTF-8 bytes. The pair mirrors pydantic's
`model_dump`/`model_dump_json`, which stay unchanged.
- `to_record()` and `to_json()` take `exclude`, a pydantic exclude spec
merged with the record's own excludes. The per-token streams are always
included.
- JSON-mode dumps (`model_dump(mode="json")`, `model_dump_json`) round
with `np.round` instead of a per-value `round()`. The output is the
same.
- The agentic and best-of-n judge envs write the trace file with
`to_json(exclude=...)`, which drops `ok` and the hidden reasoning
fields. Before, they edited the record dict. Add `orjson` as a
dependency.
- `vf-eval --push` keeps passing the episodes to the prime SDK. The SDK
encodes them with orjson from PrimeIntellect-ai/prime#1109 on.

prime-rl counterpart: PrimeIntellect-ai/prime-rl#4257. In a replayed
batch with PrimeIntellect-ai/prime#1109, the ship under monitor
contention drops from 1016 s to 114 s.

**Pinned until release:** PrimeIntellect-ai/prime#1109 is merged but not
released yet, so `prime-runs` (and `prime-traces` through
`override-dependencies`) are pinned to its merge commit on prime main
(`adf8d25`), with a TODO to replace them with the PyPI release asap and
raise the `prime-runs` minimum. The pins only apply to this repo's lock;
consumers need the release.

## Breaking

- `to_record()` node streams are numpy arrays, not lists.
`json.dumps(record)` with the stdlib `json` raises `TypeError`.
  - Migration: encode with orjson and `OPT_SERIALIZE_NUMPY`.
- Prime SDK releases before PrimeIntellect-ai/prime#1109 cannot encode
`to_record()`, so their uploads fail with `TypeError`.
  - Migration: upgrade `prime-runs`.

## Verification

Real data: one 2,048-episode training batch with 193M tokens. Each step
below ran single-threaded over the whole batch.

| Per batch | Before | After |
|---|---|---|
| `to_record()` + orjson (trace-file write) | 103.3 s (50.4 ms/episode)
| 18.1 s (8.8 ms/episode) |

A second check ran on 256 episodes of the same batch:

| Per episode | Time |
|---|---|
| `to_record()` + orjson (this branch) | 13.1 ms |
| `model_dump_json` with the same excludes | 47.9 ms |
| `model_dump(mode="json")` + orjson | 46.3 ms |

- All three paths produce the same parsed content for each episode.
- New tests:
- the record arrays and `to_json()` have the content of the plain JSON
dump, for traces and episodes, with and without rounding;
- `exclude` merges with the record's own excludes and keeps the streams;
  - `round_stream` matches `round()` on 100k float32 values.
- The judges' trace files parse to the same content as the old
edit-then-encode path, for 32 real episodes.
- `tests/unit`: all passed (Docker, `PRIME_API_KEY` and harbor tests
skipped).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes the trace/episode serialization contract (NumPy in records,
bytes from `to_json`) and pins Prime packages from git, which affects
eval uploads and any code that assumed list-shaped streams or stdlib
JSON.
> 
> **Overview**
> **Trace and episode JSON records** now attach per-token fields
(`token_ids`, `mask`, `is_content`, float training streams,
`loss_weights`) as **NumPy arrays** instead of Python lists.
`to_record()` dumps the model without those streams, then merges them
via `add_record_streams` / `MessageNode.record_streams`; float streams
use **`np.round`** (`round_stream`) at the configured precision.
> 
> Adds **`Trace.to_json()`** and **`Episode.to_json()`** — compact UTF-8
bytes from `orjson` with `OPT_SERIALIZE_NUMPY`. Both `to_record` and
`to_json` accept an optional **`exclude`** merged with
`RECORD_DUMP_EXCLUDE` via **`merge_exclude`** (judge envs use this to
drop `ok` and hidden reasoning instead of mutating dicts).
> 
> **Dependencies:** runtime **`orjson`**, and temporary **git pins** for
`prime-runs` / `prime-traces` until a PyPI release ships
prime#1109-compatible encoding.
> 
> **Breaking:** `to_record()` dicts are no longer `json.dumps`-safe;
callers must use `to_json` or orjson with NumPy support.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
4ae941f. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

<!-- Macroscope's pull request summary starts here -->
<!-- Macroscope will only edit the content between these invisible
markers, and the markers themselves will not be visible in the GitHub
rendered markdown. -->
<!-- If you delete either of the start / end markers from your PR's
description, Macroscope will append its summary at the bottom of the
description. -->
> [!NOTE]
> ### Keep record streams as NumPy arrays and encode records with orjson
> - `Trace.to_record` and `Episode.to_record` now attach node streams
(token IDs, mask, content flags, rounded float streams, loss weights) as
NumPy arrays, with float streams rounded per `float_decimals` via
`round_stream` in
[graph.py](https://github.com/PrimeIntellect-ai/verifiers/pull/2980/files#diff-64c9d635eb215902a512c9e8ab316fd9b9967c36db03d4049aacc812cdfbd740)
> - `Trace.to_json` and `Episode.to_json` encode records with orjson's
NumPy option; NaN and infinity become `null`
> - `to_record` accepts an `exclude` argument merged with built-in
record exclusions via `merge_exclude` in
[trace.py](https://github.com/PrimeIntellect-ai/verifiers/pull/2980/files#diff-834820c3aa80d87ee1c1c57fb54c74f09c66ac727036d964e6005c8613c00b5e);
`JudgeTask.from_trace` and `RankTask.record` now use `Trace.to_json`
with exclusions instead of mutating records and using stdlib JSON
> - Adds `orjson>=3.10.0` as a dependency in
[pyproject.toml](https://github.com/PrimeIntellect-ai/verifiers/pull/2980/files#diff-50c86b7ed8ac2cf95bd48334961bf0530cdc77b5a56f852c5c61b89d735fd711)
> - Behavioral Change: JSON output format changes — NaN/inf encode as
`null`, and records contain arrays instead of lists for stream fields;
check consumers of `to_json`/`to_record` output
>
> <!-- Macroscope's review summary starts here -->
>
> <sup><a href="https://app.macroscope.com">Macroscope</a> summarized
4ae941f.</sup>
> <!-- Macroscope's review summary ends here -->
>
<!-- Macroscope's pull request summary ends here -->

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
mikasenghaas added a commit to PrimeIntellect-ai/prime-rl that referenced this pull request Oct 27, 2026
## Summary

- Bump verifiers to PrimeIntellect-ai/verifiers#2980. With it,
`Episode.to_record()` returns the per-token node streams as numpy
arrays.
- The file monitor's orjson (`OPT_SERIALIZE_NUMPY`) writes them in one
pass, so the file monitor needs no code change.
- The bump adds `orjson` to the verifiers dependencies. `uv.lock` is
relocked for it.
- The prime monitors keep passing the episodes to the SDK. From
PrimeIntellect-ai/prime#1109 on, the SDK encodes the numpy streams with
orjson.
- `test_episode_records.py` checks the upload path with the SDK's own
encoders: the trace line, the samples batch and the training viewer
table.

**Pinned until release:** PrimeIntellect-ai/prime#1109 is merged but not
released yet, so `prime-runs` and `prime-traces` are pinned to its merge
commit on prime main (`adf8d25`), with a TODO to replace the pins with
the PyPI release and raise the `prime-runs` minimum. `deps/verifiers` is
on verifiers main with PrimeIntellect-ai/verifiers#2980 (f166cd5). With
the released SDK, the prime monitors' uploads fail with `TypeError`.

## Verification

Real data: one 2,048-episode training batch with 193M tokens, replayed
through the real `TrainSink` and `Orchestrator.finalize_train_batch`
with a no-op sender.

| | Before | After |
|---|---|---|
| File monitor serialization, single-threaded, per batch | 103.3 s |
18.1 s |
| `FileMonitor.log_episodes` during arrival, per batch | 113.4 s | 19.9
s |
| Ship with the file and prime serializers running in background threads
| 1015.7 s | 114.2 s |

- Ship time runs from taking the batch to shipping it. The last row is a
worst case: each monitor's real per-episode serializer loops in its own
thread, as with a backlog. These threads hold the GIL in long C calls
and starve the ship's pure-Python steps. Without them, the ship on this
base takes ~42 s.
- In the last row, before is `main` with the released SDK, and after is
this stack with PrimeIntellect-ai/prime#1109. GC time in the ship drops
from 103.7 s to 0.6 s, and the longest pause from 4.52 s to 0.01 s.
- The prime serializer thread still costs 147 ms per episode after. Of
that, 12 ms is the encode and the rest is the SDK's level-9 gzip, which
releases the GIL.
- The prime SDK trace line drops from 114.7 ms per episode (`main` and
the released SDK) to 12.2 ms (this stack with
PrimeIntellect-ai/prime#1109) on 512 episodes, with the same content.
- `pytest tests/unit/orchestrator tests/unit/utils
tests/unit/train/sft/test_prime_monitor.py
tests/unit/test_dashboard_artifacts.py` with the
PrimeIntellect-ai/prime#1109 SDK: 181 passed. With the released SDK,
`test_received_episode_uploads_plain_json` fails with `TypeError: Object
of type ndarray is not JSON serializable`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Temporary git pins on core upload/training SDK packages change
resolution and reproducibility until PyPI catches up; behavior change is
limited to serialization of episode traces but affects all prime monitor
uploads.
> 
> **Overview**
> **Pins `prime-runs` and `prime-traces` to the Prime main commit that
ships PrimeIntellect-ai/prime#1109** (orjson-based trace/record encoding
for numpy per-token streams), via `tool.uv.sources`, an override on
`prime-traces`, and a refreshed `uv.lock`. TODOs call out swapping these
git pins for the next PyPI releases.
> 
> **Aligns upload-path tests** in `test_episode_records.py` with the
SDK: trace lines use `prime_traces._encode_record`, and sample JSON uses
`prime_runs._http.encode_json`, with an explicit check that encoded
`token_ids` remain plain JSON lists—not the old `json.dumps` /
`to_mapping` stand-ins.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
d5b8db3. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
kcoopermiller added a commit that referenced this pull request Oct 29, 2026
Ships the orjson encoder from #1109 and the transient-500 fix from #1123.
prime-runs now requires prime-traces>=0.0.11: its traces sink hands records
that may hold numpy arrays to TracesClient, which 0.0.10 cannot encode.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
kcoopermiller added a commit to PrimeIntellect-ai/verifiers that referenced this pull request Oct 29, 2026
## Summary

Replaces the git pins added in #2980 with the PyPI release of
PrimeIntellect-ai/prime#1109 (orjson-encoded records and numpy streams).
That release is PrimeIntellect-ai/prime#1126, which ships `prime-runs`
0.1.5 and `prime-traces` 0.0.11.

Both are now on PyPI. `uv.lock` moves `prime-runs` and `prime-traces`
from the `adf8d25c` git sources to PyPI 0.1.5 / 0.0.11. No other package
moves. The lockfile also changes from `revision = 4` to `5`, because uv
0.13 writes `default-groups` into it.

## Changes

- `prime-runs>=0.1.4` → `prime-runs>=0.1.5`.
- Removes the `prime-runs` git source in `[tool.uv.sources]`, pinned to
`adf8d25c`.
- Removes the `prime-traces` git override in `override-dependencies`,
pinned to the same commit. `prime-runs` 0.1.5 requires
`prime-traces>=0.0.11`, so verifiers no longer needs to pin it.
- Adds `prime-traces = false` to `[tool.uv.exclude-newer-package]`.
Without it, the 7-day `exclude-newer` cooldown hides `prime-traces`
0.0.11 and the lock fails to resolve. `prime-runs` is already exempt.

## Checks

- In a fresh venv, `pip install prime-runs==0.1.5` resolves
`prime-traces` 0.0.11.
- `uv sync` installs `prime-runs` 0.1.5 and `prime-traces` 0.0.11.
- `ruff check .` passes.
- `tests/unit`: 243 passed, 10 skipped. The skips need `harbor` or
`PRIME_API_KEY`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- Macroscope's pull request summary starts here -->
<!-- Macroscope will only edit the content between these invisible
markers, and the markers themselves will not be visible in the GitHub
rendered markdown. -->
<!-- If you delete either of the start / end markers from your PR's
description, Macroscope will append its summary at the bottom of the
description. -->
> [!NOTE]
> ### Require prime-runs 0.1.5 from PyPI
> Bumps the minimum `prime-runs` version to 0.1.5 in
[pyproject.toml](https://github.com/PrimeIntellect-ai/verifiers/pull/3001/files#diff-50c86b7ed8ac2cf95bd48334961bf0530cdc77b5a56f852c5c61b89d735fd711)
and removes the uv sources and override-dependencies entries that pulled
`prime-runs` and `prime-traces` from specific Git revisions. Adds
`prime-traces = false` to `tool.uv.exclude-newer-package` so the cutoff
does not apply to it. Behavioral Change: both packages now resolve from
PyPI instead of pinned Git commits.
>
> <!-- Macroscope's changelog starts here -->
> #### Changes since #3001 opened
>
> - Updated the dependency lock to require `prime-runs` version 0.1.5
from PyPI. [2d3f59a]
> <!-- Macroscope's changelog ends here -->
>
> <!-- Macroscope's review summary starts here -->
>
> <sup><a href="https://app.macroscope.com">Macroscope</a> summarized
1b749f4.</sup>
> <!-- Macroscope's review summary ends here -->
>
<!-- Macroscope's pull request summary ends here -->

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Dependency and lockfile-only change with no application code edits;
behavior shifts from pinned git commits to released PyPI versions
already exercised via the prior pins.
> 
> **Overview**
> This PR **drops temporary git pins** for `prime-runs` and
`prime-traces` and **consumes the published PyPI releases** instead
(`prime-runs` **0.1.5**, `prime-traces` **0.0.11** via `prime-runs`'
dependency).
> 
> **`pyproject.toml`** raises the minimum to `prime-runs>=0.1.5`,
removes the `prime-runs` git entry under `[tool.uv.sources]`, removes
the `prime-traces` git `override-dependencies` block (and related TODO
comments), and adds **`prime-traces = false`** to
`[tool.uv.exclude-newer-package]` so the 7-day `exclude-newer` window
does not block resolving the new trace package.
> 
> **`uv.lock`** reflects PyPI sources for both packages, drops the
manifest override for `prime-traces`, and bumps lock **revision** to 5
(uv writing `default-groups` on the root package).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
2d3f59a. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
mikasenghaas added a commit to PrimeIntellect-ai/prime-rl that referenced this pull request Nov 2, 2026
## Summary

- Bump `prime-sandboxes` 0.5.1 → 0.5.3 so live sandbox processes are no
longer capped at 24h (via PrimeIntellect-ai/verifiers#3043).
- Bump `deps/verifiers` `60290d4` → `bccc2c5` (verifiers main, with
PrimeIntellect-ai/verifiers#3043 merged).
- Require `prime-runs[train]>=0.1.5` from PyPI. This drops the
`prime-runs` git source and the `prime-traces` git override, both pinned
to `adf8d25c`. The new verifiers requires `prime-runs>=0.1.5`
(PrimeIntellect-ai/verifiers#3001), and the old git pin no longer
resolves. 0.1.5 contains `adf8d25c`, so it includes
PrimeIntellect-ai/prime#1109. `uv.lock`: `prime-runs` 0.1.4 (git) →
0.1.5, `prime-traces` 0.0.10 (git) → 0.0.11.

### Why

On Prime, the SDK sent a fixed 24h deadline on every live process
stream, and the sandbox ended the process when it expired. A long agent
segment then lost its ACP process. The trace stopped as `harness_error`
(`EOFError: ACP process closed its stdout`) instead of `agent_timeout`,
so `agent_timeout` undercounted real 24h cap hits.

### prime-sandboxes changes (0.5.1 → 0.5.3)

0.5.3:
- fix(sandboxes): stop capping live processes at 24h
(PrimeIntellect-ai/prime#1142)

0.5.2:
- feat(sandbox): add localhost forwards to the CLI and SDK
(PrimeIntellect-ai/prime#1124)
- feat(sandboxes): add pause and resume to the SDK and CLI
(PrimeIntellect-ai/prime#1056)
- fix(cli): write credential files owner-only
(PrimeIntellect-ai/prime#1130); the SDK auth cache is written 0600

### verifiers changes (`60290d4` → `bccc2c5`)

Fixes and features:
- fix(serve): discard kept episodes when clients disconnect
(PrimeIntellect-ai/verifiers#2997)
- Reuse interception tunnels for task-scoped MCP servers
(PrimeIntellect-ai/verifiers#3006)
- Run Prime task services as native VMs and fix Harbor setup
(PrimeIntellect-ai/verifiers#2910)
- Run Compose services as native Prime VMs
(PrimeIntellect-ai/verifiers#2918)
- Accept Harbor Compose tasks on native VMs
(PrimeIntellect-ai/verifiers#2999)
- Add a native Compose integration test on Prime
(PrimeIntellect-ai/verifiers#3010)
- fix(harbor): reject ignored verifier user overrides
(PrimeIntellect-ai/verifiers#3014)
- Honor configured disk size for native Compose sidecars
(PrimeIntellect-ai/verifiers#3018)
- Size native Compose disks per service
(PrimeIntellect-ai/verifiers#3020)
- fix: use apk-installed Node and npm on Alpine
(PrimeIntellect-ai/verifiers#3004)
- fix: retry Node downloads before extracting
(PrimeIntellect-ai/verifiers#3005)
- fix(CVE-2026-111497) in Brotli and Node
(PrimeIntellect-ai/verifiers#2998)

Dependency pins:
- bump prime-sandboxes to 0.5.3 (PrimeIntellect-ai/verifiers#3043)
- chore: require prime-runs 0.1.5 from PyPI
(PrimeIntellect-ai/verifiers#3001)

Harness versions:
- Bump Codex to 0.166.0 and codex-acp to 2.5.0
(PrimeIntellect-ai/verifiers#3021)
- Bump DeepSeek harness to 0.2.1-rc.5 (PrimeIntellect-ai/verifiers#3023)
- Bump mini-swe-agent's LiteLLM dependency to 1.106.6
(PrimeIntellect-ai/verifiers#3031)
- Bump Hermes Agent to v0.22.5 (PrimeIntellect-ai/verifiers#3024)
- Bump Claude Code to 2.1.314 and claude-agent-acp to 0.99.1
(PrimeIntellect-ai/verifiers#3022)
- Bump Kimi Code to 2.4.1 (PrimeIntellect-ai/verifiers#3025)
- Bump OpenCode to 2.2.5 (PrimeIntellect-ai/verifiers#3026)
- Bump OpenClaw to 2026.10.9 (PrimeIntellect-ai/verifiers#3027)
- Bump Prime Agent to 0.10.2 (PrimeIntellect-ai/verifiers#3028)
- Bump nano-rlm to e4d4407f (PrimeIntellect-ai/verifiers#3029)
- Bump Terminus 2 to Harbor 0.25.0 (PrimeIntellect-ai/verifiers#3030)

Dependabot lockfile bumps in verifiers (they do not change prime-rl's
lock):
- urllib3 2.7.0 → 2.8.0 (PrimeIntellect-ai/verifiers#2733), pyjwt 2.13.0
→ 2.15.0 (PrimeIntellect-ai/verifiers#2735), opentelemetry-api 1.44.0 →
1.45.1 (PrimeIntellect-ai/verifiers#2964), authlib 1.7.2 → 1.9.1
(PrimeIntellect-ai/verifiers#2990), msgpack 1.2.1 → 1.2.3
(PrimeIntellect-ai/verifiers#2991), litellm 1.98.0 → 1.100.4
(PrimeIntellect-ai/verifiers#2992), dnspython 2.8.0 → 2.9.0
(PrimeIntellect-ai/verifiers#2993), filelock 3.32.4 → 4.2.1
(PrimeIntellect-ai/verifiers#3002), virtualenv 21.14.12 → 21.14.13
(PrimeIntellect-ai/verifiers#3008), joserfc 1.7.4 → 1.7.6
(PrimeIntellect-ai/verifiers#3017), oauthlib 3.3.1 → 4.0.0
(PrimeIntellect-ai/verifiers#3035)

## Verification

- `uv sync --frozen --all-packages --all-extras` installs
`prime-sandboxes` 0.5.3.
`prime_sandboxes.sandbox._LIVE_PROCESS_NO_TIMEOUT_MS == 9999999999` is
the default deadline for every `open_process` stream.
- `uv.lock` changes only `prime-sandboxes`, `prime-runs` and
`prime-traces` (plus a uv-written reorder of the `exclude-newer-package`
table).
- `pytest tests/unit --ignore=tests/unit/train`: 837 passed, 1 xfailed.
- `tests/unit/train` (RTX PRO 6000 Blackwell, SM120):
`qwen3_8_flash_next` and `test_fp8_grouped_gemm` show the same failures,
and `test_fused_lm_head.py::test_inject_prime_lm_head_vanilla` kills the
process, on this branch and on `main` (`823ed27`). These GPU kernel
tests do not touch this diff.
- verifiers#3043: the live Prime runtime tests
(`tests/unit/test_runtimes.py -k prime`, including `test_exec` on a live
process) pass on 0.5.3.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants