renderers 0.1.11.dev3__tar.gz → 0.1.11.dev4__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 (89) hide show
  1. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/PKG-INFO +2 -2
  2. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/README.md +1 -1
  3. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/docs/renderer-config.md +2 -0
  4. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/__init__.py +4 -0
  5. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/_version.py +2 -2
  6. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/base.py +5 -0
  7. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/configs.py +44 -0
  8. renderers-0.1.11.dev4/renderers/deepseek_v4.py +859 -0
  9. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/parsing.py +190 -0
  10. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/conftest.py +5 -0
  11. renderers-0.1.11.dev4/tests/reference_rendering.py +414 -0
  12. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_bridge.py +1 -0
  13. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_build_helpers.py +3 -14
  14. renderers-0.1.11.dev4/tests/test_deepseek_v4.py +565 -0
  15. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_render_ids.py +6 -15
  16. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_renderer_config_parity.py +22 -26
  17. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_roundtrip.py +1 -0
  18. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/.github/workflows/publish-dev.yml +0 -0
  19. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/.github/workflows/publish.yml +0 -0
  20. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/.github/workflows/style.yml +0 -0
  21. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/.github/workflows/test.yml +0 -0
  22. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/.gitignore +0 -0
  23. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/.pre-commit-config.yaml +0 -0
  24. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/LICENSE +0 -0
  25. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/examples/README.md +0 -0
  26. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/examples/sglang/multiturn_generate_sglang.py +0 -0
  27. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/examples/sglang/online_multiturn_sglang.py +0 -0
  28. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/examples/tinker/multiturn_generate_tinker.py +0 -0
  29. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/examples/transformers/multiturn_generate_transformers.py +0 -0
  30. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/examples/vllm/multiturn_generate_vllm.py +0 -0
  31. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/pyproject.toml +0 -0
  32. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/client.py +0 -0
  33. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/deepseek_r1.py +0 -0
  34. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/deepseek_v3.py +0 -0
  35. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/default.py +0 -0
  36. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/gemma4.py +0 -0
  37. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/glm45.py +0 -0
  38. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/glm5.py +0 -0
  39. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/gpt_oss.py +0 -0
  40. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/hy3.py +0 -0
  41. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/inkling.py +0 -0
  42. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/kimi_k2.py +0 -0
  43. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/kimi_k25.py +0 -0
  44. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/laguna_s21.py +0 -0
  45. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/laguna_xs2.py +0 -0
  46. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/llama_3.py +0 -0
  47. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/minimax_m2.py +0 -0
  48. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/nemotron3.py +0 -0
  49. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/parsers.py +0 -0
  50. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/prime_qwen3.py +0 -0
  51. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/qwen3.py +0 -0
  52. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/qwen35.py +0 -0
  53. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/qwen36.py +0 -0
  54. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/qwen38.py +0 -0
  55. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/renderers/qwen3_vl.py +0 -0
  56. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_client.py +0 -0
  57. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_deepseek_r1.py +0 -0
  58. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_disabled_thinking_stability.py +0 -0
  59. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_gemma4.py +0 -0
  60. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_glm_tool_name_validation.py +0 -0
  61. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_gpt_oss_harmony_parity.py +0 -0
  62. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_hy3.py +0 -0
  63. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_incremental.py +0 -0
  64. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_inkling.py +0 -0
  65. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_is_content.py +0 -0
  66. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_kimi_k25_tool_schema.py +0 -0
  67. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_laguna_m1.py +0 -0
  68. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_laguna_s21.py +0 -0
  69. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_laguna_xs21.py +0 -0
  70. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_llama_3.py +0 -0
  71. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_load_tokenizer.py +0 -0
  72. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_message_indices.py +0 -0
  73. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_message_tool_names.py +0 -0
  74. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_multimodal.py +0 -0
  75. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_nemotron3_parity.py +0 -0
  76. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_nemotron3_ultra.py +0 -0
  77. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_offsetless_tokenizers.py +0 -0
  78. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_parse_response.py +0 -0
  79. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_parse_response_robustness.py +0 -0
  80. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_parsers.py +0 -0
  81. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_preserve_thinking.py +0 -0
  82. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_prime_qwen3_parity.py +0 -0
  83. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_qwen35_size_coverage.py +0 -0
  84. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_qwen38.py +0 -0
  85. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_renderer_config.py +0 -0
  86. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_sampled_mask.py +0 -0
  87. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_tokens_per_message.py +0 -0
  88. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/tests/test_tool_arg_type_preservation.py +0 -0
  89. {renderers-0.1.11.dev3 → renderers-0.1.11.dev4}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: renderers
