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

View File

@ -26,6 +26,7 @@ type ThreadState = {
updateCurrentThreadModel: (model: ThreadModel) => void updateCurrentThreadModel: (model: ThreadModel) => void
getFilteredThreads: (searchTerm: string) => Thread[] getFilteredThreads: (searchTerm: string) => Thread[]
updateCurrentThreadAssistant: (assistant: Assistant) => void updateCurrentThreadAssistant: (assistant: Assistant) => void
updateThreadTimestamp: (threadId: string) => void
searchIndex: Fzf<Thread[]> | null searchIndex: Fzf<Thread[]> | null
} }
@ -164,7 +165,7 @@ export const useThreads = create<ThreadState>()(
id: ulid(), id: ulid(),
title: title ?? 'New Thread', title: title ?? 'New Thread',
model, model,
order: 1, // Will be set properly by setThreads // order: 1, // Will be set properly by setThreads
updated: Date.now() / 1000, updated: Date.now() / 1000,
assistants: assistant ? [assistant] : [], assistants: assistant ? [assistant] : [],
} }
@ -244,6 +245,62 @@ export const useThreads = create<ThreadState>()(
const { currentThreadId, threads } = get() const { currentThreadId, threads } = get()
return currentThreadId ? threads[currentThreadId] : undefined 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, name: localStorageKey.threads,