From c7f9d35b668eb22ce62bb601b5429ddf94a9de16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9B=9B=E9=87=8E?= <114060217+siye566@users.noreply.github.com> Date: Thu, 8 Oct 2026 20:59:50 +0800 Subject: [PATCH] fix(llm): preserve unrelated think-prefixed tags (#6505) * fix(llm): preserve unrelated think-prefixed tags * fix(llm): handle self-closing think tags consistently --------- Co-authored-by: Willem Jiang --- README.md | 2 + .../packages/harness/deerflow/utils/AGENTS.md | 8 ++ .../harness/deerflow/utils/llm_text.py | 34 +++++- backend/tests/test_think_tag_boundaries.py | 103 ++++++++++++++++++ 4 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 backend/tests/test_think_tag_boundaries.py diff --git a/README.md b/README.md index b89c200cd4..18f4f3d98f 100644 --- a/README.md +++ b/README.md @@ -1738,6 +1738,8 @@ Rebuild with `make up` after changing the managed extension set. See Gateway-generated follow-up suggestions now normalize both plain-string model output and block/list-style rich content before parsing the JSON array response, so provider-specific content wrappers do not silently drop suggestions. +Backend response cleanup preserves unrelated tag names such as `` and `` in follow-up suggestions and polished drafts; only the exact `` name (optionally followed by attributes) starts a reasoning block. Self-closing `` and `` tags are empty reasoning blocks and leave the following answer intact. + The Web UI composer can polish draft input before sending. The rewrite runs as a short Gateway LLM request using the `input_polish` model configuration, keeps slash skill prefixes such as `/data-analysis`, and only replaces the local draft after the user clicks the polish button; it does not create a thread run or persist a message. When the agent asks for clarification, the Web UI shows the structured response card but keeps the normal composer available. Users can complete the card or send a free-form chat message to bypass it; that message closes the latest pending clarification and becomes the agent's next input. Accompanying answer text stays outside the execution steps panel, and answering the request keeps previously completed text in the conversation while the agent continues. diff --git a/backend/packages/harness/deerflow/utils/AGENTS.md b/backend/packages/harness/deerflow/utils/AGENTS.md index e2cc85c86f..ca7e45eaa4 100644 --- a/backend/packages/harness/deerflow/utils/AGENTS.md +++ b/backend/packages/harness/deerflow/utils/AGENTS.md @@ -36,6 +36,14 @@ suffix. Keep its case-insensitive tag handling, optional whitespace before the closing `>`, and the `truncate_unclosed` behavior. Regression coverage lives in `tests/test_utils_llm_text.py`. +Opening reasoning tags require whitespace, `>`, or `/>` after the exact `think` +name; punctuated names such as ``, ``, and `` +are ordinary content. The shared prefix regex owns this boundary rule; do not +duplicate it in a manual re-check. Self-closing `` and `` tags +are empty reasoning blocks: remove the tag without consuming subsequent text. +Keep exact unfinished `