-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix markdown request renderer #14211
fix markdown request renderer #14211
Conversation
240e143
to
0cb013f
Compare
// // eslint-disable-next-line no-null/no-null | ||
// const ref: React.MutableRefObject<HTMLDivElement | null> = useRef(null); | ||
|
||
// useEffect(() => { | ||
// const host = document.createElement('div'); | ||
// const html = this.markdownIt.render(response.content); | ||
// host.innerHTML = DOMPurify.sanitize(html, { | ||
// ALLOW_UNKNOWN_PROTOCOLS: true // DOMPurify usually strips non http(s) links from hrefs | ||
// }); | ||
// while (ref?.current?.firstChild) { | ||
// ref.current.removeChild(ref.current.firstChild); | ||
// } | ||
|
||
// ref?.current?.appendChild(host); | ||
// }, [response.content]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be removed
useEffect(() => { | ||
const markdownIt = markdownit(); | ||
const text = node.request.request.displayText ?? node.request.request.text; | ||
const host = document.createElement('div'); | ||
const html = markdownIt.render(text); | ||
host.innerHTML = DOMPurify.sanitize(html, { | ||
ALLOW_UNKNOWN_PROTOCOLS: true // DOMPurify usually strips non http(s) links from hrefs | ||
}); | ||
while (ref?.current?.firstChild) { | ||
ref.current.removeChild(ref.current.firstChild); | ||
} | ||
|
||
ref?.current?.appendChild(host); | ||
}, [node.request]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is almost the same content as in the response renderer. I would like to suggest a custom hook useMarkDownRendering(markDownText)
so we can reuse this logic in both.
The hook could then also be documented on why it exists and why it uses markdownit directly.
@@ -411,35 +410,35 @@ export class TextChatResponseContentImpl implements TextChatResponseContent { | |||
|
|||
export class MarkdownChatResponseContentImpl implements MarkdownChatResponseContent { | |||
kind: 'markdownContent' = 'markdownContent'; | |||
protected _content: MarkdownStringImpl = new MarkdownStringImpl(); | |||
protected _content: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we keep the markdown string content? depending on its attributes we could then hand over different options to markdownit. Thereby we could allow html embeddings if someone wants to have that.
Change the rendering off all markdown renderers to use markdown-it directly. Also no MarkdownString class is used anymore. fixes eclipse-theia#14208
- revert model changes - create custom hook for rendering
0cb013f
to
0a6f815
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me!
I tested requests like:
Hi <span> there </span>
And I executed prompts like:
Paste me an html template. Do not wrap in code block
These requests and answers were shown correctly 👍
I only have minor comments
packages/ai-chat-ui/src/browser/chat-response-renderer/markdown-part-renderer.tsx
Outdated
Show resolved
Hide resolved
// eslint-disable-next-line no-null/no-null | ||
const ref = useRef<HTMLDivElement | null>(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a benefit of using null
over undefined
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the ref paramerter wants null, can't be used with undefined
packages/ai-chat-ui/src/browser/chat-response-renderer/markdown-part-renderer.tsx
Outdated
Show resolved
Hide resolved
useEffect(() => { | ||
const markdownIt = markdownit(); | ||
const host = document.createElement('div'); | ||
const html = markdownIt.render(markdown); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const html = markdownIt.render(markdown); | |
// TODO: accept MarkdownString objects and set options accordingly | |
const html = markdownIt.render(markdown); |
…n-part-renderer.tsx Co-authored-by: Stefan Dirix <[email protected]>
…n-part-renderer.tsx Co-authored-by: Stefan Dirix <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works great
What it does
Currently requests in the ai chat view use a markdown renderer which parses html input and tries to render this. This leads to unexpected behavior when using html in the query.
By deactivating html support there, an alternative is needed as the markdown renderer just renders an empty paragraph if html is now passed to it. So to render the actual text, a span is created and filled with the text content.
fixes #14208
How to test
Use a string like
<img src="../../enter-openai-key.png" alt="Theia IDE Screenshot" style="max-width: 525px">
in you query.Follow-ups
Review checklist
Reminder for reviewers