@@ -115,133 +115,7 @@ export const ChatHistoryComponent: React.FC<ChatHistoryComponentProps> = ({
115115
116116                  < div  className = "aiMarkup lh-base text-wrap" > 
117117                    { msg . role  ===  'assistant'  ? ( 
118-                       < ReactMarkdown 
119-                         remarkPlugins = { [ [ remarkGfm ,  {  } ] ] } 
120-                         remarkRehypeOptions = { { 
121-                         } } 
122-                         rehypePlugins = { [ rehypeRaw ,  rehypeSanitize ] } 
123-                         linkTarget = "_blank" 
124-                         components = { { 
125-                         // Code blocks and inline code 
126-                           code ( {  node,  inline,  className,  children,  ...props  } )  { 
127-                             const  text  =  String ( children ) . replace ( / \n $ / ,  '' ) 
128-                             const  match  =  / l a n g u a g e - ( \w + ) / . exec ( className  ||  '' ) 
129-                             const  language  =  match  ? match [ 1 ]  : '' 
130-                             if  ( inline )  { 
131-                               return  ( 
132-                                 < code  className = "ai-inline-code"  { ...props } > 
133-                                   { text } 
134-                                 </ code > 
135-                               ) 
136-                             } 
137-                             return  ( 
138-                               < div  className = "ai-code-block-wrapper" > 
139-                                 { language  &&  ( 
140-                                   < div  className = { `ai-code-header ${ theme  ===  'Dark'  ? 'text-white'  : 'text-dark' }  } > 
141-                                     < span  className = "ai-code-language" > { language } </ span > 
142-                                     < button 
143-                                       type = "button" 
144-                                       className = "btn btn-sm btn-outline-info border border-info" 
145-                                       onClick = { ( )  =>  copy ( text ) } 
146-                                       title = "Copy code" 
147-                                     > 
148-                                       < i  className = "fa-regular fa-copy" > </ i > 
149-                                     </ button > 
150-                                   </ div > 
151-                                 ) } 
152-                                 { ! language  &&  ( 
153-                                   < button 
154-                                     type = "button" 
155-                                     className = "ai-copy-btn ai-copy-btn-absolute" 
156-                                     onClick = { ( )  =>  copy ( text ) } 
157-                                     title = "Copy code" 
158-                                   > 
159-                                     < i  className = "fa-regular fa-copy" > </ i > 
160-                                   </ button > 
161-                                 ) } 
162-                                 < pre  className = "ai-code-pre" > 
163-                                   < code  className = { className } > { text } </ code > 
164-                                 </ pre > 
165-                               </ div > 
166-                             ) 
167-                           } , 
168-                           // Paragraphs 
169-                           p : ( {  node,  ...props  } )  =>  ( 
170-                             < p  className = "ai-paragraph"  { ...props }  /> 
171-                           ) , 
172-                           // Headings 
173-                           h1 : ( {  node,  ...props  } )  =>  ( 
174-                             < h1  className = "ai-heading ai-h1 fs-5 mb-1"  { ...props }  /> 
175-                           ) , 
176-                           h2 : ( {  node,  ...props  } )  =>  ( 
177-                             < h2  className = "ai-heading ai-h2 fs-5 mb-1"  { ...props }  /> 
178-                           ) , 
179-                           h3 : ( {  node,  ...props  } )  =>  ( 
180-                             < h3  className = "ai-heading ai-h3 fs-5 mb-1"  { ...props }  /> 
181-                           ) , 
182-                           h4 : ( {  node,  ...props  } )  =>  ( 
183-                             < h4  className = "ai-heading ai-h4 fs-6 mb-1"  { ...props }  /> 
184-                           ) , 
185-                           h5 : ( {  node,  ...props  } )  =>  ( 
186-                             < h5  className = "ai-heading ai-h5 fs-6 mb-1"  { ...props }  /> 
187-                           ) , 
188-                           h6 : ( {  node,  ...props  } )  =>  ( 
189-                             < h6  className = "ai-heading ai-h6 fs-6 mb-1"  { ...props }  /> 
190-                           ) , 
191-                           // Lists 
192-                           ul : ( {  node,  ...props  } )  =>  ( 
193-                             < ul  className = "ai-list ai-list-unordered"  { ...props }  /> 
194-                           ) , 
195-                           ol : ( {  node,  ...props  } )  =>  ( 
196-                             < ol  className = "ai-list ai-list-ordered"  { ...props }  /> 
197-                           ) , 
198-                           li : ( {  node,  ...props  } )  =>  ( 
199-                             < li  className = "ai-list-item"  { ...props }  /> 
200-                           ) , 
201-                           // Links 
202-                           a : ( {  node,  ...props  } )  =>  ( 
203-                             < a  className = "ai-link"  target = "_blank"  rel = "noopener noreferrer"  { ...props }  /> 
204-                           ) , 
205-                           // Blockquotes 
206-                           blockquote : ( {  node,  ...props  } )  =>  ( 
207-                             < blockquote  className = "ai-blockquote"  { ...props }  /> 
208-                           ) , 
209-                           // Tables 
210-                           table : ( {  node,  ...props  } )  =>  ( 
211-                             < div  className = "ai-table-wrapper" > 
212-                               < table  className = "ai-table"  { ...props }  /> 
213-                             </ div > 
214-                           ) , 
215-                           thead : ( {  node,  ...props  } )  =>  ( 
216-                             < thead  className = "ai-table-head"  { ...props }  /> 
217-                           ) , 
218-                           tbody : ( {  node,  ...props  } )  =>  ( 
219-                             < tbody  className = "ai-table-body"  { ...props }  /> 
220-                           ) , 
221-                           tr : ( {  node,  ...props  } )  =>  ( 
222-                             < tr  className = "ai-table-row"  { ...props }  /> 
223-                           ) , 
224-                           th : ( {  node,  ...props  } )  =>  ( 
225-                             < th  className = "ai-table-header-cell"  { ...props }  /> 
226-                           ) , 
227-                           td : ( {  node,  ...props  } )  =>  ( 
228-                             < td  className = "ai-table-cell"  { ...props }  /> 
229-                           ) , 
230-                           // Horizontal rule 
231-                           hr : ( {  node,  ...props  } )  =>  ( 
232-                             < hr  className = "ai-divider"  { ...props }  /> 
233-                           ) , 
234-                           // Strong and emphasis 
235-                           strong : ( {  node,  ...props  } )  =>  ( 
236-                             < strong  className = "ai-strong"  { ...props }  /> 
237-                           ) , 
238-                           em : ( {  node,  ...props  } )  =>  ( 
239-                             < em  className = "ai-emphasis"  { ...props }  /> 
240-                           ) 
241-                         } } 
242-                       > 
243-                         { normalizeMarkdown ( msg . content ) } 
244-                       </ ReactMarkdown > 
118+                       RemixMarkdownViewer ( theme ,  msg . content ) 
245119                    )  : ( 
246120                      msg . content 
247121                    ) } 
@@ -297,3 +171,132 @@ export const ChatHistoryComponent: React.FC<ChatHistoryComponentProps> = ({
297171  ) 
298172} 
299173
174+ function  RemixMarkdownViewer ( theme : string ,  markDownContent : string ) : React . ReactNode  { 
175+   return  < ReactMarkdown 
176+     remarkPlugins = { [ [ remarkGfm ,  { } ] ] } 
177+     remarkRehypeOptions = { { } } 
178+     rehypePlugins = { [ rehypeRaw ,  rehypeSanitize ] } 
179+     linkTarget = "_blank" 
180+     components = { { 
181+       // Code blocks and inline code 
182+       code ( {  node,  inline,  className,  children,  ...props  } )  { 
183+         const  text  =  String ( children ) . replace ( / \n $ / ,  '' ) 
184+         const  match  =  / l a n g u a g e - ( \w + ) / . exec ( className  ||  '' ) 
185+         const  language  =  match  ? match [ 1 ]  : '' 
186+         if  ( inline )  { 
187+           return  ( 
188+             < code  className = "ai-inline-code"  { ...props } > 
189+               { text } 
190+             </ code > 
191+           ) 
192+         } 
193+         return  ( 
194+           < div  className = "ai-code-block-wrapper" > 
195+             { language  &&  ( 
196+               < div  className = { `ai-code-header ${ theme  ===  'Dark'  ? 'text-white'  : 'text-dark' }  } > 
197+                 < span  className = "ai-code-language" > { language } </ span > 
198+                 < button 
199+                   type = "button" 
200+                   className = "btn btn-sm btn-outline-info border border-info" 
201+                   onClick = { ( )  =>  copy ( text ) } 
202+                   title = "Copy code" 
203+                 > 
204+                   < i  className = "fa-regular fa-copy" > </ i > 
205+                 </ button > 
206+               </ div > 
207+             ) } 
208+             { ! language  &&  ( 
209+               < button 
210+                 type = "button" 
211+                 className = "ai-copy-btn ai-copy-btn-absolute" 
212+                 onClick = { ( )  =>  copy ( text ) } 
213+                 title = "Copy code" 
214+               > 
215+                 < i  className = "fa-regular fa-copy" > </ i > 
216+               </ button > 
217+             ) } 
218+             < pre  className = "ai-code-pre" > 
219+               < code  className = { className } > { text } </ code > 
220+             </ pre > 
221+           </ div > 
222+         ) 
223+       } , 
224+       // Paragraphs 
225+       p : ( {  node,  ...props  } )  =>  ( 
226+         < p  className = "ai-paragraph"  { ...props }  /> 
227+       ) , 
228+       // Headings 
229+       h1 : ( {  node,  ...props  } )  =>  ( 
230+         < h1  className = "ai-heading ai-h1 fs-5 mb-1"  { ...props }  /> 
231+       ) , 
232+       h2 : ( {  node,  ...props  } )  =>  ( 
233+         < h2  className = "ai-heading ai-h2 fs-5 mb-1"  { ...props }  /> 
234+       ) , 
235+       h3 : ( {  node,  ...props  } )  =>  ( 
236+         < h3  className = "ai-heading ai-h3 fs-5 mb-1"  { ...props }  /> 
237+       ) , 
238+       h4 : ( {  node,  ...props  } )  =>  ( 
239+         < h4  className = "ai-heading ai-h4 fs-6 mb-1"  { ...props }  /> 
240+       ) , 
241+       h5 : ( {  node,  ...props  } )  =>  ( 
242+         < h5  className = "ai-heading ai-h5 fs-6 mb-1"  { ...props }  /> 
243+       ) , 
244+       h6 : ( {  node,  ...props  } )  =>  ( 
245+         < h6  className = "ai-heading ai-h6 fs-6 mb-1"  { ...props }  /> 
246+       ) , 
247+       // Lists 
248+       ul : ( {  node,  ...props  } )  =>  ( 
249+         < ul  className = "ai-list ai-list-unordered"  { ...props }  /> 
250+       ) , 
251+       ol : ( {  node,  ...props  } )  =>  ( 
252+         < ol  className = "ai-list ai-list-ordered"  { ...props }  /> 
253+       ) , 
254+       li : ( {  node,  ...props  } )  =>  ( 
255+         < li  className = "ai-list-item"  { ...props }  /> 
256+       ) , 
257+       // Links 
258+       a : ( {  node,  ...props  } )  =>  ( 
259+         < a  className = "ai-link"  target = "_blank"  rel = "noopener noreferrer"  { ...props }  /> 
260+       ) , 
261+       // Blockquotes 
262+       blockquote : ( {  node,  ...props  } )  =>  ( 
263+         < blockquote  className = "ai-blockquote"  { ...props }  /> 
264+       ) , 
265+       // Tables 
266+       table : ( {  node,  ...props  } )  =>  ( 
267+         < div  className = "ai-table-wrapper" > 
268+           < table  className = "ai-table"  { ...props }  /> 
269+         </ div > 
270+       ) , 
271+       thead : ( {  node,  ...props  } )  =>  ( 
272+         < thead  className = "ai-table-head"  { ...props }  /> 
273+       ) , 
274+       tbody : ( {  node,  ...props  } )  =>  ( 
275+         < tbody  className = "ai-table-body"  { ...props }  /> 
276+       ) , 
277+       tr : ( {  node,  ...props  } )  =>  ( 
278+         < tr  className = "ai-table-row"  { ...props }  /> 
279+       ) , 
280+       th : ( {  node,  ...props  } )  =>  ( 
281+         < th  className = "ai-table-header-cell"  { ...props }  /> 
282+       ) , 
283+       td : ( {  node,  ...props  } )  =>  ( 
284+         < td  className = "ai-table-cell"  { ...props }  /> 
285+       ) , 
286+       // Horizontal rule 
287+       hr : ( {  node,  ...props  } )  =>  ( 
288+         < hr  className = "ai-divider"  { ...props }  /> 
289+       ) , 
290+       // Strong and emphasis 
291+       strong : ( {  node,  ...props  } )  =>  ( 
292+         < strong  className = "ai-strong"  { ...props }  /> 
293+       ) , 
294+       em : ( {  node,  ...props  } )  =>  ( 
295+         < em  className = "ai-emphasis"  { ...props }  /> 
296+       ) 
297+     } } 
298+   > 
299+     { normalizeMarkdown ( markDownContent ) } 
300+   </ ReactMarkdown > 
301+ } 
302+ 
0 commit comments