()
| 20 | import { cn } from '@/lib/utils'; |
| 21 | |
| 22 | export const AppShell: React.FC = () => { |
| 23 | const { addMessage, appendStreamToken, setStreaming, clearStreaming, setMessages, addTokenUsage } = useChatStore(); |
| 24 | const setProjects = useProjectStore((s) => s.setProjects); |
| 25 | const addProject = useProjectStore((s) => s.addProject); |
| 26 | const setActiveProjectId = useProjectStore((s) => s.setActiveProjectId); |
| 27 | const activeSessionId = useSessionStore((s) => s.activeSessionId); |
| 28 | const setSessions = useSessionStore((s) => s.setSessions); |
| 29 | const addSession = useSessionStore((s) => s.addSession); |
| 30 | const setActiveSessionId = useSessionStore((s) => s.setActiveSessionId); |
| 31 | const { setProviders, setDefaultProviderId, defaultProviderId, selectedModelId, setSelectedModelId } = useSettingsStore(); |
| 32 | const leftSidebarOpen = useUIStore((s) => s.leftSidebarOpen); |
| 33 | const toggleLeftSidebar = useUIStore((s) => s.toggleLeftSidebar); |
| 34 | const rightSidebarOpen = useUIStore((s) => s.rightSidebarOpen); |
| 35 | const mainView = useUIStore((s) => s.mainView); |
| 36 | |
| 37 | const { |
| 38 | addAgentRun, |
| 39 | setAgentRuns, |
| 40 | updateAgentRun, |
| 41 | appendAgentToken, |
| 42 | flushThinkingBlock, |
| 43 | setAgentConfigs, |
| 44 | setPendingPermission, |
| 45 | pendingPermission, |
| 46 | selectedAgentType, |
| 47 | agentConfigs, |
| 48 | } = useAgentStore(); |
| 49 | |
| 50 | const chatInputRef = React.useRef<ChatInputBarHandle>(null); |
| 51 | |
| 52 | // Track which sessions have already been auto-renamed to avoid duplicates |
| 53 | const renamedSessionsRef = React.useRef<Set<string>>(new Set()); |
| 54 | |
| 55 | const autoRenameSession = React.useCallback((sessionId: string) => { |
| 56 | if (renamedSessionsRef.current.has(sessionId)) return; |
| 57 | |
| 58 | const session = useSessionStore.getState().sessions.find(s => s.id === sessionId); |
| 59 | if (!session || session.title !== 'New Chat') return; |
| 60 | |
| 61 | renamedSessionsRef.current.add(sessionId); |
| 62 | |
| 63 | // Ask the LLM to generate a short title based on the conversation |
| 64 | const { defaultProviderId: pid, selectedModelId: mid } = useSettingsStore.getState(); |
| 65 | invoke<string>('generate_title', { |
| 66 | sessionId, |
| 67 | providerId: pid ?? null, |
| 68 | modelId: mid ?? null, |
| 69 | }) |
| 70 | .then((title) => { |
| 71 | if (title && title !== 'New Chat') { |
| 72 | useSessionStore.getState().updateSessionTitle(sessionId, title); |
| 73 | invoke('update_session_title', { id: sessionId, title }).catch(console.error); |
| 74 | } |
| 75 | }) |
| 76 | .catch((err) => { |
| 77 | console.error('Auto-rename failed:', err); |
| 78 | // Remove from set so it can retry next time |
| 79 | renamedSessionsRef.current.delete(sessionId); |
nothing calls this directly
no test coverage detected