feat: add updateThreadTimestamp function to manage thread order and timestamp updates (#5180)

This commit is contained in:
Sam Hoang Van 2025-06-03 18:53:58 +07:00 committed by GitHub
parent cf56f7e5c0
commit a3ebabfd4e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 68 additions and 8 deletions

View File

@ -49,7 +49,7 @@ export const useChat = () => {
const { getProviderByName, selectedModel, selectedProvider } =
useModelProvider()
const { getCurrentThread: retrieveThread, createThread } = useThreads()
const { getCurrentThread: retrieveThread, createThread, updateThreadTimestamp } = useThreads()
const { getMessages, addMessage } = useMessages()
const router = useRouter()
@ -65,7 +65,7 @@ export const useChat = () => {
}
setTools()
let unsubscribe = () => {}
let unsubscribe = () => { }
listen(SystemEvent.MCP_UPDATE, setTools).then((unsub) => {
// Unsubscribe from the event when the component unmounts
unsubscribe = unsub
@ -111,6 +111,7 @@ export const useChat = () => {
setAbortController(activeThread.id, abortController)
updateStreamingContent(emptyThreadContent)
addMessage(newUserThreadContent(activeThread.id, message))
updateThreadTimestamp(activeThread.id)
setPrompt('')
try {
if (selectedModel?.id) {
@ -133,11 +134,11 @@ export const useChat = () => {
// Filter tools based on model capabilities and available tools for this thread
let availableTools = selectedModel?.capabilities?.includes('tools')
? tools.filter((tool) => {
const availableToolNames = getAvailableToolsForThread(
activeThread.id
)
return availableToolNames.includes(tool.name)
})
const availableToolNames = getAvailableToolsForThread(
activeThread.id
)
return availableToolNames.includes(tool.name)
})
: []
// TODO: Later replaced by Agent setup?
@ -213,6 +214,7 @@ export const useChat = () => {
allowAllMCPPermissions
)
addMessage(updatedMessage ?? finalContent)
updateThreadTimestamp(activeThread.id)
isCompleted = !toolCalls.length
// Do not create agent loop if there is no need for it
@ -236,6 +238,7 @@ export const useChat = () => {
setAbortController,
updateStreamingContent,
addMessage,
updateThreadTimestamp,
setPrompt,
selectedModel,
currentAssistant,

View File

@ -26,6 +26,7 @@ type ThreadState = {
updateCurrentThreadModel: (model: ThreadModel) => void
getFilteredThreads: (searchTerm: string) => Thread[]
updateCurrentThreadAssistant: (assistant: Assistant) => void
updateThreadTimestamp: (threadId: string) => void
searchIndex: Fzf<Thread[]> | null
}
@ -164,7 +165,7 @@ export const useThreads = create<ThreadState>()(
id: ulid(),
title: title ?? 'New Thread',
model,
order: 1, // Will be set properly by setThreads
// order: 1, // Will be set properly by setThreads
updated: Date.now() / 1000,
assistants: assistant ? [assistant] : [],
}
@ -244,6 +245,62 @@ export const useThreads = create<ThreadState>()(
const { currentThreadId, threads } = get()
return currentThreadId ? threads[currentThreadId] : undefined
},
updateThreadTimestamp: (threadId) => {
set((state) => {
const thread = state.threads[threadId]
if (!thread) return state
// If the thread is already at order 1, just update the timestamp
if (thread.order === 1) {
const updatedThread = {
...thread,
updated: Date.now() / 1000,
}
updateThread(updatedThread)
return {
threads: {
...state.threads,
[threadId]: updatedThread,
},
}
}
// Update the thread with new timestamp and set it to order 1 (top)
const updatedThread = {
...thread,
updated: Date.now() / 1000,
order: 1,
}
// Update all other threads to increment their order by 1
const updatedThreads = { ...state.threads }
Object.keys(updatedThreads).forEach(id => {
if (id !== threadId) {
const otherThread = updatedThreads[id]
updatedThreads[id] = {
...otherThread,
order: (otherThread.order || 1) + 1,
}
// Update the backend for other threads
updateThread(updatedThreads[id])
}
})
// Set the updated thread
updatedThreads[threadId] = updatedThread
// Update the backend for the main thread
updateThread(updatedThread)
return {
threads: updatedThreads,
searchIndex: new Fzf<Thread[]>(Object.values(updatedThreads), {
selector: (item: Thread) => item.title,
}),
}
})
},
}),
{
name: localStorageKey.threads,