From 818cf61e9149c3fdff302cddbb2d026090160aea Mon Sep 17 00:00:00 2001 From: Reid <61492567+reidliu41@users.noreply.github.com> Date: Mon, 20 Jul 2026 17:39:13 +0800 Subject: [PATCH] [Rust Frontend] Fix macro-based content format detection (#49042) Signed-off-by: reidliu41 --- rust/src/chat/src/renderer/hf/format.rs | 17 ++++++++++++++--- rust/src/chat/src/renderer/hf/mod.rs | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/rust/src/chat/src/renderer/hf/format.rs b/rust/src/chat/src/renderer/hf/format.rs index f419b9e3a0c..e8e9f6412bb 100644 --- a/rust/src/chat/src/renderer/hf/format.rs +++ b/rust/src/chat/src/renderer/hf/format.rs @@ -236,9 +236,10 @@ fn has_content_item_loop(root: &Stmt<'_>) -> bool { loops.into_iter().any(|loop_ast| { matches!(loop_ast.target, Expr::Var(_)) - && message_varnames - .iter() - .any(|varname| is_var_or_elems_access(&loop_ast.iter, varname, Some("content"))) + && (is_var_access(&loop_ast.iter, "content") + || message_varnames.iter().any(|varname| { + is_var_or_elems_access(&loop_ast.iter, varname, Some("content")) + })) }) } @@ -315,6 +316,16 @@ mod tests { ); } + #[test] + fn detects_openai_template_with_content_parameter_loop() { + assert_eq!( + detect( + "{% macro render(content) %}{% for item in content %}{{ item }}{% endfor %}{% endmacro %}{% for message in messages %}{{ render(message.content) }}{% endfor %}" + ), + ChatTemplateContentFormat::OpenAi + ); + } + #[test] fn detects_openai_template_with_messages_alias() { assert_eq!( diff --git a/rust/src/chat/src/renderer/hf/mod.rs b/rust/src/chat/src/renderer/hf/mod.rs index 7ba2a2ccc03..cfbc3f924a3 100644 --- a/rust/src/chat/src/renderer/hf/mod.rs +++ b/rust/src/chat/src/renderer/hf/mod.rs @@ -1309,6 +1309,26 @@ mod tests { .assert_eq(&rendered); } + #[test] + fn qwen35_template_auto_detects_openai_multimodal_content() { + let mut request = image_request(); + request.chat_options.generation_prompt_mode = GenerationPromptMode::NoGenerationPrompt; + + let rendered = render_mm( + QWEN3_5_0_8B_TEMPLATE, + &request, + ChatTemplateContentFormatOption::Auto, + ) + .unwrap(); + + expect![[r#" + Text( + "<|im_start|>user\na<|vision_start|><|image_pad|><|vision_end|>b<|im_end|>\n", + ) + "#]] + .assert_debug_eq(&rendered.prompt); + } + #[test] fn qwen35_template_renders_closed_empty_reasoning_span_when_thinking_disabled() { let mut request = sample_request(vec![ChatMessage::text(ChatRole::User, "hello")]);