Pipe chat_template_kwargs into typed RendererConfig#1468
Conversation
Pop sampling_args.extra_body.chat_template_kwargs in RendererClient.get_native_response and fold them into a typed RendererConfig via pydantic model_validate before the pool lookup. The typed configs' extra="forbid" rejects unknown keys with a field-path error; DefaultRendererConfig's extra="allow" keeps the escape hatch for arbitrary jinja kwargs. Kwargs override fields with the same name on the base config (last-write-wins). The pool cache key already keys on the effective config_json, so identical kwargs across requests reuse a single renderer; varied kwargs just produce additional pool entries. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When ``ClientConfig.renderer_config`` is ``None`` (verifiers eval CLI default) or ``AutoRendererConfig`` (prime-rl default), pull the ``MODEL_RENDERER_MAP`` lookup forward so that ``chat_template_kwargs.enable_thinking`` etc. validate against the concrete renderer's schema (Qwen3RendererConfig) instead of the intentionally-minimal Auto schema. Mirrors ``renderers._resolve_auto``'s preserve_* carry. Pool cache key still keys on the effective concrete config so this changes nothing for explicit Qwen3RendererConfig users. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit dd02a30. Configure here.
ApprovabilityVerdict: Needs human review This PR introduces new feature capability by piping chat_template_kwargs into typed RendererConfig, enabling per-request configuration overrides with auto-resolution logic. Changes runtime behavior by creating new configuration propagation paths and validating against concrete renderer schemas. You can customize Macroscope's approvability policy. Learn more. |
- Drop ValueError wrap; let pydantic ValidationError propagate with its structured field path intact - Drop dead assert (MODEL_RENDERER_MAP.get(..., "default") never returns "auto") - Use model_copy(update=...) for preserve_* carry instead of model_validate round-trip - Collapse explicit-base happy-path test into the auto-resolve test (covers Qwen3 / Auto / None bases in one loop) - Update error-path test to assert pydantic ValidationError directly Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bugbot caught a divergence: ``_resolve_renderer_config`` was looking up ``MODEL_RENDERER_MAP[model]`` while ``_get_renderer_or_pool`` builds the pool against ``ClientConfig.renderer_model_name`` when set. With per- request kwargs + None/Auto base, this could pick a renderer schema that doesn't match the actual tokenizer model. Now resolve against the same ``renderer_model_name`` override the pool uses. Also restore the ``assert concrete is not None`` (with comment) and add an explicit ``cast`` to silence ty's union-narrowing — the runtime path is unreachable but the type checker can't see through ``MODEL_RENDERER_MAP.get(..., "default")``. Adds one test that pins the override-vs-request-model behaviour. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
mikasenghaas
left a comment
There was a problem hiding this comment.
as discussed, approving this to unblock quickly. short-term cleanup would be to expose resolve_renderer(model_name: str) -> RendererConfig from renderers so we can resolve 1. the renderer 2. the chat template kwargs in the prime-rl configs

Summary
Pipe
sampling_args.extra_body.chat_template_kwargsthrough to the typedRendererConfigso users can setenable_thinkingetc. in sampling and have it land on the right renderer — no[renderer]block needed.chat_template_kwargsfrom sampling inRendererClient.get_native_response.None/AutoRendererConfig→ concrete config viaMODEL_RENDERER_MAPbefore merging, so kwargs validate against the actual renderer's schema (Qwen3RendererConfig.enable_thinking) instead ofAutoRendererConfig's intentionally-minimal one. Mirrorsrenderers._resolve_auto'spreserve_*carry.extra="forbid") reject unknown keys with a field-path error;DefaultRendererConfig(extra="allow") keeps the escape hatch for arbitrary jinja kwargs.renderer_config_json, so identical kwargs across requests reuse a single renderer.Replaces #1447 (pre-typed-config era).
Effective truth table
ClientConfig.renderer_configchat_template_kwargsQwen3RendererConfig(...)(explicit){enable_thinking: False}enable_thinking=FalseQwen3RendererConfig(...)(explicit){enable_thinkng: False}(typo)ValueError(... Qwen3RendererConfig ... extra_forbidden)AutoRendererConfig()(prime-rl default){enable_thinking: False}MODEL_RENDERER_MAP[model], then mergesNone(verifiers eval CLI default){enable_thinking: False}Companion PRs
renderer+sampling_argsthrough unchanged.MODEL_RENDERER_MAP+config_from_name+extra="forbid"/extra="allow"cover everything we need.Test plan
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 uv run pytest tests/test_renderer_client.py -k "honors_configured_renderer_config or renderer_model_name_override or merges_chat_template_kwargs or rejects_invalid_chat_template or auto_resolves_for_chat_template"— 5 passeduvx ruff check verifiers/clients/renderer_client.py tests/test_renderer_client.py— clean🤖 Generated with Claude Code
Note
Medium Risk
Changes per-request renderer pool selection and sampling param forwarding; mis-merged kwargs could affect tokenization across rollouts, though behavior is covered by new unit tests.
Overview
RendererClientnow treatssampling_args.extra_body.chat_template_kwargsas renderer configuration instead of engine sampling: they are removed from params sent to/generateand merged into the effectiveRendererConfigused when building or selecting a shared renderer pool.A new
_resolve_renderer_configpath resolvesNone/AutoRendererConfigto the concrete config for the tokenizer model (viaMODEL_RENDERER_MAP, honoringClientConfig.renderer_model_namewhen set), carriespreserve_*fields from auto config, then applies kwargs with pydantic validation (unknown keys fail on strict configs)._get_renderer_or_poolaccepts a per-request resolved config so pool cache keys reflect merged settings.Tests cover explicit/auto/
Nonebases,renderer_model_nameoverride during auto-resolution, stripping kwargs from forwarded sampling params, andValidationErroron typos.Reviewed by Cursor Bugbot for commit 14ab2a7. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Pipe
chat_template_kwargsfromextra_bodyinto a typedRendererConfigbefore generationchat_template_kwargsfromsampling_params.extra_bodyinRendererClient.get_native_responseand removes them before forwarding to/generate._resolve_renderer_configin renderer_client.py to merge kwargs into a concreteRendererConfig, resolvingAuto/Nonebases viaMODEL_RENDERER_MAPandconfig_from_name.ClientConfig.renderer_model_nameis set, auto-resolution uses that override instead of the request model name._get_renderer_or_poolnow accepts an optionalrenderer_configparameter so the resolved config drives pool selection.chat_template_kwargskeys now raise a pydanticValidationErrorbefore generation, which is a breaking change for callers passing unrecognized keys.Macroscope summarized 14ab2a7.