Skip to content

perf: lazy-load the client errors so renderers.configs imports without openai - #199

Merged
hallerite merged 1 commit into
mainfrom
sai/light-configs
Oct 22, 2026
Merged

hallerite merged 1 commit into
mainfrom
sai/light-configs

Conversation

@skpulipaka26

@skpulipaka26 skpulipaka26 commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

renderers/__init__ eagerly imported renderers.client for its two exceptions, so importing only the config layer (renderers.configs, which verifiers and prime-rl's config schema use) also loaded httpx and openai. The two exceptions now resolve through the existing PEP 562 table alongside the lazy renderer classes, with a TYPE_CHECKING import so their types stay visible. import renderers.configs now loads only pydantic.

No API change: from renderers import OverlongPromptError still works. Tested with tests/test_client.py, ruff and ty (same diagnostics as main), and an import check that renderers.client and openai stay out of sys.modules. This unblocks a pydantic-only environment for hosted training's config validation (paired verifiers and prime-rl PRs).

Note

Lazy-load client error classes in renderers so renderers.configs imports without openai

Removes the eager import of HTTP client error classes from renderers/init.py. They are instead added to the lazy export registry and resolved on demand via renderers.__getattr__, which imports renderers.client and caches the result in package globals.

  • dir(renderers) now lists the lazily exported client error class names (MalformedGenerateResponseError, OverlongPromptError) alongside renderer classes.

Macroscope summarized 1a3b5d2.

@macroscopeapp

macroscopeapp Bot commented Oct 21, 2026

Copy link
Copy Markdown

Approvability

Verdict: Approved at 1a3b5d2

Macroscope's review found this PR approvable — The PR narrowly converts two existing client error exports to the package’s established lazy-export mechanism, allowing config-only imports to avoid loading OpenAI while preserving normal access to the errors. It changes only import timing in one module and introduces no schema or production workflow changes.

Notes:

  • Macroscope's correctness review did not run, so approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

Comment thread renderers/__init__.py
# ``transformers`` dependency is absent. ``__getattr__`` (PEP 562) resolves the
# names on first attribute access, while ``renderers.base._populate_registry``
# handles lazy registration for ``create_renderer``.
_LAZY_RENDERERS: dict[str, str] = {

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.

why renaming this var name

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The table now also holds the two renderers.client exceptions, not just renderer classes, so _LAZY_RENDERERS would have been misleading. Happy to rename it back if you prefer.

@hallerite
hallerite merged commit dc0b492 into main Oct 22, 2026
10 checks passed
@hallerite
hallerite deleted the sai/light-configs branch October 22, 2026 08:42
mikasenghaas pushed a commit to PrimeIntellect-ai/verifiers that referenced this pull request Oct 22, 2026
… names lazily (#2938)

The config tree is documented to import only types and other configs,
but `configs.agent`, `configs.env`, `configs.judge` and
`configs.scoring` reached into `clients`, `runtimes` and `interception`,
and `verifiers.v1/__init__` imported the whole runtime eagerly.
Importing a single config cost ~0.9s and needed openai, anthropic,
sympy, numpy, prime-sandboxes and friends installed. The runtime,
deployment, interception, tunnel and single-agent env configs now live
in `verifiers.v1.configs` (old import paths keep re-exporting them),
`types.py` imports numpy only where it builds arrays, and `verifiers.v1`
resolves its names on first access through one name to module table,
with the same imports under `TYPE_CHECKING` so type checkers still see
real types. The whole config tree now imports with only pydantic, in
~140ms.

No public API change: every `vf.*` name and existing import path still
resolves. `tests/unit/test_api.py` keeps the lazy table, the
`TYPE_CHECKING` imports and `__all__` in sync and asserts the config
tree imports without the runtime; that test needs
PrimeIntellect-ai/renderers#199 released and the renderers pin bumped,
which I'll add here once it's published. Unit tests and `ty check` pass.
prime-rl's 29 example RL/SFT configs validate in an 11-package env with
output identical to a full install.

<!-- 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 `verifiers.v1` config tree free of runtime imports and
resolve names lazily
> - Moves all config models (`RuntimeConfig`, `InterceptionConfig`,
`DeploymentConfig`, `SingleAgentEnvConfig`) from
runtime/interception/env implementation modules into a dedicated
`verifiers.v1.configs` package, so importing the config tree no longer
pulls in runtime dependencies
> - Makes
[__init__.py](https://github.com/PrimeIntellect-ai/verifiers/pull/2938/files#diff-731a849803c53d001c41b5e0fb1bfcb392eaae7eb4fa4b3ace382768dc40066a)
import public symbols only under `TYPE_CHECKING` and resolves them at
attribute access via a new `__getattr__` registry that caches resolved
values; `__dir__` lists unresolved lazy names
> - Moves the NumPy import in
[types.py](https://github.com/PrimeIntellect-ai/verifiers/pull/2938/files#diff-88a4e4ee0c58ac5dc7344161a011374082a3767eda2ad32af97c942dca982112)
to call time inside array-building helpers, so `verifiers.v1.types`
imports without NumPy
> - Adds tests in
[test_api.py](https://github.com/PrimeIntellect-ai/verifiers/pull/2938/files#diff-3cabff7688a6836f0be39ae71c04a68b09858683669c2bf6d24281910999cb74)
that the lazy mapping matches the type-checking imports, `__all__` stays
in sync, and every config module imports without runtime packages
> - Behavioral Change: `dir(verifiers.v1)` and import-time side effects
differ — the config models now live only under `verifiers.v1.configs`
(e.g. `DeploymentConfig`, `PrimeConfig`); old import paths like
`verifiers.v1.runtimes.PrimeConfig` are removed, and in-tree importers
were updated to the new modules
>
> <!-- Macroscope's review summary starts here -->
>
> <sup><a href="https://app.macroscope.com">Macroscope</a> summarized
c289d0c.</sup>
> <!-- Macroscope's review summary ends here -->
>
<!-- Macroscope's pull request summary ends here -->
mikasenghaas added a commit to PrimeIntellect-ai/verifiers that referenced this pull request Oct 22, 2026
## Summary

- Bump `renderers[multimodal]` from `>=0.1.12` to `>=0.1.13.dev16`, and
lock 0.1.13.dev16.
- dev16 is the build of PrimeIntellect-ai/renderers#199, which
lazy-loads the client errors. With 0.1.12, `from renderers import
RendererConfig` in `configs/client.py` loads `openai`, `httpx` and
`rich`.
- I locked with uv 0.12.6 to keep the lockfile format unchanged, so the
lock diff only touches renderers.

## Verification

- Before: `test_config_tree_imports_without_the_runtime` fails on `main`
(`7f3290501`) in CI and locally. The extra packages are `openai`,
`httpx`, `rich`, `anyio`, `pygments` and others.
- After: the same test passes, and the full unit suite passes locally.

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Dependency-only bump with no application code changes; risk is limited
to behavior differences in the pinned pre-release renderers build.
> 
> **Overview**
> Bumps **`renderers[multimodal]`** from `>=0.1.12` to
**`>=0.1.13.dev16`** and refreshes **`uv.lock`** to pin that pre-release
(renderers#199).
> 
> The newer build **lazy-loads client/OpenAI-related code**, so
importing the config tree (e.g. `RendererConfig` via
`verifiers.v1.configs`) no longer drags in **`openai`**, **`httpx`**,
**`rich`**, and their transitive deps. That restores
**`test_config_tree_imports_without_the_runtime`**, which expects only a
small allowlist of top-level packages when walking
`verifiers.v1.configs`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
aeee131. 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]
> ### Bump `renderers[multimodal]` to `0.1.13.dev16` so config tree
imports without openai
> Raises the minimum `renderers[multimodal]` dependency from `0.1.12` to
`0.1.13.dev16` in
[pyproject.toml](https://github.com/PrimeIntellect-ai/verifiers/pull/2950/files#diff-50c86b7ed8ac2cf95bd48334961bf0530cdc77b5a56f852c5c61b89d735fd711).
Updates
[uv.lock](https://github.com/PrimeIntellect-ai/verifiers/pull/2950/files#diff-84321598744d84dbee2318e634c74c9aae39a1c253f1c4bd17ebf9ef2f807b11)
to match. Risk: installs now require a dev prerelease (`0.1.13.dev16`)
rather than a stable `renderers` release.
>
> <!-- Macroscope's review summary starts here -->
>
> <sup><a href="https://app.macroscope.com">Macroscope</a> summarized
aeee131.</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 22, 2026
…t runs (#4206)

## Summary

- Bump `deps/verifiers` to verifiers `main` (`4c2738dc6`), which
includes PrimeIntellect-ai/verifiers#2949. Its new agent config fields
reach prime-rl through each source's `env` block:
- `env.agent.scoring.skip_on_truncated`: skip task scoring for a
truncated trace. It keeps no rewards, so its reward is 0.
- `env.agent.scoring.skip_on_timeout`: the same for a trace whose stage
deadline expired before scoring.
- `env.agent.max_turn_tokens`: the framework per-turn limit. It lowers
`sampling.max_tokens` on every request. Like the other `max_*` caps, it
stops the run once a response hits it, with the `max_turn_tokens` stop
condition. This also stops harnesses that continue past a capped turn,
such as RLM.
- Count `max_turn_tokens` as truncation in both copies of
`TRUNCATING_STOPS`, which mirror `Trace.is_truncated`:
`monitors/file/traces/index.py` and the dashboard's `static/app.js`.
- Bump `deps/renderers` to renderers `main`
(PrimeIntellect-ai/renderers#199, 0.1.13.dev16), because verifiers
`main` now requires `renderers>=0.1.13.dev16`
(PrimeIntellect-ai/verifiers#2950).
- The verifiers bump also moves `prime-sandboxes` 0.4.7 → 0.5.0 in
`uv.lock`, because verifiers `main` requires it.
- Mention the flags in the eval skill.

```toml
[[source]]
env.taskset.id = "gsm8k"
env.agent.max_turn_tokens = 4096
env.agent.scoring.skip_on_truncated = true
env.agent.scoring.skip_on_timeout = true
```

## Verification

I ran `uv run eval` on Prime Inference (default model), null harness,
subprocess runtime.

- **Turn cap**, alphabet-sort, `max_turns = 1`, 4 tasks × 2:
- Skip off: the two `max_turns`-stopped traces score `alphabet_sort:
0.5`.
- Skip on: the same traces get `rewards={}` (reward 0) and
`info.scoring_skipped="truncated"`. Traces that end normally still
score.
- **Token cap**, gsm8k, `max_completion_tokens = 24`, 8 tasks × 2:
- Skip off: all 16 traces finish with `length` and score `correct: 0.0`.
  - Skip on: all 16 get `rewards={}` and `scoring_skipped="truncated"`.
- **Per-turn limit**, alphabet-sort, skip on:
- `max_turn_tokens = 8`: every request carries `max_tokens=8`, and the
two-turn tasks end after 1 call with `stop=max_turn_tokens`.
- `sampling.max_tokens = 8` instead: the two-turn tasks make 2 capped
calls.
  - Every trace is truncated and keeps no rewards.
- Unit tests in `tests/unit/{eval,orchestrator}` and the dashboard and
config tests: 409 pass. One test needs `vllm` and one needs
`prime_kernels`. Neither is installed on macOS.

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: truncation classification parity in monitors/UI, eval docs,
and dependency lock updates; scoring behavior changes come from the
verifiers bump rather than new prime-rl logic in this diff.
> 
> **Overview**
> Aligns prime-rl with verifiers’ **per-turn token cap** and **optional
zero-reward scoring** when runs truncate or time out before scoring.
> 
> **Truncation handling:** `max_turn_tokens` is added to
`TRUNCATING_STOPS` in the dashboard (`app.js`) and file trace monitor
(`traces/index.py`) so traces stopped by the per-turn limit are treated
like other framework caps when mirroring `Trace.is_truncated` (e.g. for
`is_truncated/mean` and UI).
> 
> **Docs:** The eval skill now explains `env.agent.max_turn_tokens` and
`env.agent.scoring.skip_on_truncated` / `skip_on_timeout` as
alternatives to raising `sampling.max_completion_tokens` when truncation
metrics are high.
> 
> **Dependencies:** `uv.lock` bumps `prime-sandboxes` to 0.5.0 and
`renderers` to `>=0.1.13.dev16` (with verifiers), plus lock revision.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
d06f443. 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>
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.

3 participants