3
- Version: 0.1.11.dev3
3
+ Version: 0.1.11.dev4
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
@@ -77,7 +77,7 @@ next_prompt_ids = r.bridge_to_next_turn(
77
77
  )
78
78
  ```
79
79
 
80
- Hand-coded renderers ship for `qwen3`, `qwen3-vl`, `qwen3.5`, `qwen3.6`, `qwen3.8`, `gemma4`, `glm-5`, `glm-5.1`, `glm-4.5`, `minimax-m2`, `deepseek-v3`, `deepseek-r1`, `kimi-k2`, `kimi-k2.5` / `kimi-k2.6`, `laguna-xs.2`, `laguna-xs-2.1`, `laguna-s-2.1`, `laguna-m.1`, `nemotron-3`, `nemotron-3-ultra`, `nemotron-3.5`, `llama-3`, `gpt-oss`, `hy3`, `inkling` / `inkling-small`, and `prime-qwen3`. Anything else falls back to `DefaultRenderer`, a generic `apply_chat_template` wrapper. `qwen3-vl`, `qwen3.5`, `qwen3.6`, `qwen3.8`, `gemma4`, `kimi-k2.5` / `kimi-k2.6`, and the Inkling checkpoints are multimodal (Inkling handles both image **and** audio).
80
+ Hand-coded renderers ship for `qwen3`, `qwen3-vl`, `qwen3.5`, `qwen3.6`, `qwen3.8`, `gemma4`, `glm-5`, `glm-5.1`, `glm-4.5`, `minimax-m2`, `deepseek-v3`, `deepseek-r1`, `deepseek-v4` (V4 Flash 0731), `kimi-k2`, `kimi-k2.5` / `kimi-k2.6`, `laguna-xs.2`, `laguna-xs-2.1`, `laguna-s-2.1`, `laguna-m.1`, `nemotron-3`, `nemotron-3-ultra`, `nemotron-3.5`, `llama-3`, `gpt-oss`, `hy3`, `inkling` / `inkling-small`, and `prime-qwen3`. Anything else falls back to `DefaultRenderer`, a generic `apply_chat_template` wrapper. `qwen3-vl`, `qwen3.5`, `qwen3.6`, `qwen3.8`, `gemma4`, `kimi-k2.5` / `kimi-k2.6`, and the Inkling checkpoints are multimodal (Inkling handles both image **and** audio).
81
81
 
82
82
  ## API
83
83
 
@@ -57,7 +57,7 @@ next_prompt_ids = r.bridge_to_next_turn(
57
57
  )
58
58
  ```
59
59
 
60
- Hand-coded renderers ship for `qwen3`, `qwen3-vl`, `qwen3.5`, `qwen3.6`, `qwen3.8`, `gemma4`, `glm-5`, `glm-5.1`, `glm-4.5`, `minimax-m2`, `deepseek-v3`, `deepseek-r1`, `kimi-k2`, `kimi-k2.5` / `kimi-k2.6`, `laguna-xs.2`, `laguna-xs-2.1`, `laguna-s-2.1`, `laguna-m.1`, `nemotron-3`, `nemotron-3-ultra`, `nemotron-3.5`, `llama-3`, `gpt-oss`, `hy3`, `inkling` / `inkling-small`, and `prime-qwen3`. Anything else falls back to `DefaultRenderer`, a generic `apply_chat_template` wrapper. `qwen3-vl`, `qwen3.5`, `qwen3.6`, `qwen3.8`, `gemma4`, `kimi-k2.5` / `kimi-k2.6`, and the Inkling checkpoints are multimodal (Inkling handles both image **and** audio).
60
+ Hand-coded renderers ship for `qwen3`, `qwen3-vl`, `qwen3.5`, `qwen3.6`, `qwen3.8`, `gemma4`, `glm-5`, `glm-5.1`, `glm-4.5`, `minimax-m2`, `deepseek-v3`, `deepseek-r1`, `deepseek-v4` (V4 Flash 0731), `kimi-k2`, `kimi-k2.5` / `kimi-k2.6`, `laguna-xs.2`, `laguna-xs-2.1`, `laguna-s-2.1`, `laguna-m.1`, `nemotron-3`, `nemotron-3-ultra`, `nemotron-3.5`, `llama-3`, `gpt-oss`, `hy3`, `inkling` / `inkling-small`, and `prime-qwen3`. Anything else falls back to `DefaultRenderer`, a generic `apply_chat_template` wrapper. `qwen3-vl`, `qwen3.5`, `qwen3.6`, `qwen3.8`, `gemma4`, `kimi-k2.5` / `kimi-k2.6`, and the Inkling checkpoints are multimodal (Inkling handles both image **and** audio).
61
61
 
