From 0cc4f4d86ce6318d040d6fad728d2604e8eae59d Mon Sep 17 00:00:00 2001 From: Adrian Lyjak Date: Tue, 30 Sep 2025 15:56:31 -0400 Subject: [PATCH] Bugfixes (#22) * Bugfixes: invalidate stale handlers, show upload progress/toast. Fix showcase page title * Fix some readme links * fix sonner --- README.md | 2 +- ui/package.json.jinja | 1 + ui/src/App.tsx | 3 ++- ui/src/libs/useChatHistory.ts | 27 ++++++++++++++++++++++++--- ui/src/pages/Home.tsx | 13 +++++++++---- 5 files changed, 37 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 8163f52..53ece48 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A document question-answering application built with LlamaIndex workflows and LlamaCloud services. -This application uses LlamaDeploy. For more information see [the docs](https://developers.llamaindex.ai/python/cloud/llamadeploy/getting-started) +This application uses LlamaDeploy. For more information see [the docs](https://developers.llamaindex.ai/python/cloud/llamaagents/getting-started) # Getting Started diff --git a/ui/package.json.jinja b/ui/package.json.jinja index c6382a4..37e7129 100644 --- a/ui/package.json.jinja +++ b/ui/package.json.jinja @@ -22,6 +22,7 @@ "lucide-react": "^0.544.0", "react": "^19.0.0", "react-dom": "^19.0.0", + "sonner": "^2.0.7", "tw-animate-css": "^1.3.8" }, "devDependencies": { diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 55dffe3..c09634d 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -1,4 +1,4 @@ -import { ApiProvider } from "@llamaindex/ui"; +import { ApiProvider, Toaster } from "@llamaindex/ui"; import Home from "./pages/Home"; import { Theme } from "@radix-ui/themes"; import { clients } from "@/libs/clients"; @@ -27,6 +27,7 @@ export default function App() { }, []); return ( + diff --git a/ui/src/libs/useChatHistory.ts b/ui/src/libs/useChatHistory.ts index 92a094c..d7600a1 100644 --- a/ui/src/libs/useChatHistory.ts +++ b/ui/src/libs/useChatHistory.ts @@ -1,5 +1,7 @@ import { IDBPDatabase, openDB } from "idb"; import { useEffect, useState } from "react"; +import { getResultsByHandlerId } from "@llamaindex/workflows-client"; +import { useWorkflowsClient } from "@llamaindex/ui"; export interface ChatHistory { handlerId: string; @@ -35,6 +37,7 @@ export function useChatHistory(): UseChatHistory { >(null); const [db, setDb] = useState | null>(null); const [chatCounter, setChatCounter] = useState(0); + const workflowsClient = useWorkflowsClient(); // Initialize database useEffect(() => { @@ -74,11 +77,29 @@ export function useChatHistory(): UseChatHistory { try { setLoading(true); const chats = await getChatsFromDb(); - setChatHistory(chats); + // validate the local state against the remote state + const validatedChats = await Promise.all( + chats.map(async (chat) => { + const result = await getResultsByHandlerId({ + client: workflowsClient, + path: { + handler_id: chat.handlerId, + }, + }); + if (result.response.status === 404) { + await deleteChat(chat.handlerId); + return; + } else { + return chat; + } + }), + ); + const validChats = validatedChats.filter((c) => c !== undefined); + setChatHistory(validChats); // Initialize selectedChat to the latest chat (first in sorted array) - if (chats.length > 0 && !selectedChatHandlerId) { - setSelectedChatHandlerId(chats[0].handlerId); + if (validChats.length > 0 && !selectedChatHandlerId) { + setSelectedChatHandlerId(validChats[0].handlerId); } } catch (error) { console.error("Failed to load chat history:", error); diff --git a/ui/src/pages/Home.tsx b/ui/src/pages/Home.tsx index 2992518..9a7beb8 100644 --- a/ui/src/pages/Home.tsx +++ b/ui/src/pages/Home.tsx @@ -3,7 +3,8 @@ import { useWorkflowHandlerList, WorkflowTrigger } from "@llamaindex/ui"; import { APP_TITLE, INDEX_NAME } from "../libs/config"; import { useChatHistory } from "@/libs/useChatHistory"; import Sidebar from "@/components/Sidebar"; -import { Loader } from "lucide-react"; +import { useRef, useEffect } from "react"; +import { toast } from "sonner"; export default function Home() { const chatHistory = useChatHistory(); @@ -12,6 +13,12 @@ export default function Home() { (h) => h.status === "running" && h.workflowName === "upload", ); const anyActiveHandlers = activeHandlers.length > 0; + const lastCount = useRef(activeHandlers.length); + useEffect(() => { + if (activeHandlers.length < lastCount.current) { + toast.success("Upload completed"); + } + }, [activeHandlers.length]); return (
@@ -37,10 +44,8 @@ export default function Home() { index_name: INDEX_NAME, }; }} + isProcessing={anyActiveHandlers} /> - {anyActiveHandlers && ( - - )}