@@ -182,6 +182,33 @@ struct ChatTemplateTests {
182182 #expect( decoded == decodedTarget)
183183 }
184184
185+ /// https://github.com/huggingface/swift-transformers/issues/322
186+ @Test ( " Jinja block whitespace control " )
187+ func jinjaBlockWhitespaceControl( ) async throws {
188+ let tokenizer = try await Self . sharedPhiTokenizer ( )
189+ let whitespaceSensitiveTemplate = """
190+ {% for message in messages %}
191+ {% if message['role'] == 'user' %}
192+ {{ message['content'] }}
193+ {% endif %}
194+ {% endfor %}
195+ {% if add_generation_prompt %}
196+ assistant
197+ {% endif %}
198+ """
199+ let encoded = try tokenizer. applyChatTemplate (
200+ messages: messages, chatTemplate: whitespaceSensitiveTemplate
201+ )
202+ let decoded = tokenizer. decode ( tokens: encoded)
203+ let expected = """
204+ Describe the Swift programming language.
205+ assistant
206+ """
207+ #expect( decoded == expected)
208+ #expect( !decoded. hasPrefix ( " \n " ) )
209+ #expect( !decoded. contains ( " \n \n " ) )
210+ }
211+
185212 @Test ( " Qwen 2.5 with tools functionality " )
186213 func qwen2_5WithTools( ) async throws {
187214 let tokenizer = try await makeTokenizer ( model: " mlx-community/Qwen2.5-7B-Instruct-4bit " )
@@ -284,7 +311,12 @@ struct ChatTemplateTests {
284311 decoded. hasPrefix ( expectedPromptStart) ,
285312 " Prompt should start with expected system message "
286313 )
287- #expect( decoded. hasSuffix ( expectedPromptEnd) , " Prompt should end with expected format " )
314+ #expect(
315+ decoded. trimmingCharacters ( in: . newlines) . hasSuffix (
316+ expectedPromptEnd. trimmingCharacters ( in: . newlines)
317+ ) ,
318+ " Prompt should end with expected format "
319+ )
288320 }
289321
290322 /// Test for vision models with a vision chat template in chat_template.json
0 commit comments