Skip to content

Commit 8134113

Browse files
samhvw8Minh141120
authored andcommitted
feat: add updateThreadTimestamp function to manage thread order and timestamp updates (#5180)
1 parent 38b37c6 commit 8134113

File tree

2 files changed

+68
-8
lines changed

2 files changed

+68
-8
lines changed

web-app/src/hooks/useChat.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const useChat = () => {
4949
const { getProviderByName, selectedModel, selectedProvider } =
5050
useModelProvider()
5151

52-
const { getCurrentThread: retrieveThread, createThread } = useThreads()
52+
const { getCurrentThread: retrieveThread, createThread, updateThreadTimestamp } = useThreads()
5353
const { getMessages, addMessage } = useMessages()
5454
const router = useRouter()
5555

@@ -65,7 +65,7 @@ export const useChat = () => {
6565
}
6666
setTools()
6767

68-
let unsubscribe = () => {}
68+
let unsubscribe = () => { }
6969
listen(SystemEvent.MCP_UPDATE, setTools).then((unsub) => {
7070
// Unsubscribe from the event when the component unmounts
7171
unsubscribe = unsub
@@ -111,6 +111,7 @@ export const useChat = () => {
111111
setAbortController(activeThread.id, abortController)
112112
updateStreamingContent(emptyThreadContent)
113113
addMessage(newUserThreadContent(activeThread.id, message))
114+
updateThreadTimestamp(activeThread.id)
114115
setPrompt('')
115116
try {
116117
if (selectedModel?.id) {
@@ -133,11 +134,11 @@ export const useChat = () => {
133134
// Filter tools based on model capabilities and available tools for this thread
134135
let availableTools = selectedModel?.capabilities?.includes('tools')
135136
? tools.filter((tool) => {
136-
const availableToolNames = getAvailableToolsForThread(
137-
activeThread.id
138-
)
139-
return availableToolNames.includes(tool.name)
140-
})
137+
const availableToolNames = getAvailableToolsForThread(
138+
activeThread.id
139+
)
140+
return availableToolNames.includes(tool.name)
141+
})
141142
: []
142143

143144
// TODO: Later replaced by Agent setup?
@@ -213,6 +214,7 @@ export const useChat = () => {
213214
allowAllMCPPermissions
214215
)
215216
addMessage(updatedMessage ?? finalContent)
217+
updateThreadTimestamp(activeThread.id)
216218

217219
isCompleted = !toolCalls.length
218220
// Do not create agent loop if there is no need for it
@@ -236,6 +238,7 @@ export const useChat = () => {
236238
setAbortController,
237239
updateStreamingContent,
238240
addMessage,
241+
updateThreadTimestamp,
239242
setPrompt,
240243
selectedModel,
241244
currentAssistant,

web-app/src/hooks/useThreads.ts

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type ThreadState = {
2626
updateCurrentThreadModel: (model: ThreadModel) => void
2727
getFilteredThreads: (searchTerm: string) => Thread[]
2828
updateCurrentThreadAssistant: (assistant: Assistant) => void
29+
updateThreadTimestamp: (threadId: string) => void
2930
searchIndex: Fzf<Thread[]> | null
3031
}
3132

@@ -164,7 +165,7 @@ export const useThreads = create<ThreadState>()(
164165
id: ulid(),
165166
title: title ?? 'New Thread',
166167
model,
167-
order: 1, // Will be set properly by setThreads
168+
// order: 1, // Will be set properly by setThreads
168169
updated: Date.now() / 1000,
169170
assistants: assistant ? [assistant] : [],
170171
}
@@ -244,6 +245,62 @@ export const useThreads = create<ThreadState>()(
244245
const { currentThreadId, threads } = get()
245246
return currentThreadId ? threads[currentThreadId] : undefined
246247
},
248+
updateThreadTimestamp: (threadId) => {
249+
set((state) => {
250+
const thread = state.threads[threadId]
251+
if (!thread) return state
252+
253+
// If the thread is already at order 1, just update the timestamp
254+
if (thread.order === 1) {
255+
const updatedThread = {
256+
...thread,
257+
updated: Date.now() / 1000,
258+
}
259+
updateThread(updatedThread)
260+
261+
return {
262+
threads: {
263+
...state.threads,
264+
[threadId]: updatedThread,
265+
},
266+
}
267+
}
268+
269+
// Update the thread with new timestamp and set it to order 1 (top)
270+
const updatedThread = {
271+
...thread,
272+
updated: Date.now() / 1000,
273+
order: 1,
274+
}
275+
276+
// Update all other threads to increment their order by 1
277+
const updatedThreads = { ...state.threads }
278+
Object.keys(updatedThreads).forEach(id => {
279+
if (id !== threadId) {
280+
const otherThread = updatedThreads[id]
281+
updatedThreads[id] = {
282+
...otherThread,
283+
order: (otherThread.order || 1) + 1,
284+
}
285+
// Update the backend for other threads
286+
updateThread(updatedThreads[id])
287+
}
288+
})
289+
290+
// Set the updated thread
291+
updatedThreads[threadId] = updatedThread
292+
293+
// Update the backend for the main thread
294+
updateThread(updatedThread)
295+
296+
return {
297+
threads: updatedThreads,
298+
searchIndex: new Fzf<Thread[]>(Object.values(updatedThreads), {
299+
selector: (item: Thread) => item.title,
300+
}),
301+
}
302+
})
303+
},
247304
}),
248305
{
249306
name: localStorageKey.threads,

0 commit comments

Comments
 (0)