fix(tool_parsing): require a pipe on the Qwen bare end marker (#5829)

The `end` branch of _QWEN_BARE_MARKER_RE had both pipes optional
(`\|?end\|?`), so it also matched a bare `end` between whitespace and
replaced it with a space. Messages containing Ruby, Lua or shell code that
closes a block with a lone `end` had those lines deleted, and ordinary prose
lost the word too.

Require at least one pipe so only real turn markers match; `|end`, `end|`,
`|end|` and `/|end|` strip exactly as before. Applied to the duplicated
pattern in static/js/chatRenderer.js as well.

Fixes #5547
This commit is contained in:
Husam
2026-08-07 19:33:14 +02:00
committed by GitHub
parent 36d4098421
commit f1e96d102e
3 changed files with 105 additions and 2 deletions
+5 -1
View File
@@ -187,8 +187,12 @@ _FUNCTION_MODEL_NAME_RE = re.compile(
_FUNCTION_MODEL_PARAMS_OPEN_RE = re.compile(r"<parameters>\s*", re.IGNORECASE)
_FUNCTION_MODEL_PARAMS_CLOSE_RE = re.compile(r"</parameters>", re.IGNORECASE)
_QWEN_ROLE_MARKER_RE = re.compile(r"</?\|(?:assistant|assistan|user|system|tool)\|>?|</\|end\|>?", re.IGNORECASE)
# At least one pipe is required around `end`. Both pipes used to be optional
# (`\|?end\|?`), which also matched a bare `end` on its own line and deleted it
# from ordinary prose and from Ruby/Lua/shell snippets that close blocks with
# one; see #5547. `|end`, `end|`, `|end|` and `/|end|` still strip as before.
_QWEN_BARE_MARKER_RE = re.compile(
r"(?:^|[\t\r\n ])(?:\|?end\|?|/?\|end\|)(?=[\t\r\n ]|$)|"
r"(?:^|[\t\r\n ])(?:/?\|end\||\|end|end\|)(?=[\t\r\n ]|$)|"
r"(?:^|[\t\r\n ])assistan(?:t)?(?=[\t\r\n ]|$)",
re.IGNORECASE,
)