Skip to content

Support Jinja2 implicit adjacent string-literal concatenation in minja - #1095

Merged
sayanshaw24 merged 1 commit into
mainfrom
jiafa/minja-string-literal-concat
Jul 23, 2026
Merged

Support Jinja2 implicit adjacent string-literal concatenation in minja#1095
sayanshaw24 merged 1 commit into
mainfrom
jiafa/minja-string-literal-concat

Conversation

@jiafatom

Copy link
Copy Markdown
Contributor

Problem

Jinja2 (like Python) implicitly concatenates adjacent string literals, e.g. {{ "foo" "bar" }} renders as foobar. minja's parseConstant only consumed a single string literal, so it threw Expected closing parenthesis in call args whenever a template placed two string literals next to each other.

This breaks real, valid templates. For example google/gemma-4-E2B-it's chat_template.jinja splits a long raise_exception(...) message across adjacent string literals:

{{- raise_exception("chat_template: tool_calls[].function.arguments must be a "
                    "JSON object (mapping), not a string. Deserialize arguments "
                    "before passing to the template.") -}}

minja::Parser::parse() fails at that line, so the entire template is rejected and OrtxApplyChatTemplate (used by onnxruntime-genai) becomes unusable for the model.

Before (parsing the Gemma-4 template):

PARSE FAILED: Expected closing parenthesis in call args at row 259, column 29

After: PARSE OK.

Fix

In parseConstant, after reading a string literal, loop and merge any run of consecutive string literals into a single constant — matching Jinja2/Python semantics. parseString() already skips leading whitespace and returns nullptr when the next token is not a string literal, so the loop terminates naturally and does not affect any other expression form.

Test

Adds OrtxTokenizerTest.AdjacentStringLiteralConcatenation, covering single-line ("Hello, " "world" '!'), cross-newline, and mixed-quote concatenation. Also verified existing behavior is unaffected (explicit ~ concat, numbers, conditionals) via a standalone render harness.

Jinja2 (like Python) implicitly concatenates adjacent string literals,
e.g. `{{ "foo" "bar" }}` renders as `foobar`. minja's `parseConstant`
only consumed a single string literal, so it raised
"Expected closing parenthesis in call args" whenever a template placed
two string literals next to each other.

This breaks real, valid templates. For example google/gemma-4-E2B-it's
`chat_template.jinja` splits a long `raise_exception(...)` message across
adjacent string literals, which made the whole template fail to parse and
rendered `OrtxApplyChatTemplate` unusable for that model.

Merge any run of consecutive string literals into a single constant in
`parseConstant`, matching Jinja2/Python semantics. Adds a unit test
covering single-line, cross-newline, and mixed-quote concatenation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d58326c3-f1ef-497f-a288-3dfd4b0f05c6
@jiafatom
jiafatom requested a review from a team as a code owner July 23, 2026 19:36
Copilot AI review requested due to automatic review settings July 23, 2026 19:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the minja template parser to match Jinja2/Python behavior by implicitly concatenating adjacent string literals (e.g., {{ "foo" "bar" }}foobar). This fixes parsing of real-world Jinja templates that split long strings across multiple adjacent literals, enabling OrtxApplyChatTemplate to handle such templates successfully.

Changes:

  • Extend minja::Parser::parseConstant() to merge runs of consecutive string literals into a single constant value.
  • Add a tokenizer/chat-template regression test that validates same-line, newline-separated, and mixed-quote adjacent literal concatenation.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
test/pp_api_test/test_tokenizer_chat.cc Adds a regression test covering implicit adjacent string-literal concatenation via OrtxApplyChatTemplate.
shared/api/minja.hpp Implements Jinja2-style implicit concatenation by looping parseString() calls and appending consecutive literals.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@sayanshaw24
sayanshaw24 enabled auto-merge (squash) July 23, 2026 21:04
@sayanshaw24
sayanshaw24 merged commit 319f8d2 into main Jul 23, 2026
39 checks passed
@sayanshaw24
sayanshaw24 deleted the jiafa/minja-string-literal-concat branch July 23, 2026 21:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants