[GH-ISSUE #24634] issue: <details type="tool_calls"> tag not rendered, displayed as raw text #74969

Open
opened 2026-05-13 07:49:26 -05:00 by GiteaMirror · 5 comments
Owner

Originally created by @sharyuke on GitHub (May 13, 2026).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/24634

Bug Report

Check Existing Issues

  • I have searched for any existing and/or related issues.
  • I have searched for any existing and/or related discussions.
  • I have also searched in the CLOSED issues AND CLOSED discussions and found no related items.
  • I am using the latest version of Open WebUI.

Installation Method

Docker

Open WebUI Version

latest (please specify your version)

Operating System

Linux

Expected Behavior

When MiniMax series models (e.g., MiniMax-M2.7-highspeed, MiniMax-M2.1) output tool calls using <details type="tool_calls"> HTML tags, OpenWebUI should render them as collapsible/expandable UI components, not display raw HTML tags as plain text.

Actual Behavior

The <details type="tool_calls" done="true" id="call_function_xxx"> tag is displayed as raw text at the top of the response. The <summary> content and the closing </details> tag are similarly shown as plain text instead of being rendered as an interactive collapsible section. The tool call content (JSON payload) is also exposed as raw text.

Example raw output visible to user:

<details type="tool_calls" done="true" id="call_function_xxx">
<summary>replace_file_content</summary>
{"file_path": "...", "old_string": "...", "new_string": "..."}
</details>

The details tag appears as a large heading at the top of the response, completely unstyled and unparsed.

Steps to Reproduce

  1. Connect MiniMax-M2.7-highspeed (or MiniMax-M2.1) model to OpenWebUI via OpenAI-compatible API
  2. Enable tool calling / function calling feature
  3. Send a prompt that triggers a tool call (e.g., ask the model to edit a file)
  4. Observe that <details type="tool_calls"> tags are rendered as raw text instead of collapsible UI components

Logs & Screenshots

Screenshot attached showing raw <details type="tool_calls"> tag output from MiniMax-M2.7-highspeed model.

Additional Information

  • This is different from PR #21050 which deals with unclosed </details> tags for reasoning/thinking content (where </details> appears at the start of a new text block due to improper tag closing before tool calls)
  • This issue is specifically about details type="tool_calls" tags which are used by MiniMax models to encapsulate function calling output
  • The tags are properly formed (matching open/close tags), but OpenWebUI does not parse them as HTML — they are treated as plain text
  • This appears to be a parsing/filtering issue where the details tag with type="tool_calls" is not recognized as a valid HTML tag that should be rendered, and instead gets passed through as raw text
Originally created by @sharyuke on GitHub (May 13, 2026). Original GitHub issue: https://github.com/open-webui/open-webui/issues/24634 ## Bug Report ### Check Existing Issues - [x] I have searched for any existing and/or related issues. - [x] I have searched for any existing and/or related discussions. - [x] I have also searched in the CLOSED issues AND CLOSED discussions and found no related items. - [x] I am using the latest version of Open WebUI. ### Installation Method Docker ### Open WebUI Version latest (please specify your version) ### Operating System Linux ### Expected Behavior When MiniMax series models (e.g., MiniMax-M2.7-highspeed, MiniMax-M2.1) output tool calls using `<details type="tool_calls">` HTML tags, OpenWebUI should render them as collapsible/expandable UI components, not display raw HTML tags as plain text. ### Actual Behavior The `<details type="tool_calls" done="true" id="call_function_xxx">` tag is displayed as **raw text at the top of the response**. The `<summary>` content and the closing `</details>` tag are similarly shown as plain text instead of being rendered as an interactive collapsible section. The tool call content (JSON payload) is also exposed as raw text. Example raw output visible to user: ``` <details type="tool_calls" done="true" id="call_function_xxx"> <summary>replace_file_content</summary> {"file_path": "...", "old_string": "...", "new_string": "..."} </details> ``` The `details` tag appears as a large heading at the top of the response, completely unstyled and unparsed. ### Steps to Reproduce 1. Connect MiniMax-M2.7-highspeed (or MiniMax-M2.1) model to OpenWebUI via OpenAI-compatible API 2. Enable tool calling / function calling feature 3. Send a prompt that triggers a tool call (e.g., ask the model to edit a file) 4. Observe that `<details type="tool_calls">` tags are rendered as raw text instead of collapsible UI components ### Logs & Screenshots Screenshot attached showing raw `<details type="tool_calls">` tag output from MiniMax-M2.7-highspeed model. ### Additional Information - This is different from PR #21050 which deals with unclosed `</details>` tags for reasoning/thinking content (where `</details>` appears at the start of a new text block due to improper tag closing before tool calls) - This issue is specifically about `details type="tool_calls"` tags which are used by MiniMax models to encapsulate function calling output - The tags are properly formed (matching open/close tags), but OpenWebUI does not parse them as HTML — they are treated as plain text - This appears to be a parsing/filtering issue where the `details` tag with `type="tool_calls"` is not recognized as a valid HTML tag that should be rendered, and instead gets passed through as raw text
Author
Owner

@sharyuke commented on GitHub (May 13, 2026):

Screenshot

tool_calls raw text

Image
<!-- gh-comment-id:4436324425 --> @sharyuke commented on GitHub (May 13, 2026): ## Screenshot ![tool_calls raw text](https://raw.githubusercontent.com/sharyuke/open-webui/main/.github/images/issue-24634-screenshot.png) <img width="588" height="1280" alt="Image" src="https://github.com/user-attachments/assets/5ad5ba73-cb81-4de3-9653-aed036b2b971" />
Author
Owner

@owui-terminator[bot] commented on GitHub (May 13, 2026):

🔍 Related Issues Found

I found some existing issues that might be related. Please check if any of these are duplicates or contain helpful solutions:

  1. 🟣 #24291 Minimax tool_call not working
    This is the closest Minimax-specific tool-calling issue. It confirms Open WebUI has compatibility problems with Minimax tool_call output, which is likely the same integration area causing the <details type="tool_calls"> markup to be mishandled.
    by sharyuke

  2. 🟣 #21860 issue: Inconsistent HTML Rendering: Escaped in Chat, Rendered in Notification
    This issue is about inconsistent HTML rendering versus escaping in chat, which is directly relevant to a report where a <details> block is being shown as raw text instead of being rendered or consistently processed.
    by Mywk · bug

  3. 🟣 #20600 issue: Tool call results not decoded from HTML entities before sending to LLM
    This bug concerns the processDetails() path and HTML-escaped tool-call content, which is part of the same tool-call rendering/parsing pipeline and may share the underlying issue of how tool-call markup is handled.
    by Koumi460 · bug, confirmed issue


💡 If your issue is a duplicate, please close it and add any additional details to the existing issue instead.

This comment was generated automatically. React with 👍 if helpful, 👎 if not.

<!-- gh-comment-id:4436325012 --> @owui-terminator[bot] commented on GitHub (May 13, 2026): <!-- terminator-bot:related-issues-reply --> 🔍 **Related Issues Found** I found some existing issues that might be related. Please check if any of these are duplicates or contain helpful solutions: 1. 🟣 [#24291](https://github.com/open-webui/open-webui/issues/24291) **Minimax tool_call not working** *This is the closest Minimax-specific tool-calling issue. It confirms Open WebUI has compatibility problems with Minimax tool_call output, which is likely the same integration area causing the `<details type="tool_calls">` markup to be mishandled.* *by sharyuke* 2. 🟣 [#21860](https://github.com/open-webui/open-webui/issues/21860) **issue: Inconsistent HTML Rendering: Escaped in Chat, Rendered in Notification** *This issue is about inconsistent HTML rendering versus escaping in chat, which is directly relevant to a report where a `<details>` block is being shown as raw text instead of being rendered or consistently processed.* *by Mywk · `bug`* 3. 🟣 [#20600](https://github.com/open-webui/open-webui/issues/20600) **issue: Tool call results not decoded from HTML entities before sending to LLM** *This bug concerns the `processDetails()` path and HTML-escaped tool-call content, which is part of the same tool-call rendering/parsing pipeline and may share the underlying issue of how tool-call markup is handled.* *by Koumi460 · `bug`, `confirmed issue`* --- 💡 If your issue is a duplicate, please close it and add any additional details to the existing issue instead. *This comment was generated automatically.* React with 👍 if helpful, 👎 if not.
Author
Owner

@siriusa51 commented on GitHub (May 13, 2026):

Same Root Cause Also Affects type="reasoning" Blocks

I have investigated this issue and identified the root cause. It also affects <details type="reasoning"> blocks (generated from <think> tags) in the same way.

Root Cause

The problem is in serialize_output() in backend/open_webui/utils/middleware.py.

The function collects all output items (text messages, reasoning blocks, tool calls) into a parts list, then joins them with:

return "".join(parts)

This concatenates text content and <details> blocks directly with no blank line separator:

previous text<details type="tool_calls" done="true" ...>

In Markdown, block-level elements (including <details>) must be preceded by a blank line (\n\n) to be recognized as a new block. Without it, marked's paragraph tokenizer absorbs the <details> tag into the preceding paragraph, preventing the custom details marked extension from ever being triggered.

When the custom extension is not triggered, marked falls back to its built-in HTML tokenizer, which produces an html token. In HTMLToken.svelte, this token is rendered via {token.text} (textContent interpolation), displaying the raw HTML string.

Fix

Change the join separator from "" to "\n\n" in serialize_output():

# Before:
return "".join(parts)

# After:
return "\n\n".join(parts)

This ensures a blank line exists between every block-level element, allowing marked's parser to correctly separate paragraphs from <details> blocks and route them to the custom details marked extension.

Affected Types

All <details> block types are affected:

  • type="reasoning" — from <think> tag processing
  • type="tool_calls" — from function/tool calling
  • type="code_interpreter" — from code execution
<!-- gh-comment-id:4436505583 --> @siriusa51 commented on GitHub (May 13, 2026): ## Same Root Cause Also Affects `type="reasoning"` Blocks I have investigated this issue and identified the root cause. It also affects `<details type="reasoning">` blocks (generated from `<think>` tags) in the same way. ### Root Cause The problem is in `serialize_output()` in `backend/open_webui/utils/middleware.py`. The function collects all output items (text messages, reasoning blocks, tool calls) into a `parts` list, then joins them with: ```python return "".join(parts) ``` This concatenates text content and `<details>` blocks directly with no blank line separator: ``` previous text<details type="tool_calls" done="true" ...> ``` In Markdown, block-level elements (including `<details>`) must be preceded by a blank line (`\n\n`) to be recognized as a new block. Without it, marked's paragraph tokenizer absorbs the `<details>` tag into the preceding paragraph, preventing the custom `details` marked extension from ever being triggered. When the custom extension is not triggered, marked falls back to its built-in HTML tokenizer, which produces an `html` token. In `HTMLToken.svelte`, this token is rendered via `{token.text}` (textContent interpolation), displaying the raw HTML string. ### Fix Change the join separator from `""` to `"\n\n"` in `serialize_output()`: ```python # Before: return "".join(parts) # After: return "\n\n".join(parts) ``` This ensures a blank line exists between every block-level element, allowing marked's parser to correctly separate paragraphs from `<details>` blocks and route them to the custom `details` marked extension. ### Affected Types All `<details>` block types are affected: - `type="reasoning"` — from `<think>` tag processing - `type="tool_calls"` — from function/tool calling - `type="code_interpreter"` — from code execution ### Related Code - `serialize_output`: https://github.com/open-webui/open-webui/blob/main/backend/open_webui/utils/middleware.py#L457 - Custom details marked extension: `src/lib/utils/marked/extension.ts` - HTML fallback renderer: `src/lib/components/chat/Messages/Markdown/HTMLToken.svelte`
Author
Owner

@sharyuke commented on GitHub (May 13, 2026):

Thanks for the detailed root cause analysis! I'll try the fix now.

<!-- gh-comment-id:4436522227 --> @sharyuke commented on GitHub (May 13, 2026): Thanks for the detailed root cause analysis! I'll try the fix now.
Author
Owner

@Classic298 commented on GitHub (May 13, 2026):

almost 100% certain this is a model or provider issue

<!-- gh-comment-id:4438303904 --> @Classic298 commented on GitHub (May 13, 2026): almost 100% certain this is a model or provider issue
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#74969