Add pendingChatLibrarySlug state and related logic in App.jsx
This commit is contained in:
109
src/App.jsx
109
src/App.jsx
@@ -143,6 +143,7 @@ export default function App() {
|
|||||||
const [libraryJobs, setLibraryJobs] = useState([])
|
const [libraryJobs, setLibraryJobs] = useState([])
|
||||||
const [activeLibrarySlug, setActiveLibrarySlug] = useState(null)
|
const [activeLibrarySlug, setActiveLibrarySlug] = useState(null)
|
||||||
const [chatLibrarySlug, setChatLibrarySlug] = useState(localStorage.getItem(CHAT_LIBRARY_KEY) || null)
|
const [chatLibrarySlug, setChatLibrarySlug] = useState(localStorage.getItem(CHAT_LIBRARY_KEY) || null)
|
||||||
|
const [pendingChatLibrarySlug, setPendingChatLibrarySlug] = useState(null)
|
||||||
const [isCreatingLibrary, setIsCreatingLibrary] = useState(false)
|
const [isCreatingLibrary, setIsCreatingLibrary] = useState(false)
|
||||||
const [newLibraryName, setNewLibraryName] = useState('')
|
const [newLibraryName, setNewLibraryName] = useState('')
|
||||||
const [libraryCreateError, setLibraryCreateError] = useState('')
|
const [libraryCreateError, setLibraryCreateError] = useState('')
|
||||||
@@ -721,6 +722,22 @@ async function regenerateFromIndex(index, overrideUserText = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function startLibraryJob(slug, kind) {
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' }
|
||||||
|
}
|
||||||
|
if (kind === 'embed') {
|
||||||
|
options.body = JSON.stringify({})
|
||||||
|
}
|
||||||
|
const response = await fetch(`${ollamaApiUrl}/libraries/${slug}/jobs/${kind}`, options)
|
||||||
|
if (!response.ok) {
|
||||||
|
const detail = await response.text()
|
||||||
|
throw new Error(detail || `HTTP ${response.status}`)
|
||||||
|
}
|
||||||
|
await refreshLibraryJobs()
|
||||||
|
}
|
||||||
|
|
||||||
async function createLibrary(nameOverride = null) {
|
async function createLibrary(nameOverride = null) {
|
||||||
const rawName = typeof nameOverride === 'string' ? nameOverride : newLibraryName
|
const rawName = typeof nameOverride === 'string' ? nameOverride : newLibraryName
|
||||||
const name = rawName.trim()
|
const name = rawName.trim()
|
||||||
@@ -825,12 +842,104 @@ async function regenerateFromIndex(index, overrideUserText = null) {
|
|||||||
return libraries.find(lib => lib.slug === chatLibrarySlug) || null;
|
return libraries.find(lib => lib.slug === chatLibrarySlug) || null;
|
||||||
}, [chatLibrarySlug, libraries]);
|
}, [chatLibrarySlug, libraries]);
|
||||||
|
|
||||||
|
const pendingChatLibrary = useMemo(() => {
|
||||||
|
return libraries.find(lib => lib.slug === pendingChatLibrarySlug) || null;
|
||||||
|
}, [pendingChatLibrarySlug, libraries]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (chatLibrarySlug && chatLibrary && !chatLibrary.states?.is_indexed) {
|
if (chatLibrarySlug && chatLibrary && !chatLibrary.states?.is_indexed) {
|
||||||
setChatLibrarySlug(null)
|
setChatLibrarySlug(null)
|
||||||
}
|
}
|
||||||
}, [chatLibrarySlug, chatLibrary]);
|
}, [chatLibrarySlug, chatLibrary]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!pendingChatLibrarySlug || !ollamaApiUrl) return
|
||||||
|
|
||||||
|
const jobsForLibrary = libraryJobs
|
||||||
|
.filter(job => job.slug === pendingChatLibrarySlug)
|
||||||
|
.sort((a, b) => String(b.created_at || '').localeCompare(String(a.created_at || '')))
|
||||||
|
const hasActiveJob = jobsForLibrary.some(job => job.status === 'queued' || job.status === 'running')
|
||||||
|
const latestJob = jobsForLibrary[0] || null
|
||||||
|
|
||||||
|
if (!pendingChatLibrary) {
|
||||||
|
setPendingChatLibrarySlug(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pendingChatLibrary.states?.is_indexed) {
|
||||||
|
setChatLibrarySlug(pendingChatLibrarySlug)
|
||||||
|
setPendingChatLibrarySlug(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasActiveJob) return
|
||||||
|
|
||||||
|
if (latestJob?.status === 'failed') {
|
||||||
|
setPendingChatLibrarySlug(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pendingChatLibrary.files?.length) {
|
||||||
|
setPendingChatLibrarySlug(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let cancelled = false
|
||||||
|
;(async () => {
|
||||||
|
try {
|
||||||
|
if (!pendingChatLibrary.states?.has_corpus) {
|
||||||
|
await startLibraryJob(pendingChatLibrarySlug, 'build')
|
||||||
|
} else {
|
||||||
|
await startLibraryJob(pendingChatLibrarySlug, 'embed')
|
||||||
|
}
|
||||||
|
if (!cancelled) {
|
||||||
|
await refreshLibraries()
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to prepare library for chat', error)
|
||||||
|
if (!cancelled) {
|
||||||
|
setPendingChatLibrarySlug(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
cancelled = true
|
||||||
|
}
|
||||||
|
}, [pendingChatLibrarySlug, pendingChatLibrary, libraryJobs, ollamaApiUrl])
|
||||||
|
|
||||||
|
async function toggleChatLibrary(libraryOrSlug) {
|
||||||
|
const slug = typeof libraryOrSlug === 'string' ? libraryOrSlug : libraryOrSlug?.slug
|
||||||
|
if (!slug) return
|
||||||
|
|
||||||
|
if (chatLibrarySlug === slug || pendingChatLibrarySlug === slug) {
|
||||||
|
setChatLibrarySlug(current => (current === slug ? null : current))
|
||||||
|
setPendingChatLibrarySlug(current => (current === slug ? null : current))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const library = libraries.find(lib => lib.slug === slug)
|
||||||
|
if (!library) return
|
||||||
|
|
||||||
|
if (library.states?.is_indexed) {
|
||||||
|
setChatLibrarySlug(slug)
|
||||||
|
setPendingChatLibrarySlug(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!library.files?.length) {
|
||||||
|
throw new Error('Add files before using this database in chat.')
|
||||||
|
}
|
||||||
|
|
||||||
|
setPendingChatLibrarySlug(slug)
|
||||||
|
if (!library.states?.has_corpus) {
|
||||||
|
await startLibraryJob(slug, 'build')
|
||||||
|
} else {
|
||||||
|
await startLibraryJob(slug, 'embed')
|
||||||
|
}
|
||||||
|
await refreshLibraries()
|
||||||
|
}
|
||||||
|
|
||||||
// Persist the scrollTop of the session we are LEAVING (on chat change or when leaving the chat view)
|
// Persist the scrollTop of the session we are LEAVING (on chat change or when leaving the chat view)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const leavingSessionId = activeSessionId;
|
const leavingSessionId = activeSessionId;
|
||||||
|
|||||||
Reference in New Issue
Block a user