@@ -28,6 +28,8 @@ const MessageItem = ({
2828} : MessageItemProps ) => {
2929 const [ isHovered , setIsHovered ] = useState ( false ) ;
3030 const [ hasBeenClicked , setHasBeenClicked ] = useState ( false ) ;
31+ const [ isReasoningExpanded , setIsReasoningExpanded ] = useState ( true ) ;
32+ const reasoningText = message . reasoning_content ?. trim ( ) ;
3133
3234 const handleCopy = async ( ) => {
3335 try {
@@ -43,63 +45,87 @@ const MessageItem = ({
4345 return (
4446 < div
4547 className = { twJoin (
46- "mb-2 hover:bg-slate-50" ,
48+ "mb-2 w-full hover:bg-slate-50" ,
4749 isEditing && "bg-sky-100 opacity-50" ,
4850 ) }
4951 onMouseOver = { ( ) => setIsHovered ( true ) }
5052 onMouseLeave = { ( ) => setIsHovered ( false ) }
5153 >
52- < div className = "flex items-center gap-2" >
53- < p
54- className = "my-0 font-bold"
55- onClick = { ( ) => {
56- setHasBeenClicked ( ( value ) => ! value ) ;
57- } }
58- >
59- { message . role }
60- </ p >
61- { ( hasBeenClicked || isHovered ) && (
62- < >
54+ < div className = "w-full max-w-[65ch]" >
55+ < div className = "flex items-center gap-2" >
56+ < p
57+ className = "my-0 font-bold"
58+ onClick = { ( ) => {
59+ setHasBeenClicked ( ( value ) => ! value ) ;
60+ } }
61+ >
62+ { message . role }
63+ </ p >
64+ { ( hasBeenClicked || isHovered ) && (
65+ < >
66+ < UnstyledButton
67+ className = "i-lucide-copy text-slate-400 hover:text-slate-600 transition"
68+ onClick = { handleCopy }
69+ />
70+ < UnstyledButton
71+ className = "i-lucide-edit text-slate-400 hover:text-slate-600 transition"
72+ onClick = { onEdit }
73+ />
74+ < Popover width = { 200 } position = "bottom" withArrow >
75+ < Popover . Target >
76+ < UnstyledButton className = "i-lucide-trash text-slate-400 hover:text-slate-600 transition" />
77+ </ Popover . Target >
78+ < Popover . Dropdown >
79+ < div className = "flex flex-col" >
80+ < Text > Delete?</ Text >
81+ < Button
82+ className = "min-w-0 h-auto flex-1 !p-1 text-xs self-end"
83+ onClick = { onDelete }
84+ >
85+ Yes
86+ </ Button >
87+ </ div >
88+ </ Popover . Dropdown >
89+ </ Popover >
90+ < UnstyledButton
91+ className = "i-lucide-unlink text-slate-400 hover:text-slate-600 transition"
92+ onClick = { onDetach }
93+ />
94+ < UnstyledButton
95+ className = "i-lucide-git-branch-plus text-slate-400 hover:text-slate-600 transition"
96+ title = "Branch from here"
97+ onClick = { onBranch }
98+ />
99+ </ >
100+ ) }
101+ </ div >
102+ { reasoningText && (
103+ < div className = "mb-2 rounded-md border border-slate-200" >
63104 < UnstyledButton
64- className = "i-lucide-copy text-slate-400 hover:text-slate-600 transition"
65- onClick = { handleCopy }
66- />
67- < UnstyledButton
68- className = "i-lucide-edit text-slate-400 hover:text-slate-600 transition"
69- onClick = { onEdit }
70- />
71- < Popover width = { 200 } position = "bottom" withArrow >
72- < Popover . Target >
73- < UnstyledButton className = "i-lucide-trash text-slate-400 hover:text-slate-600 transition" />
74- </ Popover . Target >
75- < Popover . Dropdown >
76- < div className = "flex flex-col" >
77- < Text > Delete?</ Text >
78- < Button
79- className = "min-w-0 h-auto flex-1 !p-1 text-xs self-end"
80- onClick = { onDelete }
81- >
82- Yes
83- </ Button >
84- </ div >
85- </ Popover . Dropdown >
86- </ Popover >
87- < UnstyledButton
88- className = "i-lucide-unlink text-slate-400 hover:text-slate-600 transition"
89- onClick = { onDetach }
90- />
91- < UnstyledButton
92- className = "i-lucide-git-branch-plus text-slate-400 hover:text-slate-600 transition"
93- title = "Branch from here"
94- onClick = { onBranch }
95- />
96- </ >
105+ className = "flex w-full items-center gap-2 px-2 pt-1 text-sm font-semibold text-slate-600"
106+ onClick = { ( ) => setIsReasoningExpanded ( ( value ) => ! value ) }
107+ aria-expanded = { isReasoningExpanded }
108+ >
109+ < div
110+ className = { twJoin (
111+ "i-lucide-chevron-down transition-transform" ,
112+ isReasoningExpanded && "rotate-180" ,
113+ ) }
114+ />
115+ < span > Reasoning</ span >
116+ </ UnstyledButton >
117+ { isReasoningExpanded && (
118+ < div className = "twp prose prose-p:whitespace-pre-wrap px-2 pt-1 pb-3 text-sm text-slate-500" >
119+ < Markdown remarkPlugins = { [ ] } > { reasoningText } </ Markdown >
120+ </ div >
121+ ) }
122+ </ div >
97123 ) }
98- </ div >
99- < div className = "twp prose prose-p:whitespace-pre-wrap" >
100- < Markdown remarkPlugins = { [ ] } >
101- { ` ${ message . content } ${ isLast && isGenerating ? "▪️" : "" } ` }
102- </ Markdown >
124+ < div className = "twp prose prose-p:whitespace-pre-wrap" >
125+ < Markdown remarkPlugins = { [ ] } >
126+ { ` ${ message . content } ${ isLast && isGenerating ? "▪️" : "" } ` }
127+ </ Markdown >
128+ </ div >
103129 </ div >
104130 </ div >
105131 ) ;
0 commit comments