Skip to content
This repository was archived by the owner on Feb 6, 2026. It is now read-only.

Commit 6ebb156

Browse files
committed
working tool call ui!
1 parent 769475c commit 6ebb156

File tree

1 file changed

+38
-26
lines changed

1 file changed

+38
-26
lines changed

examples/chat-ui/src/hooks/useStreamResponse.ts

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ export const useStreamResponse = ({
102102

103103
const streamResponse = async (messages: Message[]) => {
104104
let aiResponse = ''
105+
let assistantMessageIndex = -1 // Track the index of our assistant message
106+
let assistantMessageCreated = false // Track if we've created the assistant message yet
107+
105108
debugLog(`[useStreamResponse] streamResponse called with ${messages.length} messages`)
106109
debugLog(`[useStreamResponse] Messages:`, messages)
107110
debugLog(`[useStreamResponse] Current conversationId:`, conversationId)
@@ -123,19 +126,6 @@ export const useStreamResponse = ({
123126
try {
124127
const modelInstance = getModelInstance(selectedModel, apiKey)
125128

126-
debugLog(`[useStreamResponse] Adding empty assistant message to conversation ${conversationId}`)
127-
setConversations((prev) => {
128-
const updated = [...prev]
129-
const conv = updated.find((c) => c.id === conversationId)
130-
if (conv) {
131-
debugLog(`[useStreamResponse] Found conversation, adding assistant message. Current message count: ${conv.messages.length}`)
132-
conv.messages.push({ role: 'assistant', content: '' })
133-
debugLog(`[useStreamResponse] After adding assistant message, message count: ${conv.messages.length}`)
134-
} else {
135-
debugLog(`[useStreamResponse] Could not find conversation with id: ${conversationId}`)
136-
}
137-
return updated
138-
})
139129
debugLog(`[useStreamResponse] Setting stream started to true`)
140130
setStreamStarted(true)
141131

@@ -243,6 +233,22 @@ export const useStreamResponse = ({
243233
} else if (event.type === 'text-delta') {
244234
debugLog(`[useStreamResponse] Text delta:`, event.textDelta)
245235

236+
// Create assistant message on first text delta (after all tool calls/results)
237+
if (!assistantMessageCreated) {
238+
debugLog(`[useStreamResponse] Creating assistant message after tool calls/results`)
239+
setConversations((prev) => {
240+
const updated = [...prev]
241+
const conv = updated.find((c) => c.id === conversationId)
242+
if (conv) {
243+
conv.messages.push({ role: 'assistant', content: '' })
244+
assistantMessageIndex = conv.messages.length - 1
245+
debugLog(`[useStreamResponse] Created assistant message at index ${assistantMessageIndex}`)
246+
}
247+
return updated
248+
})
249+
assistantMessageCreated = true
250+
}
251+
246252
aiResponse += event.textDelta
247253
aiResponseRef.current = aiResponse
248254

@@ -267,9 +273,13 @@ export const useStreamResponse = ({
267273
const conv = updated.find((c) => c.id === conversationId)
268274
if (conv) {
269275
debugLog(`[useStreamResponse] Updating conversation message content (length: ${aiResponse.length})`)
270-
const lastMessage = conv.messages[conv.messages.length - 1]
271-
if (hasContent(lastMessage)) {
272-
lastMessage.content = aiResponse
276+
// Update the specific assistant message we created, not just the last message
277+
const assistantMessage = conv.messages[assistantMessageIndex]
278+
if (assistantMessage && hasContent(assistantMessage) && assistantMessage.role === 'assistant') {
279+
assistantMessage.content = aiResponse
280+
debugLog(`[useStreamResponse] Updated assistant message at index ${assistantMessageIndex}`)
281+
} else {
282+
debugLog(`[useStreamResponse] Could not find assistant message at index ${assistantMessageIndex}`, assistantMessage)
273283
}
274284
} else {
275285
debugLog(`[useStreamResponse] Could not find conversation with id: ${conversationId}`)
@@ -295,16 +305,18 @@ export const useStreamResponse = ({
295305
console.error('[useStreamResponse] Error stack:', error.stack)
296306
console.error('[useStreamResponse] Error message:', error.message)
297307
}
298-
// Remove the assistant message if there was an error
299-
setConversations((prev) => {
300-
const updated = [...prev]
301-
const conv = updated.find((c) => c.id === conversationId)
302-
if (conv && conv.messages[conv.messages.length - 1].role === 'assistant') {
303-
debugLog('[useStreamResponse] Removing assistant message due to error')
304-
conv.messages.pop()
305-
}
306-
return updated
307-
})
308+
// Remove the assistant message if there was an error and we created one
309+
if (assistantMessageCreated) {
310+
setConversations((prev) => {
311+
const updated = [...prev]
312+
const conv = updated.find((c) => c.id === conversationId)
313+
if (conv && assistantMessageIndex >= 0 && conv.messages[assistantMessageIndex]?.role === 'assistant') {
314+
debugLog('[useStreamResponse] Removing assistant message due to error')
315+
conv.messages.splice(assistantMessageIndex, 1)
316+
}
317+
return updated
318+
})
319+
}
308320
}
309321
} finally {
310322
debugLog('[useStreamResponse] Cleaning up stream state')

0 commit comments

Comments
 (0)