dify icon indicating copy to clipboard operation
dify copied to clipboard

fix: frontend for <think> tags conflicting with original <details> tags

Open junjiem opened this issue 10 months ago • 9 comments

Self Checks

  • [x] This is only for bug report, if you would like to ask a question, please head to Discussions.
  • [x] I have searched for existing issues search for existing issues, including closed ones.
  • [x] I confirm that I am using English to submit this report (我已阅读并同意 Language Policy).
  • [x] [FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)
  • [x] Please do not modify this template :) and fill in all the required fields.

Dify version

1.0

Cloud or Self Hosted

Self Hosted (Docker)

Steps to reproduce

Image

Image

The original <details> tags is rendered as a reasoning mode output thinking display.

✔️ Expected Behavior

Distinguish between the rendering of the tags and the original <details> tags.

❌ Actual Behavior

No response

junjiem avatar Feb 19 '25 11:02 junjiem

Hey @junjiem, I'm here to help you with bug fixes, questions, and becoming a contributor. Let's squash those bugs together! 🤖

To address the conflict between <think> tags and original <details> tags in the frontend rendering for a self-hosted Dify version 1.0 setup, you can modify the preprocessThinkTag function to handle the conversion more accurately. The current implementation replaces both <think> and <details> tags with <details>, which can cause conflicts if both tags are used in the content.

Here's a possible solution:

  1. Modify the preprocessThinkTag function to differentiate between <think> and <details> tags:
const preprocessThinkTag = (content: string) => {
  if (!(content.trim().startsWith('<think>\n') || content.trim().startsWith('<details style=')))
    return content

  return flow([
    (str: string) => str.replaceAll('<think>\n', '<details class="think">\n'),
    (str: string) => str.replaceAll('\n</think>', '\n[ENDTHINKFLAG]</details>'),
    (str: string) => str.replaceAll('\n</details>', '\n[ENDTHINKFLAG]</details>'),
  ])(content)
}
  1. Update the Markdown component to handle the new class for <details> tags that originated from <think> tags:
components={{
  code: CodeBlock,
  img: Img,
  video: VideoBlock,
  audio: AudioBlock,
  a: Link,
  p: Paragraph,
  button: MarkdownButton,
  form: MarkdownForm,
  script: ScriptBlock,
  details: ({ node, ...props }) => {
    if (node.properties?.className?.includes('think')) {
      return <ThinkBlock {...props} />
    }
    return <details {...props} />
  },
}}

This approach ensures that <think> tags are converted to <details> with a specific class, allowing you to handle them separately from original <details> tags [1].

To continue talking to Dosu, mention @dosu.


Help Dosu learn! Give it feedback: Great Response | Irrelevant Answer | Incorrect Sources | Too Verbose | Hallucination | Bug Report | Other

dosubot[bot] avatar Feb 19 '25 11:02 dosubot[bot]