Skip to content

chore: consolidate v1 root modules into utils - #2204

Merged
xeophon merged 2 commits into
mainfrom
chore/consolidate-v1-utils
Jul 31, 2026
Merged

chore: consolidate v1 root modules into utils#2204
xeophon merged 2 commits into
mainfrom
chore/consolidate-v1-utils

Conversation

@mikasenghaas

@mikasenghaas mikasenghaas commented Jul 31, 2026

Copy link
Copy Markdown
Member

Summary

  • Move six modules from the verifiers/v1 package root into verifiers/v1/utils/: scoring.pyutils/score.py, push.pyutils/platform.py, artifacts.pyutils/artifacts.py, decorators.pyutils/decorators.py, loaders.pyutils/loaders.py, retries.pyutils/retries.py.
  • Remove the sample() helper (and with it utils/sampling.py), inlining the fixed-seed shuffle + head-slice at its two call sites (cli/eval/runner.py, legacy.py). The shared SEED constant now lives in taskset.py, next to Taskset.shuffle which already used it.
  • Inline _as_messages at its single call site (Interaction._turn in agent.py) and remove it from rollout.py — it normalized wire-dict user turns to typed messages and had no other consumer.
  • Move _serve_interception out of rollout.py into the interception package as public serve_interception (alongside requires_tunnel/make_interception, symmetric with mcp's serve_tools).
  • Rename RolloutRun -> Rollout.
  • All vf.* re-exports in verifiers/v1/__init__.py are unchanged.

Breaking

Deep-path imports of the moved modules break; verifiers.v1 re-exports are unaffected.

  • verifiers.v1.scoringverifiers.v1.utils.score
  • verifiers.v1.pushverifiers.v1.utils.platform
  • verifiers.v1.artifactsverifiers.v1.utils.artifacts
  • verifiers.v1.decoratorsverifiers.v1.utils.decorators
  • verifiers.v1.loadersverifiers.v1.utils.loaders
  • verifiers.v1.retriesverifiers.v1.utils.retries
  • verifiers.v1.rollout.RolloutRun -> verifiers.v1.rollout.Rollout (not re-exported from verifiers.v1; its only in-tree driver is Agent).
  • verifiers.v1.utils.sampling is removed: import SEED from verifiers.v1.taskset; sample() has no replacement (inline the shuffle + slice).

Verification

uv run ruff check, uv run pre-commit run --all-files, and uv run pytest tests/v1 (66 passed, 66 skipped — skips need PRIME_API_KEY) all pass.

🤖 Generated with Claude Code


Note

Medium Risk
Breaking for deep imports of moved modules and removed utils.sampling; public verifiers.v1 API unchanged. Shuffle behavior should match prior sample() if semantics are preserved.

Overview
Moves six former verifiers/v1 top-level modules under verifiers/v1/utils/ (loaders, decorators, retries, artifacts, scoringscore, pushplatform) and updates internal imports across CLI, env, rollout, tasksets, and tests. verifiers/v1/__init__.py still re-exports the same vf.* surface from the new paths.

utils/sampling.py is removed: SEED lives on taskset.py (alongside Taskset.shuffle), and legacy/server eval paths inline random.Random(SEED).shuffle + slice instead of sample().

state.py only gets a shorter module docstring.

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

Note

Move v1 root utility modules into verifiers/v1/utils/ subpackage

Relocates artifacts, decorators, loaders, push, retries, scoring from verifiers/v1/ to verifiers/v1/utils/, with push renamed to platform and scoring renamed to score. All internal imports across the codebase are updated to the new paths. Public re-exports in verifiers/v1/__init__.py are updated to source from the new locations, keeping the external API unchanged.

  • verifiers/v1/utils/sampling.py is deleted; SEED is moved to taskset.py and callers of sample() now inline equivalent deterministic shuffle-and-slice logic using random.Random(SEED).
  • Risk: any code importing verifiers.v1.utils.sampling directly will now get an ImportError.

Macroscope summarized 98c0984.

Move scoring, push, artifacts, decorators, loaders, and retries from the
v1 package root into verifiers/v1/utils, and inline the sample() helper
at its two call sites (SEED now lives next to Taskset.shuffle).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mikasenghaas
mikasenghaas requested review from hallerite and xeophon and removed request for hallerite July 31, 2026 17:26
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Jul 31, 2026
@macroscopeapp

macroscopeapp Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved 98c0984

Mechanical file reorganization moving v1 root modules into utils subdirectory. All import paths updated consistently, public API preserved via re-exports, and the inlined sampling logic is behaviorally identical to the removed helper function.

You can customize Macroscope's approvability policy. Learn more.

Comment thread verifiers/v1/taskset.py
if TYPE_CHECKING:
from verifiers.v1.mcp import Toolset

SEED = 0 # fixed so `--shuffle` samples the same items every run (reproducible)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

hm, idk

@xeophon
xeophon merged commit 83be3f6 into main Jul 31, 2026
12 of 13 checks passed
xeophon added a commit that referenced this pull request Aug 31, 2026
## Overview

Consolidates v1 MCP client utilities and standalone harness code behind
shared owning modules.

## Details

- Exposes mcp_client, with_retry, connect_mcp,
mcp_content_to_chat_content, and call_mcp from verifiers.v1.mcp.
- Preserves the existing per-call client, timeout, teardown, naming,
image conversion, and at-least-once retry behavior.
- Embeds the public client source after PEP 723 metadata so standalone
sandbox programs retain their declared dependency isolation.
- Shares one minimal program between Null and Bash and centralizes the
common host-side launch path.
- Reuses the public client helper from NeMo Gym and removes the
duplicate MCP implementations from Null, Bash, Browser Use, and NeMo
Gym.

## Related work

- #2474 moved first-party clients to MCP 2.0 and the 2026-07-28
protocol; this PR consolidates those implementations without changing
their protocol behavior.
- #2204 established the v1 package-organization pattern by consolidating
root helpers into an owning utils package; this PR applies the same
approach to MCP client utilities.
- #2134 explored both a shared Null/Bash program and new
lifecycle/replay rules; this PR carries forward the shared-program
consolidation only and leaves lifecycle and retry semantics unchanged.

Closes #2202

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches eval harness launch paths and MCP tool wiring across Null,
Bash, Browser Use, and NeMo Gym; behavioral differences between Null and
Bash modes in the unified program warrant careful regression testing.
> 
> **Overview**
> Moves duplicated MCP HTTP client, retry, tool discovery, and call
helpers into **`verifiers.v1.mcp.client`**, re-exported from
**`verifiers.v1.mcp`**, and wires NeMo Gym’s upstream MCP calls through
that shared **`mcp_client`** instead of a local session helper.
> 
> Adds **`standalone.py`** with **`launch_chat_program`** (shared
CLI/MCP/initial-messages launch path) and **`inline_mcp_client`**
(splices the client module source into PEP 723 sandbox scripts).
**Null** and **Bash** now share **`minimal/program.py`** (Bash passes
**`--bash`** plus edit/search/interception flags); **`null/program.py`**
is removed. **Browser Use** drops its inlined MCP copy and uses the same
embed + **`launch_chat_program`** pattern.
> 
> The shared minimal program keeps **Null**-specific behavior when
**`--bash`** is off (60s MCP enumeration cap, graceful exit on
context-overflow API errors) and **Bash**-specific behavior when on
(longer HTTP timeouts, unbounded MCP connect wait, local tools gated by
flags).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
1944f34. 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]
> ### Consolidate v1 MCP client utilities into shared `client.py` and
`launch_chat_program`
> - Adds a reusable MCP client in
[client.py](https://github.com/PrimeIntellect-ai/verifiers/pull/2467/files#diff-00e3f7299d973207d20664447f3f10392038cc94faba8282d8fd7145f53606fe)
with `mcp_client`, `with_retry`, `connect_mcp`,
`mcp_content_to_chat_content`, and `call_mcp` helpers, replacing
per-harness duplicates
> - Adds `standalone.launch_chat_program` and `inline_mcp_client` in
[standalone.py](https://github.com/PrimeIntellect-ai/verifiers/pull/2467/files#diff-2c4721a1f03415dbed2e15a162cbc76345a56a9c3cdcbc6092e1f6968b20102b)
to centralize wire-argument passing and embed the MCP client into PEP
723 scripts at build time
> - Refactors the bash, browser_use, and null harnesses to call
`launch_chat_program` with the shared `minimal.PROGRAM_SOURCE`; deletes
the standalone null program
> - Unifies `minimal/program.py` to serve both Null and Bash harnesses
via a `--bash` flag that enables bash tooling, unbounded MCP
enumeration, and longer model timeout; without it, bash tooling is
disabled and context-overflow errors terminate cleanly
> - Refactors `NeMoGymToolset.list_tools`/`call_tool` in
[toolset.py](https://github.com/PrimeIntellect-ai/verifiers/pull/2467/files#diff-fdaa3c526186955703d1d22244a24748ea125e780d399bd6be9b9c863fda6511)
to use the shared `mcp_client` helper with explicit timeouts
> - Risk: `minimal.program` now relies on inlined shared functions
(`mcp_client`, `with_retry`, `connect_mcp`, `call_mcp`,
`mcp_content_to_chat_content`) being present at runtime via
`inline_mcp_client`; if `PROGRAM_SOURCE` is constructed without calling
`inline_mcp_client`, the script will fail with `NameError`
>
> <!-- Macroscope's review summary starts here -->
>
> <sup><a href="https://app.macroscope.com">Macroscope</a> summarized
1944f34.</sup>
> <!-- Macroscope's review summary ends here -->
>
<!-- Macroscope's pull request summary ends here -->
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