62
62
  ## API
63
63
 
@@ -51,6 +51,7 @@ definition time. Template fields are covered by parity tests against
51
51
  | Nemotron-3.5 Lightning | `Nemotron35RendererConfig` | `enable_thinking`, `truncate_history_thinking` | - |
52
52
  | DeepSeek V3 | `DeepSeekV3RendererConfig` | - | - |
53
53
  | DeepSeek R1 | `DeepSeekR1RendererConfig` | - | - |
54
+ | DeepSeek V4 Flash 0731 | `DeepSeekV4RendererConfig` | `enable_thinking`, `drop_thinking`, `reasoning_effort` | - |
54
55
 
55
56
  Configs are frozen value objects. To override a field, construct a new instance
56
57
  or call `config.model_copy(update={...})`.
@@ -145,6 +146,7 @@ the knobs its template actually exposes:
145
146
  | Kimi K2.5 / 2.6 | `thinking=False -> all`, else `tool_cycle` |
146
147
  | Nemotron-3 / 3.5 | `truncate_history_thinking=False -> all`; else `enable_thinking=False -> all`; else `tool_cycle` |
147
148
  | DeepSeek R1 | `template` |
149
+ | DeepSeek V4 Flash 0731 | `enable_thinking=False` or `drop_thinking=False -> all`, else `tool_cycle` |
148
150
  | MiniMax M2 | `tool_cycle` |
149
151
  | DeepSeek V3, Qwen3-VL, Kimi K2, Laguna XS.2 / M.1 / XS-2.1 / S-2.1, Llama 3, Inkling | `all` |
150
152
  | PrimeIntellect Qwen3 | `all` |
