renderers 0.1.11.dev4__tar.gz → 0.1.11.dev5__tar.gz

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.
Files changed (92) hide show
  1. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/PKG-INFO +2 -2
  2. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/README.md +1 -1
  3. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/docs/renderer-config.md +2 -2
  4. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/pyproject.toml +1 -1
  5. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/_version.py +2 -2
  6. renderers-0.1.11.dev5/tests/conftest.py +59 -0
  7. renderers-0.1.11.dev5/tests/parity.py +782 -0
  8. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/reference_rendering.py +283 -29
  9. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_bridge.py +2 -24
  10. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_deepseek_r1.py +3 -70
  11. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_disabled_thinking_stability.py +17 -33
  12. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_gemma4.py +2 -6
  13. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_glm_tool_name_validation.py +2 -4
  14. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_incremental.py +1 -1
  15. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_laguna_m1.py +0 -78
  16. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_llama_3.py +4 -147
  17. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_message_indices.py +1 -1
  18. renderers-0.1.11.dev5/tests/test_parity.py +222 -0
  19. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_parse_response.py +64 -0
  20. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_qwen35_size_coverage.py +4 -91
  21. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_roundtrip.py +12 -50
  22. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_tool_arg_type_preservation.py +2 -10
  23. renderers-0.1.11.dev4/tests/conftest.py +0 -171
  24. renderers-0.1.11.dev4/tests/test_gpt_oss_harmony_parity.py +0 -271
  25. renderers-0.1.11.dev4/tests/test_laguna_s21.py +0 -128
  26. renderers-0.1.11.dev4/tests/test_nemotron3_parity.py +0 -683
  27. renderers-0.1.11.dev4/tests/test_prime_qwen3_parity.py +0 -254
  28. renderers-0.1.11.dev4/tests/test_render_ids.py +0 -402
  29. renderers-0.1.11.dev4/tests/test_renderer_config_parity.py +0 -602
  30. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/.github/workflows/publish-dev.yml +0 -0
  31. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/.github/workflows/publish.yml +0 -0
  32. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/.github/workflows/style.yml +0 -0
  33. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/.github/workflows/test.yml +0 -0
  34. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/.gitignore +0 -0
  35. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/.pre-commit-config.yaml +0 -0
  36. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/LICENSE +0 -0
  37. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/examples/README.md +0 -0
  38. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/examples/sglang/multiturn_generate_sglang.py +0 -0
  39. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/examples/sglang/online_multiturn_sglang.py +0 -0
  40. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/examples/tinker/multiturn_generate_tinker.py +0 -0
  41. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/examples/transformers/multiturn_generate_transformers.py +0 -0
  42. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/examples/vllm/multiturn_generate_vllm.py +0 -0
  43. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/__init__.py +0 -0
  44. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/base.py +0 -0
  45. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/client.py +0 -0
  46. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/configs.py +0 -0
  47. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/deepseek_r1.py +0 -0
  48. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/deepseek_v3.py +0 -0
  49. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/deepseek_v4.py +0 -0
  50. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/default.py +0 -0
  51. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/gemma4.py +0 -0
  52. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/glm45.py +0 -0
  53. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/glm5.py +0 -0
  54. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/gpt_oss.py +0 -0
  55. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/hy3.py +0 -0
  56. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/inkling.py +0 -0
  57. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/kimi_k2.py +0 -0
  58. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/kimi_k25.py +0 -0
  59. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/laguna_s21.py +0 -0
  60. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/laguna_xs2.py +0 -0
  61. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/llama_3.py +0 -0
  62. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/minimax_m2.py +0 -0
  63. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/nemotron3.py +0 -0
  64. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/parsers.py +0 -0
  65. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/parsing.py +0 -0
  66. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/prime_qwen3.py +0 -0
  67. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/qwen3.py +0 -0
  68. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/qwen35.py +0 -0
  69. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/qwen36.py +0 -0
  70. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/qwen38.py +0 -0
  71. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/renderers/qwen3_vl.py +0 -0
  72. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_build_helpers.py +0 -0
  73. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_client.py +0 -0
  74. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_deepseek_v4.py +0 -0
  75. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_hy3.py +0 -0
  76. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_inkling.py +0 -0
  77. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_is_content.py +0 -0
  78. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_kimi_k25_tool_schema.py +0 -0
  79. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_laguna_xs21.py +0 -0
  80. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_load_tokenizer.py +0 -0
  81. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_message_tool_names.py +0 -0
  82. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_multimodal.py +0 -0
  83. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_nemotron3_ultra.py +0 -0
  84. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_offsetless_tokenizers.py +0 -0
  85. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_parse_response_robustness.py +0 -0
  86. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_parsers.py +0 -0
  87. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_preserve_thinking.py +0 -0
  88. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_qwen38.py +0 -0
  89. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_renderer_config.py +0 -0
  90. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_sampled_mask.py +0 -0
  91. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/tests/test_tokens_per_message.py +0 -0
  92. {renderers-0.1.11.dev4 → renderers-0.1.11.dev5}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: renderers
3
- Version: 0.1.11.dev4
3
+ Version: 0.1.11.dev5
4
4
  Summary: Chat template renderers — deterministic message-to-token conversion for LLM training
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -199,7 +199,7 @@ uv sync --group dev
199
199
  uv run pytest
