@@ -32,6 +32,7 @@ export const MessageBubble = ({ message }: { message: Message }) => {
3232 } ;
3333
3434 const messageContent = getMessageContent ( ) ;
35+ const hasMessageContent = messageContent . trim ( ) . length > 0 ;
3536 const isLongMessage = messageContent . length > 200 ; // Threshold for considering a message "long"
3637 const displayContent =
3738 isLongMessage && ! isExpanded
@@ -78,31 +79,37 @@ export const MessageBubble = ({ message }: { message: Message }) => {
7879 } `}
7980 >
8081 { /* Copy button positioned in top-right corner */ }
81- < div className = "absolute top-1 right-1" >
82- < Tooltip
83- content = { copySuccess ? "Copied!" : "Copy message to clipboard" }
84- position = "top"
85- >
86- < Button
87- onClick = { handleCopy }
88- size = "sm"
89- variant = "secondary"
90- className = { `p-0.5 h-5 text-[10px] opacity-60 hover:opacity-100 transition-opacity cursor-pointer ${
91- isUser
92- ? "text-blue-600 hover:bg-blue-100"
93- : isSystem
94- ? "text-gray-600 hover:bg-gray-100"
95- : isTool
96- ? "text-green-600 hover:bg-green-100"
97- : "text-yellow-600 hover:bg-yellow-100"
98- } `}
82+ { hasMessageContent && (
83+ < div className = "absolute top-1 right-1" >
84+ < Tooltip
85+ content = { copySuccess ? "Copied!" : "Copy message to clipboard" }
86+ position = "top"
9987 >
100- Copy
101- </ Button >
102- </ Tooltip >
103- </ div >
88+ < Button
89+ onClick = { handleCopy }
90+ size = "sm"
91+ variant = "secondary"
92+ className = { `p-0.5 h-5 text-[10px] opacity-60 hover:opacity-100 transition-opacity cursor-pointer ${
93+ isUser
94+ ? "text-blue-600 hover:bg-blue-100"
95+ : isSystem
96+ ? "text-gray-600 hover:bg-gray-100"
97+ : isTool
98+ ? "text-green-600 hover:bg-green-100"
99+ : "text-yellow-600 hover:bg-yellow-100"
100+ } `}
101+ >
102+ Copy
103+ </ Button >
104+ </ Tooltip >
105+ </ div >
106+ ) }
104107
105- < div className = "font-semibold text-xs mb-0.5 capitalize pr-8" >
108+ < div
109+ className = { `font-semibold text-xs mb-0.5 capitalize ${
110+ hasMessageContent ? "pr-8" : ""
111+ } `}
112+ >
106113 { message . role }
107114 </ div >
108115 < div className = "whitespace-pre-wrap break-words overflow-hidden text-xs" >
@@ -170,57 +177,63 @@ export const MessageBubble = ({ message }: { message: Message }) => {
170177 >
171178 Tool Calls:
172179 </ div >
173- { message . tool_calls . map ( ( call , i ) => (
174- < div
175- key = { i }
176- className = { `mb-1 p-1 border rounded text-xs relative ${
177- isTool
178- ? "bg-green-100 border-green-200"
179- : "bg-yellow-100 border-yellow-200"
180- } `}
181- >
182- { /* Copy button for tool call arguments */ }
183- < div className = "absolute top-1 right-1" >
184- < Tooltip
185- content = {
186- toolCallCopySuccess [ i ]
187- ? "Copied!"
188- : "Copy tool call arguments"
189- }
190- position = "top"
191- >
192- < Button
193- onClick = { ( ) =>
194- handleToolCallCopy ( i , call . function . arguments )
195- }
196- size = "sm"
197- variant = "secondary"
198- className = { `p-0.5 h-5 text-[10px] opacity-60 hover:opacity-100 transition-opacity cursor-pointer ${
199- isTool
200- ? "text-green-600 hover:bg-green-200"
201- : "text-yellow-600 hover:bg-yellow-200"
202- } `}
203- >
204- Copy
205- </ Button >
206- </ Tooltip >
207- </ div >
180+ { message . tool_calls . map ( ( call , i ) => {
181+ const hasToolCallArguments =
182+ call . function . arguments . trim ( ) . length > 0 ;
183+ return (
208184 < div
209- className = { `font-semibold mb-0.5 text-xs pr-8 ${
210- isTool ? "text-green-800" : "text-yellow-800"
185+ key = { i }
186+ className = { `mb-1 p-1 border rounded text-xs relative ${
187+ isTool
188+ ? "bg-green-100 border-green-200"
189+ : "bg-yellow-100 border-yellow-200"
211190 } `}
212191 >
213- { call . function . name }
214- </ div >
215- < div
216- className = { `font-mono text-xs break-all overflow-hidden ${
217- isTool ? "text-green-700" : "text-yellow-700"
218- } `}
219- >
220- { call . function . arguments }
192+ { /* Copy button for tool call arguments */ }
193+ { hasToolCallArguments && (
194+ < div className = "absolute top-1 right-1" >
195+ < Tooltip
196+ content = {
197+ toolCallCopySuccess [ i ]
198+ ? "Copied!"
199+ : "Copy tool call arguments"
200+ }
201+ position = "top"
202+ >
203+ < Button
204+ onClick = { ( ) =>
205+ handleToolCallCopy ( i , call . function . arguments )
206+ }
207+ size = "sm"
208+ variant = "secondary"
209+ className = { `p-0.5 h-5 text-[10px] opacity-60 hover:opacity-100 transition-opacity cursor-pointer ${
210+ isTool
211+ ? "text-green-600 hover:bg-green-200"
212+ : "text-yellow-600 hover:bg-yellow-200"
213+ } `}
214+ >
215+ Copy
216+ </ Button >
217+ </ Tooltip >
218+ </ div >
219+ ) }
220+ < div
221+ className = { `font-semibold mb-0.5 text-xs ${
222+ hasToolCallArguments ? "pr-8" : ""
223+ } ${ isTool ? "text-green-800" : "text-yellow-800" } `}
224+ >
225+ { call . function . name }
226+ </ div >
227+ < div
228+ className = { `font-mono text-xs break-all overflow-hidden ${
229+ isTool ? "text-green-700" : "text-yellow-700"
230+ } `}
231+ >
232+ { call . function . arguments }
233+ </ div >
221234 </ div >
222- </ div >
223- ) ) }
235+ ) ;
236+ } ) }
224237 </ div >
225238 ) }
226239 { hasFunctionCall && message . function_call && (
@@ -244,35 +257,39 @@ export const MessageBubble = ({ message }: { message: Message }) => {
244257 } `}
245258 >
246259 { /* Copy button for function call arguments */ }
247- < div className = "absolute top-1 right-1" >
248- < Tooltip
249- content = {
250- toolCallCopySuccess [ - 1 ]
251- ? "Copied!"
252- : "Copy function call arguments"
253- }
254- position = "top"
255- >
256- < Button
257- onClick = { ( ) =>
258- handleToolCallCopy ( - 1 , message . function_call ! . arguments )
260+ { message . function_call . arguments . trim ( ) . length > 0 && (
261+ < div className = "absolute top-1 right-1" >
262+ < Tooltip
263+ content = {
264+ toolCallCopySuccess [ - 1 ]
265+ ? "Copied!"
266+ : "Copy function call arguments"
259267 }
260- size = "sm"
261- variant = "secondary"
262- className = { `p-0.5 h-5 text-[10px] opacity-60 hover:opacity-100 transition-opacity cursor-pointer ${
263- isTool
264- ? "text-green-600 hover:bg-green-200"
265- : "text-yellow-600 hover:bg-yellow-200"
266- } `}
268+ position = "top"
267269 >
268- Copy
269- </ Button >
270- </ Tooltip >
271- </ div >
270+ < Button
271+ onClick = { ( ) =>
272+ handleToolCallCopy ( - 1 , message . function_call ! . arguments )
273+ }
274+ size = "sm"
275+ variant = "secondary"
276+ className = { `p-0.5 h-5 text-[10px] opacity-60 hover:opacity-100 transition-opacity cursor-pointer ${
277+ isTool
278+ ? "text-green-600 hover:bg-green-200"
279+ : "text-yellow-600 hover:bg-yellow-200"
280+ } `}
281+ >
282+ Copy
283+ </ Button >
284+ </ Tooltip >
285+ </ div >
286+ ) }
272287 < div
273- className = { `font-semibold mb-0.5 text-xs pr-8 ${
274- isTool ? "text-green-800" : "text-yellow-800"
275- } `}
288+ className = { `font-semibold mb-0.5 text-xs ${
289+ message . function_call . arguments . trim ( ) . length > 0
290+ ? "pr-8"
291+ : ""
292+ } ${ isTool ? "text-green-800" : "text-yellow-800" } `}
276293 >
277294 { message . function_call . name }
278295 </ div >
0 commit comments