Skip to content

Commit 21404d1

Browse files
committed
fix: message stream pickup and task ordering
1 parent df7e731 commit 21404d1

4 files changed

Lines changed: 51 additions & 17 deletions

File tree

apps/sim/app/api/mothership/chat/route.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ export async function POST(req: NextRequest) {
126126
.set({
127127
messages: [...conversationHistory, userMsg],
128128
conversationId: userMessageId,
129+
updatedAt: new Date(),
129130
})
130131
.where(eq(copilotChats.id, actualChatId))
131132
}

apps/sim/app/workspace/[workspaceId]/home/home.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ export function Home({ chatId }: HomeProps = {}) {
4747
return (
4848
<div className='flex h-full bg-[#FCFCFC] dark:bg-[var(--surface-2)]'>
4949
<div className='flex h-full min-w-0 flex-1 flex-col'>
50-
<div className='min-h-0 flex-1 overflow-y-auto px-[16px] py-[16px]'>
51-
<div className='mx-auto max-w-[768px] space-y-[16px]'>
50+
<div className='min-h-0 flex-1 overflow-y-auto px-[24px] py-[16px]'>
51+
<div className='mx-auto max-w-[640px] space-y-[16px]'>
5252
{messages.map((msg) => {
5353
if (msg.role === 'user') {
5454
return (
@@ -91,7 +91,7 @@ export function Home({ chatId }: HomeProps = {}) {
9191
</div>
9292
</div>
9393

94-
<div className='flex-shrink-0 border-[var(--border)] border-t px-[24px] py-[16px]'>
94+
<div className='flex-shrink-0 px-[24px] pb-[16px]'>
9595
<UserInput
9696
value={inputValue}
9797
onChange={setInputValue}

apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { useCallback, useEffect, useRef, useState } from 'react'
22
import { useQueryClient } from '@tanstack/react-query'
3-
import { usePathname } from 'next/navigation'
3+
import { usePathname, useRouter } from 'next/navigation'
44
import { MOTHERSHIP_CHAT_API_PATH } from '@/lib/copilot/constants'
55
import {
6+
type TaskChatHistory,
67
type TaskStoredContentBlock,
78
type TaskStoredMessage,
89
taskKeys,
@@ -71,13 +72,22 @@ function getPayloadData(payload: SSEPayload): SSEPayloadData | undefined {
7172
export function useChat(workspaceId: string, initialChatId?: string): UseChatReturn {
7273
const pathname = usePathname()
7374
const queryClient = useQueryClient()
75+
const router = useRouter()
76+
const routerRef = useRef(router)
7477
const [messages, setMessages] = useState<ChatMessage[]>([])
7578
const [isSending, setIsSending] = useState(false)
7679
const [error, setError] = useState<string | null>(null)
7780
const abortControllerRef = useRef<AbortController | null>(null)
7881
const chatIdRef = useRef<string | undefined>(initialChatId)
7982
const chatBottomRef = useRef<HTMLDivElement>(null)
8083
const appliedChatIdRef = useRef<string | undefined>(undefined)
84+
const pendingUserMsgRef = useRef<{ id: string; content: string } | null>(null)
85+
const streamIdRef = useRef<string | undefined>(undefined)
86+
const sendingRef = useRef(false)
87+
88+
useEffect(() => {
89+
routerRef.current = router
90+
}, [router])
8191

8292
const isHomePage = pathname.endsWith('/home')
8393

@@ -161,11 +171,17 @@ export function useChat(workspaceId: string, initialChatId?: string): UseChatRet
161171
chatIdRef.current = parsed.chatId
162172
queryClient.invalidateQueries({ queryKey: taskKeys.list(workspaceId) })
163173
if (isNewChat) {
164-
window.history.replaceState(
165-
null,
166-
'',
167-
`/workspace/${workspaceId}/task/${parsed.chatId}`
168-
)
174+
const userMsg = pendingUserMsgRef.current
175+
const activeStreamId = streamIdRef.current
176+
if (userMsg && activeStreamId) {
177+
queryClient.setQueryData<TaskChatHistory>(taskKeys.detail(parsed.chatId), {
178+
id: parsed.chatId,
179+
title: null,
180+
messages: [{ id: userMsg.id, role: 'user', content: userMsg.content }],
181+
activeStreamId,
182+
})
183+
}
184+
routerRef.current.replace(`/workspace/${workspaceId}/task/${parsed.chatId}`)
169185
}
170186
}
171187
break
@@ -266,7 +282,7 @@ export function useChat(workspaceId: string, initialChatId?: string): UseChatRet
266282

267283
useEffect(() => {
268284
const activeStreamId = chatHistory?.activeStreamId
269-
if (!activeStreamId || !appliedChatIdRef.current) return
285+
if (!activeStreamId || !appliedChatIdRef.current || sendingRef.current) return
270286

271287
const abortController = new AbortController()
272288
abortControllerRef.current = abortController
@@ -295,19 +311,41 @@ export function useChat(workspaceId: string, initialChatId?: string): UseChatRet
295311

296312
return () => {
297313
abortController.abort()
314+
appliedChatIdRef.current = undefined
298315
}
299316
}, [chatHistory?.activeStreamId, processSSEStream, finalize])
300317

301318
const sendMessage = useCallback(
302319
async (message: string) => {
303320
if (!message.trim() || !workspaceId) return
304321

322+
abortControllerRef.current?.abort()
323+
305324
setError(null)
306325
setIsSending(true)
326+
sendingRef.current = true
307327

308328
const userMessageId = crypto.randomUUID()
309329
const assistantId = crypto.randomUUID()
310330

331+
pendingUserMsgRef.current = { id: userMessageId, content: message }
332+
streamIdRef.current = userMessageId
333+
334+
if (chatIdRef.current) {
335+
queryClient.setQueryData<TaskChatHistory>(taskKeys.detail(chatIdRef.current), (old) =>
336+
old
337+
? {
338+
...old,
339+
messages: [
340+
...old.messages,
341+
{ id: userMessageId, role: 'user' as const, content: message },
342+
],
343+
activeStreamId: userMessageId,
344+
}
345+
: undefined
346+
)
347+
}
348+
311349
setMessages((prev) => [
312350
...prev,
313351
{ id: userMessageId, role: 'user', content: message },
@@ -343,10 +381,11 @@ export function useChat(workspaceId: string, initialChatId?: string): UseChatRet
343381
if (err instanceof Error && err.name === 'AbortError') return
344382
setError(err instanceof Error ? err.message : 'Failed to send message')
345383
} finally {
384+
sendingRef.current = false
346385
finalize()
347386
}
348387
},
349-
[workspaceId, processSSEStream, finalize]
388+
[workspaceId, queryClient, processSSEStream, finalize]
350389
)
351390

352391
const stopGeneration = useCallback(() => {

apps/sim/lib/copilot/chat-streaming.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,6 @@ export function createSSEStream(params: StreamingOrchestrationParams): ReadableS
158158
},
159159
})
160160

161-
if (currentChat) {
162-
await db
163-
.update(copilotChats)
164-
.set({ updatedAt: new Date() })
165-
.where(eq(copilotChats.id, chatId!))
166-
}
167161
await eventWriter.close()
168162
await setStreamMeta(streamId, { status: 'complete', userId })
169163
} catch (error) {

0 commit comments

Comments
 (0)