renderers 0.1.13.dev4__tar.gz → 0.1.13.dev7__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 (97) hide show
  1. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/PKG-INFO +2 -2
  2. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/README.md +1 -1
  3. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/docs/renderer-config.md +2 -2
  4. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/__init__.py +4 -0
  5. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/_version.py +2 -2
  6. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/base.py +9 -1
  7. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/client.py +17 -5
  8. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/configs.py +9 -0
  9. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/glm5.py +326 -35
  10. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/parity.py +5 -0
  11. renderers-0.1.13.dev7/tests/test_glm53_flash.py +624 -0
  12. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_reasoning_boundaries.py +2 -1
  13. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/.github/workflows/publish-dev.yml +0 -0
  14. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/.github/workflows/publish.yml +0 -0
  15. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/.github/workflows/style.yml +0 -0
  16. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/.github/workflows/test.yml +0 -0
  17. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/.gitignore +0 -0
  18. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/.pre-commit-config.yaml +0 -0
  19. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/LICENSE +0 -0
  20. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/examples/README.md +0 -0
  21. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/examples/sglang/multiturn_generate_sglang.py +0 -0
  22. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/examples/sglang/online_multiturn_sglang.py +0 -0
  23. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/examples/tinker/multiturn_generate_tinker.py +0 -0
  24. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/examples/transformers/multiturn_generate_transformers.py +0 -0
  25. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/examples/vllm/multiturn_generate_vllm.py +0 -0
  26. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/pyproject.toml +0 -0
  27. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/custom.py +0 -0
  28. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/deepseek_r1.py +0 -0
  29. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/deepseek_v3.py +0 -0
  30. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/deepseek_v4.py +0 -0
  31. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/default.py +0 -0
  32. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/gemma4.py +0 -0
  33. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/glm45.py +0 -0
  34. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/gpt_oss.py +0 -0
  35. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/hy3.py +0 -0
  36. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/inkling.py +0 -0
  37. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/kimi_k2.py +0 -0
  38. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/kimi_k25.py +0 -0
  39. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/laguna_s21.py +0 -0
  40. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/laguna_xs2.py +0 -0
  41. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/llama_3.py +0 -0
  42. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/minimax_m2.py +0 -0
  43. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/nemotron3.py +0 -0
  44. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/parsers.py +0 -0
  45. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/parsing.py +0 -0
  46. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/prime_qwen3.py +0 -0
  47. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/qwen3.py +0 -0
  48. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/qwen35.py +0 -0
  49. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/qwen36.py +0 -0
  50. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/qwen38.py +0 -0
  51. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/qwen3_vl.py +0 -0
  52. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/reasoning.py +0 -0
  53. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/renderers/tagged.py +0 -0
  54. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/audit_prefix_stability.py +0 -0
  55. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/conftest.py +0 -0
  56. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/fixtures/prefix_stability.json +0 -0
  57. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/reference_continuations.py +0 -0
  58. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/reference_rendering.py +0 -0
  59. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/replay.py +0 -0
  60. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_bridge.py +0 -0
  61. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_build_helpers.py +0 -0
  62. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_client.py +0 -0
  63. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_custom.py +0 -0
  64. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_deepseek_r1.py +0 -0
  65. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_deepseek_v4.py +0 -0
  66. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_disabled_thinking_stability.py +0 -0
  67. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_gemma4.py +0 -0
  68. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_glm_tool_name_validation.py +0 -0
  69. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_hy3.py +0 -0
  70. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_incremental.py +0 -0
  71. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_inkling.py +0 -0
  72. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_is_content.py +0 -0
  73. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_kimi_k25_tool_schema.py +0 -0
  74. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_laguna_m1.py +0 -0
  75. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_laguna_xs21.py +0 -0
  76. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_llama_3.py +0 -0
  77. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_load_tokenizer.py +0 -0
  78. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_message_indices.py +0 -0
  79. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_message_tool_names.py +0 -0
  80. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_multimodal.py +0 -0
  81. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_nemotron35_vlm.py +0 -0
  82. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_nemotron3_ultra.py +0 -0
  83. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_offsetless_tokenizers.py +0 -0
  84. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_parity.py +0 -0
  85. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_parse_response.py +0 -0
  86. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_parse_response_robustness.py +0 -0
  87. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_parsers.py +0 -0
  88. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_preserve_thinking.py +0 -0
  89. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_qwen35_size_coverage.py +0 -0
  90. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_qwen38.py +0 -0
  91. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_renderer_config.py +0 -0
  92. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_roundtrip.py +0 -0
  93. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_sampled_mask.py +0 -0
  94. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_tagged_rollout.py +0 -0
  95. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_tokens_per_message.py +0 -0
  96. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/tests/test_tool_arg_type_preservation.py +0 -0
  97. {renderers-0.1.13.dev4 → renderers-0.1.13.dev7}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: renderers
