From 0be2177937e598699ed23a225c20b145d12e28a8 Mon Sep 17 00:00:00 2001 From: icarus Date: Fri, 26 Sep 2025 14:31:56 +0800 Subject: [PATCH] fix(chat): handle agent and session state changes properly update activeAgentId type to allow null and reset state when deleting agent add validation for missing agent/session in UI components --- src/renderer/src/hooks/agents/useAgents.ts | 15 +++++++++ src/renderer/src/pages/home/Chat.tsx | 29 +++++++++++++++-- .../src/pages/home/Tabs/SessionsTab.tsx | 31 ++++++------------- src/renderer/src/store/runtime.ts | 2 +- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/src/renderer/src/hooks/agents/useAgents.ts b/src/renderer/src/hooks/agents/useAgents.ts index 700661d103..c3adc65095 100644 --- a/src/renderer/src/hooks/agents/useAgents.ts +++ b/src/renderer/src/hooks/agents/useAgents.ts @@ -1,9 +1,12 @@ +import { useAppDispatch } from '@renderer/store' +import { setActiveAgentId, setActiveSessionIdAction } from '@renderer/store/runtime' import { AddAgentForm } from '@renderer/types' import { formatErrorMessageWithPrefix } from '@renderer/utils/error' import { useCallback } from 'react' import { useTranslation } from 'react-i18next' import useSWR from 'swr' +import { useRuntime } from '../useRuntime' import { useAgentClient } from './useAgentClient' export const useAgents = () => { @@ -16,6 +19,9 @@ export const useAgents = () => { return result.data }, [client]) const { data, error, isLoading, mutate } = useSWR(key, fetcher) + const { chat } = useRuntime() + const { activeAgentId } = chat + const dispatch = useAppDispatch() const addAgent = useCallback( async (form: AddAgentForm) => { @@ -34,6 +40,15 @@ export const useAgents = () => { async (id: string) => { try { await client.deleteAgent(id) + dispatch(setActiveSessionIdAction({ agentId: id, sessionId: null })) + if (activeAgentId === id) { + const newId = data?.filter((a) => a.id !== id).find(() => true)?.id + if (newId) { + dispatch(setActiveAgentId(newId)) + } else { + dispatch(setActiveAgentId(null)) + } + } mutate((prev) => prev?.filter((a) => a.id !== id) ?? []) window.toast.success(t('common.delete_success')) } catch (error) { diff --git a/src/renderer/src/pages/home/Chat.tsx b/src/renderer/src/pages/home/Chat.tsx index d5870add7f..12ba9d7573 100644 --- a/src/renderer/src/pages/home/Chat.tsx +++ b/src/renderer/src/pages/home/Chat.tsx @@ -18,7 +18,7 @@ import { classNames } from '@renderer/utils' import { Flex } from 'antd' import { debounce } from 'lodash' import { AnimatePresence, motion } from 'motion/react' -import React, { FC, useMemo, useState } from 'react' +import React, { FC, useCallback, useMemo, useState } from 'react' import { useHotkeys } from 'react-hotkeys-hook' import { useTranslation } from 'react-i18next' import styled from 'styled-components' @@ -172,6 +172,27 @@ const Chat: FC = (props) => { return () => }, [activeAgentId, activeSessionId]) + // TODO: more info + const AgentInvalid = useCallback(() => { + return ( +
+
+ +
+
+ ) + }, []) + + // TODO: more info + const SessionInvalid = useCallback(() => { + return ( +
+
+ +
+
+ ) + }, []) return ( {isTopNavbar && ( @@ -213,7 +234,11 @@ const Chat: FC = (props) => { )} - {activeTopicOrSession === 'session' && ( + {activeTopicOrSession === 'session' && !activeAgentId && } + {activeTopicOrSession === 'session' && activeAgentId && !activeSessionId[activeAgentId] && ( + + )} + {activeTopicOrSession === 'session' && activeAgentId && activeSessionId[activeAgentId] && ( <> diff --git a/src/renderer/src/pages/home/Tabs/SessionsTab.tsx b/src/renderer/src/pages/home/Tabs/SessionsTab.tsx index fa62ce812e..59d44a5f15 100644 --- a/src/renderer/src/pages/home/Tabs/SessionsTab.tsx +++ b/src/renderer/src/pages/home/Tabs/SessionsTab.tsx @@ -1,4 +1,4 @@ -import { Alert, cn, Spinner } from '@heroui/react' +import { Alert, cn } from '@heroui/react' import { useRuntime } from '@renderer/hooks/useRuntime' import { useSettings } from '@renderer/hooks/useSettings' import { AnimatePresence, motion } from 'framer-motion' @@ -24,6 +24,14 @@ const SessionsTab: FC = () => { ) } + if (!activeAgentId) { + return ( +
+ +
+ ) + } + return ( = () => { 'overflow-hidden', topicPosition === 'right' && navbarPosition === 'top' ? 'rounded-l-2xl border-t border-b border-l' : undefined )}> - {!activeAgentId ? ( - - - - {t('common.loading')}... - - - ) : ( - - )} + ) diff --git a/src/renderer/src/store/runtime.ts b/src/renderer/src/store/runtime.ts index 4c0183e9e4..fe556b9a9e 100644 --- a/src/renderer/src/store/runtime.ts +++ b/src/renderer/src/store/runtime.ts @@ -158,7 +158,7 @@ const runtimeSlice = createSlice({ // @ts-ignore ts2589 false positive state.chat.activeTopic = action.payload }, - setActiveAgentId: (state, action: PayloadAction) => { + setActiveAgentId: (state, action: PayloadAction) => { state.chat.activeAgentId = action.payload }, setActiveSessionIdAction: (state, action: PayloadAction<{ agentId: string; sessionId: string | null }>) => {