diff --git a/web/frontend/src/components/chat/chat-page.tsx b/web/frontend/src/components/chat/chat-page.tsx
index a3ab843b4..0f0471fc9 100644
--- a/web/frontend/src/components/chat/chat-page.tsx
+++ b/web/frontend/src/components/chat/chat-page.tsx
@@ -26,6 +26,7 @@ export function ChatPage() {
messages,
isTyping,
activeSessionId,
+ isLoadingSession,
sendMessage,
switchSession,
newChat,
@@ -122,13 +123,19 @@ export function ChatPage() {
className="min-h-0 flex-1 overflow-y-auto px-4 py-6 md:px-8 lg:px-24 xl:px-48"
>
- {messages.length === 0 && !isTyping && (
+ {isLoadingSession ? (
+
+
+ {t("chat.loading")}
+
+
+ ) : messages.length === 0 && !isTyping ? (
- )}
+ ) : null}
{messages.map((msg) => (
diff --git a/web/frontend/src/hooks/use-pico-chat.ts b/web/frontend/src/hooks/use-pico-chat.ts
index 4ce615dcf..3ea0f34f0 100644
--- a/web/frontend/src/hooks/use-pico-chat.ts
+++ b/web/frontend/src/hooks/use-pico-chat.ts
@@ -108,8 +108,8 @@ export function usePicoChat() {
const [connectionState, setConnectionState] =
useState("disconnected")
const [isTyping, setIsTyping] = useState(false)
- const [activeSessionId, setActiveSessionId] =
- useState(generateSessionId)
+ const [activeSessionId, setActiveSessionId] = useState("")
+ const [isLoadingSession, setIsLoadingSession] = useState(true)
const wsRef = useRef(null)
const isConnectingRef = useRef(false)
@@ -290,6 +290,39 @@ export function usePicoChat() {
return () => disconnect()
}, [disconnect])
+ // Load most recent session on initial mount
+ useEffect(() => {
+ const loadRecentSession = async () => {
+ try {
+ const sessions = await getSessions(0, 1)
+ if (sessions.length > 0) {
+ const recentSession = sessions[0]
+ const detail = await getSessionHistory(recentSession.id)
+ const fallbackTime = detail.updated
+ const historyMessages = detail.messages.map((m, i) => ({
+ id: `hist-${i}-${Date.now()}`,
+ role: m.role as "user" | "assistant",
+ content: m.content,
+ timestamp: fallbackTime,
+ }))
+ setActiveSessionId(recentSession.id)
+ setMessages(historyMessages)
+ } else {
+ // No existing sessions, create a new one
+ setActiveSessionId(generateSessionId())
+ }
+ } catch (err) {
+ console.error("Failed to load recent session:", err)
+ // Fall back to new session on error
+ setActiveSessionId(generateSessionId())
+ } finally {
+ setIsLoadingSession(false)
+ }
+ }
+
+ void loadRecentSession()
+ }, [])
+
const sendMessage = useCallback((content: string) => {
if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {
console.warn("WebSocket not connected")
@@ -379,6 +412,7 @@ export function usePicoChat() {
connectionState,
isTyping,
activeSessionId,
+ isLoadingSession,
sendMessage,
switchSession,
newChat,
diff --git a/web/frontend/src/i18n/locales/en.json b/web/frontend/src/i18n/locales/en.json
index 453c5905f..7b9a8e478 100644
--- a/web/frontend/src/i18n/locales/en.json
+++ b/web/frontend/src/i18n/locales/en.json
@@ -31,6 +31,7 @@
"historyLoadFailed": "Failed to load chat history",
"historyOpenFailed": "Failed to open this chat history",
"loadingMore": "Loading more...",
+ "loading": "Loading...",
"deleteSession": "Delete session",
"messagesCount": "{{count}} messages",
"noModel": "Select model",
diff --git a/web/frontend/src/i18n/locales/zh.json b/web/frontend/src/i18n/locales/zh.json
index b6bdedbfa..9e3f5c9c6 100644
--- a/web/frontend/src/i18n/locales/zh.json
+++ b/web/frontend/src/i18n/locales/zh.json
@@ -31,6 +31,7 @@
"historyLoadFailed": "加载历史记录失败",
"historyOpenFailed": "打开该历史会话失败",
"loadingMore": "加载更多...",
+ "loading": "加载中...",
"deleteSession": "删除会话",
"messagesCount": "{{count}} 条消息",
"noModel": "选择模型",