3
- Version: 0.1.13.dev4
3
+ Version: 0.1.13.dev7
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
@@ -114,7 +114,7 @@ next_prompt_ids = r.bridge_to_next_turn(
114
114
  )
115
115
  ```
116
116
 
117
- Hand-coded renderers ship for `qwen3`, `qwen3-vl`, `qwen3.5`, `qwen3.6`, `qwen3.8`, `gemma4`, `glm-5`, `glm-5.1`, `glm-5.3`, `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).
117
+ Hand-coded renderers ship for `qwen3`, `qwen3-vl`, `qwen3.5`, `qwen3.6`, `qwen3.8`, `gemma4`, `glm-5`, `glm-5.1`, `glm-5.3`, `glm-5.3-flash`, `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`, `glm-5.3-flash`, `kimi-k2.5` / `kimi-k2.6`, and the Inkling checkpoints are multimodal (Inkling handles both image **and** audio; `glm-5.3-flash` renders images only with `process_multimodal=False`).
118
118
 
119
119
  ## API
120
120
 
@@ -94,7 +94,7 @@ next_prompt_ids = r.bridge_to_next_turn(
94
94
  )
95
95
  ```
96
96
 
97
- Hand-coded renderers ship for `qwen3`, `qwen3-vl`, `qwen3.5`, `qwen3.6`, `qwen3.8`, `gemma4`, `glm-5`, `glm-5.1`, `glm-5.3`, `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).
97
+ Hand-coded renderers ship for `qwen3`, `qwen3-vl`, `qwen3.5`, `qwen3.6`, `qwen3.8`, `gemma4`, `glm-5`, `glm-5.1`, `glm-5.3`, `glm-5.3-flash`, `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`, `glm-5.3-flash`, `kimi-k2.5` / `kimi-k2.6`, and the Inkling checkpoints are multimodal (Inkling handles both image **and** audio; `glm-5.3-flash` renders images only with `process_multimodal=False`).
98
98
 
99
99
  ## API
100
100
 
@@ -34,7 +34,7 @@ product in `tests/test_parity.py`.
34
34
  | Qwen3-VL | `Qwen3VLRendererConfig` | `add_vision_id` | `image_cache_max` |
35
35
  | Gemma 4 | `Gemma4RendererConfig` | `enable_thinking`, `preserve_thinking` | `image_cache_max` |
36
36
  | GLM-5 / 5.1 | `GLM5RendererConfig` / `GLM51RendererConfig` | `enable_thinking`, `clear_thinking` | - |
37
- | GLM-5.3 | `GLM53RendererConfig` | `clear_thinking`, `reasoning_effort` | - |
37
+ | GLM-5.3 / 5.3 Flash | `GLM53RendererConfig` / `GLM53FlashRendererConfig` | `clear_thinking`, `reasoning_effort` | - |
38
38
  | GLM-4.5 | `GLM45RendererConfig` | `enable_thinking` | - |
39
39
  | gpt-oss | `GptOssRendererConfig` | `reasoning_effort`, `conversation_start_date` | `use_system_prompt`, `knowledge_cutoff`, `model_identity`, `auto_drop_analysis` |
40
40
  | Hy3 | `Hy3RendererConfig` | `reasoning_effort`, `preserved_thinking`, `is_training`, `raw_last_assistant`, `fallback_strategy` | - |
@@ -141,7 +141,7 @@ the knobs its template actually exposes:
141
141
  | Qwen3.8 | `preserve_thinking=True -> all`; else `enable_thinking=False -> all`; else `tool_cycle` |
142
142
  | Gemma 4 | `preserve_thinking=True -> all`; else `enable_thinking=False -> all`; else `tool_cycle` |
143
143
  | GLM-5 / 5.1 | `clear_thinking=False -> all`; else `enable_thinking=False -> all`; else `tool_cycle` |
144
- | GLM-5.3 | `clear_thinking=False -> all`, else `tool_cycle` |
144
+ | GLM-5.3 / 5.3 Flash | `clear_thinking=False -> all`, else `tool_cycle` |
145
145
  | GLM-4.5 | `enable_thinking=False -> all`, else `tool_cycle` |