@@ -48,6 +48,7 @@ from renderers.configs import (
48
48
  DefaultRendererConfig,
49
49
  DeepSeekR1RendererConfig,
50
50
  DeepSeekV3RendererConfig,
51
+ DeepSeekV4RendererConfig,
51
52
  GLM45RendererConfig,
52
53
  GLM51RendererConfig,
53
54
  GLM5RendererConfig,
@@ -85,6 +86,7 @@ from renderers.configs import (
85
86
  _LAZY_RENDERERS: dict[str, str] = {
86
87
  "DeepSeekR1Renderer": "renderers.deepseek_r1",
87
88
  "DeepSeekV3Renderer": "renderers.deepseek_v3",
89
+ "DeepSeekV4Renderer": "renderers.deepseek_v4",
88
90
  "DefaultRenderer": "renderers.default",
89
91
  "GLM45Renderer": "renderers.glm45",
90
92
  "GLM51Renderer": "renderers.glm5",
@@ -138,6 +140,8 @@ __all__ = [
138
140
  "DeepSeekR1RendererConfig",
139
141
  "DeepSeekV3Renderer",
140
142
  "DeepSeekV3RendererConfig",
143
+ "DeepSeekV4Renderer",
144
+ "DeepSeekV4RendererConfig",
141
145
  "DefaultRenderer",
142
146
  "DefaultRendererConfig",
143
147
  "GLM45Renderer",
@@ -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.dev3'
22
- __version_tuple__ = version_tuple = (0, 1, 11, 'dev3')
21
+ __version__ = version = '0.1.11.dev4'
22
+ __version_tuple__ = version_tuple = (0, 1, 11, 'dev4')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -982,6 +982,9 @@ MODEL_RENDERER_MAP: dict[str, str] = {
982
982
  # DeepSeek R1 (reasoning).
983
983
  "deepseek-ai/DeepSeek-R1": "deepseek-r1",
984
984
  "deepseek-ai/DeepSeek-R1-0528": "deepseek-r1",
985
+ # DeepSeek V4 Flash 0731 uses the repository's Python DSML encoder (the
986
+ # tokenizer intentionally ships no Jinja chat_template).
987
+ "deepseek-ai/DeepSeek-V4-Flash-0731": "deepseek-v4",
985
988
  # Kimi K2 (K2.5 and K2.6 share the K2.5 template, distinct from K2).
986
989
  "moonshotai/Kimi-K2-Instruct": "kimi-k2",
987
990
  "moonshotai/Kimi-K2.5": "kimi-k2.5",
@@ -1299,6 +1302,7 @@ def _populate_registry():
1299
1302
  return
1300
1303
  from renderers.deepseek_r1 import DeepSeekR1Renderer
1301
1304
  from renderers.deepseek_v3 import DeepSeekV3Renderer
1305
+ from renderers.deepseek_v4 import DeepSeekV4Renderer
1302
1306
  from renderers.default import DefaultRenderer
1303
1307
  from renderers.glm5 import GLM5Renderer, GLM51Renderer
1304
1308
  from renderers.glm45 import GLM45Renderer
@@ -1344,6 +1348,7 @@ def _populate_registry():
1344
1348
  "minimax-m2": MiniMaxM2Renderer,
1345
1349
  "deepseek-v3": DeepSeekV3Renderer,
1346
1350
  "deepseek-r1": DeepSeekR1Renderer,
1351
+ "deepseek-v4": DeepSeekV4Renderer,
1347
1352
  "hy3": Hy3Renderer,
1348
1353
  "inkling": InklingRenderer,
1349
1354
  "kimi-k2": KimiK2Renderer,
@@ -930,6 +930,47 @@ class DeepSeekR1RendererConfig(BaseRendererConfig):
930
930
  _template_fields = frozenset()
931
931
 
932
932
 
933
+ class DeepSeekV4RendererConfig(BaseRendererConfig):
934
+ """DeepSeek-V4-Flash-0731 reference-encoder configuration.
935
+
936
+ The checkpoint ships a Python encoder rather than a Jinja template. These
937
+ fields mirror its public controls: chat vs thinking mode, historical
938
+ reasoning dropping, and the opt-in thinking-effort prefix.
939
+ """
940
+
941
+ name: Literal["deepseek-v4"] = "deepseek-v4"
942
+ _template_fields = frozenset(
943
+ {"enable_thinking", "drop_thinking", "reasoning_effort"}
944
+ )
945
+
946
+ enable_thinking: bool = False
947
+ """Select thinking mode. ``False`` matches the official inference script."""
948
+
949
+ drop_thinking: bool = True
950
+ """Drop reasoning before the latest user query when no tools are present.
951
+
952
+ The reference encoder automatically preserves all reasoning whenever tools
953
+ are supplied, regardless of this value.
954
+ """
955
+
956
+ reasoning_effort: Literal["low", "high", "max"] = "low"
957
+ """Thinking-only effort prefix; ``low`` adds no text.
958
+
959
+ ``low`` is the checkpoint Python encoder's default. DeepSeek's hosted API
960
+ independently defaults its thinking effort to ``high``.
961
+ """
962
+
963
+ @model_validator(mode="after")
964
+ def _check_thinking_retention(self):
965
+ _reject_thinking_retention_conflict(
966
+ self,
967
+ "drop_thinking",
968
+ true_implies="tool_cycle",
969
+ false_implies="all",
970
+ )
971
+ return self
972
+
973
+
933
974
  RendererConfig = Annotated[
934
975
  Union[
935
976
  AutoRendererConfig,
@@ -960,6 +1001,7 @@ RendererConfig = Annotated[
960
1001
  Nemotron35RendererConfig,
961
1002
  DeepSeekV3RendererConfig,
962
1003
  DeepSeekR1RendererConfig,
1004
+ DeepSeekV4RendererConfig,
963
1005
  ],
964
1006
  Field(discriminator="name"),
965
1007
  ]
@@ -1006,6 +1048,7 @@ _CONFIG_BY_NAME: dict[str, type[BaseRendererConfig]] = {
1006
1048
  "nemotron-3.5": Nemotron35RendererConfig,
1007
1049
  "deepseek-v3": DeepSeekV3RendererConfig,
1008
1050
  "deepseek-r1": DeepSeekR1RendererConfig,
1051
+ "deepseek-v4": DeepSeekV4RendererConfig,
1009
1052
  }
1010
1053
 
1011
1054
 
@@ -1039,6 +1082,7 @@ __all__ = [
1039
1082
  "DefaultRendererConfig",
1040
1083
  "DeepSeekR1RendererConfig",
1041
1084
  "DeepSeekV3RendererConfig",
1085
+ "DeepSeekV4RendererConfig",
1042
1086
  "GLM45RendererConfig",
1043
1087
  "GLM51RendererConfig",
1044
1088
  "GLM5RendererConfig",