200
200
  ```
201
201
 
202
- Round-trip parity (render → parse → original) and token-level parity against `apply_chat_template` are tested per renderer. End-to-end validation runs against Reverse-Text, Wordle, OpenCode-Math, and RLM-SWE environments.
202
+ Round-trip parity (render → parse → original) and token-level parity against each model's independent reference encoder are tested per renderer. Most references use `apply_chat_template`; DeepSeek V4 uses its shipped Python encoder, and GPT-OSS uses Harmony.
203
203
 
204
204
  ## License
205
205
 
@@ -179,7 +179,7 @@ uv sync --group dev
179
179
  uv run pytest
180
180
  ```
181
181
 
182
- Round-trip parity (render → parse → original) and token-level parity against `apply_chat_template` are tested per renderer. End-to-end validation runs against Reverse-Text, Wordle, OpenCode-Math, and RLM-SWE environments.
182
+ Round-trip parity (render → parse → original) and token-level parity against each model's independent reference encoder are tested per renderer. Most references use `apply_chat_template`; DeepSeek V4 uses its shipped Python encoder, and GPT-OSS uses Harmony.
183
183
 
184
184
  ## License
185
185
 
@@ -21,8 +21,8 @@ construction.
21
21
  Use `type(config).template_field_names()` to inspect the explicit allowlist of
22
22
  fields accepted through `chat_template_kwargs`. Every renderer-specific field
23
23
  is classified as either a template field or a renderer-only field at class
24
- definition time. Template fields are covered by parity tests against
25
- `apply_chat_template` in `tests/test_renderer_config_parity.py`.
24
+ definition time. Template fields are covered by the model/scenario/kwarg
25
+ product in `tests/test_parity.py`.
26
26
 
27
27
  | Renderer | Config class | Template fields | Renderer-only fields |
28
28
  | --- | --- | --- | --- |
@@ -27,7 +27,7 @@ dependencies = [
27
27
  # release through 0.5.12.post1 hard-pins ``openai-harmony==0.0.4``, so a
28
28
  # higher floor makes ``renderers`` uninstallable alongside SGLang. The
29
29
  # GptOssRenderer renders byte-identically on 0.0.4 (verified token-for-token
30
- # against 0.0.8) and ``tests/test_gpt_oss_harmony_parity.py`` passes on it,
30
+ # against 0.0.8) and the Harmony cells in ``tests/test_parity.py`` pass,
31
31
  # so the older harmony is safe.
32
32
  "openai-harmony>=0.0.4",
33
33
  # ``BaseRendererConfig`` inherits from ``pydantic_config.BaseConfig`` so
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.1.11.dev4'
22
- __version_tuple__ = version_tuple = (0, 1, 11, 'dev4')
21
+ __version__ = version = '0.1.11.dev5'
22
+ __version_tuple__ = version_tuple = (0, 1, 11, 'dev5')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -0,0 +1,59 @@
1
+ """Shared fixtures for renderer tests.
2
+
3
+ Each (model_name, renderer_name) pair gets a tokenizer + renderer.
4
+ The same barrage of tests runs against every pair.
5
+ """
6
+
7
+ from pathlib import Path
8
+
9
+ import pytest
10
+ from parity import models_for
11
+ from renderers import create_renderer
12
+ from renderers.base import load_tokenizer
13
+ from renderers.configs import config_from_name
14
+
15
+ # Backwards-compatible view used by documentation and a few invariant tests.
16
+ RENDERER_MODELS = [(case.model, case.renderer) for case in models_for("shared")]
17
+
18
+ _cache: dict[str, tuple] = {}
19
+
20
+
21
+ def _load(model_name: str, renderer_name: str):
22
+ key = f"{model_name}:{renderer_name}"
23
+ if key not in _cache:
24
+ tokenizer = load_tokenizer(model_name)
25
+ renderer = create_renderer(tokenizer, config_from_name(renderer_name))
26
+ _cache[key] = (tokenizer, renderer)
27
+ return _cache[key]
28
+
29
+
30
+ def pytest_generate_tests(metafunc):
31
+ if "model_name" in metafunc.fixturenames:
32
+ filename = Path(str(metafunc.definition.path)).name
33
+ if filename == "test_build_helpers.py":
34
+ suite = "build-helpers"
35
+ elif filename in {
36
+ "test_parse_response.py",
37
+ "test_parse_response_robustness.py",
38
+ }:
39
+ suite = "plain-parser"
40
+ else:
41
+ suite = "shared"
42
+ cases = models_for(suite)
43
+ metafunc.parametrize(
44
+ "model_name,renderer_name",
45
+ [(case.model, case.renderer) for case in cases],
46
+ ids=[case.model for case in cases],
47
+ )
48
+
49
+
50
+ @pytest.fixture
51
+ def tokenizer(model_name, renderer_name):
52
+ t, _ = _load(model_name, renderer_name)
53
+ return t
54
+
55
+
56
+ @pytest.fixture
57
+ def renderer(model_name, renderer_name):
58
+ _, r = _load(model_name, renderer_name)
59
+ return r