146
146
  | gpt-oss | `auto_drop_analysis=False -> all`, else `tool_cycle` |
147
147
  | Hy3 | `preserved_thinking=True -> all`, else `tool_cycle` |
@@ -55,6 +55,7 @@ from renderers.configs import (
55
55
  GLM5RendererConfig,
56
56
  GLM45RendererConfig,
57
57
  GLM51RendererConfig,
58
+ GLM53FlashRendererConfig,
58
59
  GLM53RendererConfig,
59
60
  GptOssRendererConfig,
60
61
  Hy3RendererConfig,
@@ -95,6 +96,7 @@ _LAZY_RENDERERS: dict[str, str] = {
95
96
  "DefaultRenderer": "renderers.default",
96
97
  "GLM45Renderer": "renderers.glm45",
97
98
  "GLM51Renderer": "renderers.glm5",
99
+ "GLM53FlashRenderer": "renderers.glm5",
98
100
  "GLM53Renderer": "renderers.glm5",
99
101
  "GLM5Renderer": "renderers.glm5",
100
102
  "GptOssRenderer": "renderers.gpt_oss",
@@ -155,6 +157,8 @@ __all__ = [
155
157
  "GLM45RendererConfig",
156
158
  "GLM51Renderer",
157
159
  "GLM51RendererConfig",
160
+ "GLM53FlashRenderer",
161
+ "GLM53FlashRendererConfig",
158
162
  "GLM53Renderer",
159
163
  "GLM53RendererConfig",
160
164
  "GLM5Renderer",
@@ -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.13.dev4'
22
- __version_tuple__ = version_tuple = (0, 1, 13, 'dev4')
21
+ __version__ = version = '0.1.13.dev7'
22
+ __version_tuple__ = version_tuple = (0, 1, 13, 'dev7')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -1012,6 +1012,8 @@ MODEL_RENDERER_MAP: dict[str, str] = {
1012
1012
  "zai-org/GLM-5.1": "glm-5.1",
1013
1013
  "zai-org/GLM-5.3": "glm-5.3",
1014
1014
  "zai-org/GLM-5.3-BF16": "glm-5.3",
1015
+ "zai-org/GLM-5.3-Flash": "glm-5.3-flash",
1016
+ "zai-org/GLM-5.3-Flash-BF16": "glm-5.3-flash",
1015
1017
  # GLM-4.5.
1016
1018
  "THUDM/GLM-4.5-Air": "glm-4.5",
1017
1019
  "zai-org/GLM-4.5-Air": "glm-4.5",
@@ -1353,7 +1355,12 @@ def _populate_registry():
1353
1355
  from renderers.deepseek_v4 import DeepSeekV4Renderer
1354
1356
  from renderers.default import DefaultRenderer
1355
1357
  from renderers.gemma4 import Gemma4Renderer
1356
- from renderers.glm5 import GLM5Renderer, GLM51Renderer, GLM53Renderer
1358
+ from renderers.glm5 import (
1359
+ GLM5Renderer,
1360
+ GLM51Renderer,
1361
+ GLM53FlashRenderer,
1362
+ GLM53Renderer,
1363
+ )
1357
1364
  from renderers.glm45 import GLM45Renderer
1358
1365
  from renderers.gpt_oss import GptOssRenderer
1359
1366
  from renderers.hy3 import Hy3Renderer
@@ -1393,6 +1400,7 @@ def _populate_registry():
1393
1400
  "glm-5": GLM5Renderer,
1394
1401
  "glm-5.1": GLM51Renderer,
1395
1402
  "glm-5.3": GLM53Renderer,
1403
+ "glm-5.3-flash": GLM53FlashRenderer,
1396
1404
  "glm-4.5": GLM45Renderer,
1397
1405
  "minimax-m2": MiniMaxM2Renderer,
1398
1406
  "deepseek-v3": DeepSeekV3Renderer,
@@ -261,9 +261,11 @@ async def generate(
261
261
  Returns a dict with: request_id, prompt_ids, renderer_prompt_ids,
262
262
  mm_placeholders, completion_ids, completion_logprobs, content,
263
263
  reasoning_content, tool_calls, finish_reason, routed_experts,
264
- multi_modal_data, prompt_attribution. ``renderer_prompt_ids`` is the
265
- unexpanded logical prompt when ``process_multimodal=False`` and ``None``
266
- otherwise.
264
+ weight_versions, multi_modal_data, prompt_attribution.
265
+ ``renderer_prompt_ids`` is the unexpanded logical prompt when
266
+ ``process_multimodal=False`` and ``None`` otherwise. ``weight_versions``
267
+ is vLLM's (>= 0.32) list of ``{version, start, end}`` spans over
268
+ completion-token indexes, or ``None`` when the engine labels none.
267
269
 
268
270
  ``prompt_attribution`` is the renderer's :class:`RenderedTokens` for
269
271
  the prompt — either the one this call computed via
@@ -336,7 +338,9 @@ async def generate(
336
338
  "token_ids": prompt_ids,
337
339
  "sampling_params": sp,
338
340
  }
339
- content_parts = _content_parts(messages) if not process_multimodal else None
341
+ content_parts = (
342
+ _content_parts(messages, renderer=renderer) if not process_multimodal else None
343
+ )
340
344
  features = (
341
345
  _build_mm_features(renderer, mm_data)
342
346
  if process_multimodal and mm_data and not mm_data.is_empty()
@@ -429,6 +433,7 @@ async def generate(
429
433
  "reasoning_complete": parsed.reasoning_complete,
430
434
  "routed_experts": routed_experts,
431
435
  "sampling_mask": sampling_mask,
436
+ "weight_versions": choice.get("weight_versions"),
432
437
  # The mm sidecar consumed on the request side, surfaced back so
433
438
  # callers can persist it on the trajectory step for downstream
434
439
  # multi-turn bridging and training-sample construction.
@@ -454,8 +459,15 @@ _MEDIA_URL_TYPES = {
454
459
  }
455
460
 
456
461
 
457
- def _content_parts(messages: list[Message]) -> list[dict[str, Any]]:
462
+ def _content_parts(
463
+ messages: list[Message], *, renderer: Renderer
464
+ ) -> list[dict[str, Any]]:
458
465
  """Flatten raw media in prompt order for vLLM's token generate endpoint."""
466
+ # Some templates reorder tool results. Use the same order for raw media,
467
+ # including when the caller supplies a prebuilt prompt and skips rendering.
468
+ order_messages = getattr(renderer, "messages_in_prompt_order", None)
469
+ if order_messages is not None:
470
+ messages = order_messages(messages)
459
471
  parts: list[dict[str, Any]] = []
460
472
  for message in messages:
461
473
  content = message.get("content")
@@ -434,6 +434,12 @@ class GLM53RendererConfig(BaseRendererConfig):
434
434
  return self
435
435
 
436
436
 
437
+ class GLM53FlashRendererConfig(GLM53RendererConfig):
438
+ """GLM-5.3 Flash renderer config. GLM-5.3's template surface, plus images."""
439
+
440
+ name: Literal["glm-5.3-flash"] = "glm-5.3-flash"
441
+
442
+
437
443
  class GLM45RendererConfig(BaseRendererConfig):
438
444
  """GLM-4.5 Air renderer config."""
439
445
 
@@ -1042,6 +1048,7 @@ RendererConfig = Annotated[
1042
1048
  GLM5RendererConfig,
1043
1049
  GLM51RendererConfig,
1044
1050
  GLM53RendererConfig,
1051
+ GLM53FlashRendererConfig,
1045
1052
  GLM45RendererConfig,
1046
1053
  GptOssRendererConfig,
1047
1054
  Hy3RendererConfig,
@@ -1091,6 +1098,7 @@ _CONFIG_BY_NAME: dict[str, type[BaseRendererConfig]] = {
1091
1098
  "glm-5": GLM5RendererConfig,
1092
1099
  "glm-5.1": GLM51RendererConfig,
1093
1100
  "glm-5.3": GLM53RendererConfig,
1101
+ "glm-5.3-flash": GLM53FlashRendererConfig,
1094
1102
  "glm-4.5": GLM45RendererConfig,
1095
1103
  "gpt-oss": GptOssRendererConfig,
1096
1104
  "hy3": Hy3RendererConfig,
@@ -1144,6 +1152,7 @@ __all__ = [
1144
1152
  "DeepSeekV4RendererConfig",
1145
1153
  "GLM45RendererConfig",
1146
1154
  "GLM51RendererConfig",
1155
+ "GLM53FlashRendererConfig",
1147
1156
  "GLM53RendererConfig",
1148
1157
  "GLM5RendererConfig",
1149
1158
  "Gemma4RendererConfig",