diff --git a/src/components/ChatInterface.jsx b/src/components/ChatInterface.jsx index a9d5110..f0a26cf 100644 --- a/src/components/ChatInterface.jsx +++ b/src/components/ChatInterface.jsx @@ -33,6 +33,7 @@ import ClaudeStatus from './ClaudeStatus'; import TokenUsagePie from './TokenUsagePie'; import { MicButton } from './MicButton.jsx'; import { api, authenticatedFetch } from '../utils/api'; +import ThinkingModeSelector, { thinkingModes } from './ThinkingModeSelector.jsx'; import Fuse from 'fuse.js'; import CommandMenu from './CommandMenu'; import { CLAUDE_MODELS, CURSOR_MODELS, CODEX_MODELS } from '../../shared/modelConstants'; @@ -1884,6 +1885,7 @@ function ChatInterface({ selectedProject, selectedSession, ws, sendMessage, mess const [slashPosition, setSlashPosition] = useState(-1); const [visibleMessageCount, setVisibleMessageCount] = useState(100); const [claudeStatus, setClaudeStatus] = useState(null); + const [thinkingMode, setThinkingMode] = useState('none'); const [provider, setProvider] = useState(() => { return localStorage.getItem('selected-provider') || 'claude'; }); @@ -4226,6 +4228,13 @@ function ChatInterface({ selectedProject, selectedSession, ws, sendMessage, mess e.preventDefault(); if (!input.trim() || isLoading || !selectedProject) return; + // Apply thinking mode prefix if selected + let messageContent = input; + const selectedThinkingMode = thinkingModes.find(mode => mode.id === thinkingMode); + if (selectedThinkingMode && selectedThinkingMode.prefix) { + messageContent = `${selectedThinkingMode.prefix}: ${input}`; + } + // Upload images first if any let uploadedImages = []; if (attachedImages.length > 0) { @@ -4365,6 +4374,7 @@ function ChatInterface({ selectedProject, selectedSession, ws, sendMessage, mess setUploadingImages(new Map()); setImageErrors(new Map()); setIsTextareaExpanded(false); + setThinkingMode('none'); // Reset thinking mode after sending // Reset textarea height if (textareaRef.current) { @@ -5180,6 +5190,13 @@ function ChatInterface({ selectedProject, selectedSession, ws, sendMessage, mess + + {/* Thinking Mode Selector */} + {/* Token usage pie chart - positioned next to mode indicator */} { + const handleClickOutside = (event) => { + if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { + setIsOpen(false); + if (onClose) onClose(); + } + }; + + document.addEventListener('mousedown', handleClickOutside); + return () => document.removeEventListener('mousedown', handleClickOutside); + }, [onClose]); + + const currentMode = thinkingModes.find(mode => mode.id === selectedMode) || thinkingModes[0]; + const IconComponent = currentMode.icon || Brain; + + return ( + + setIsOpen(!isOpen)} + className={`w-10 h-10 sm:w-10 sm:h-10 rounded-full flex items-center justify-center transition-all duration-200 ${ + selectedMode === 'none' + ? 'bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600' + : 'bg-blue-100 hover:bg-blue-200 dark:bg-blue-900 dark:hover:bg-blue-800' + }`} + title={`Thinking mode: ${currentMode.name}`} + > + + + + {isOpen && ( + + + + + Thinking Mode + + { + setIsOpen(false); + if (onClose) onClose(); + }} + className="p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded" + > + + + + + Extended thinking gives Claude more time to evaluate alternatives + + + + + {thinkingModes.map((mode) => { + const ModeIcon = mode.icon; + const isSelected = mode.id === selectedMode; + + return ( + { + onModeChange(mode.id); + setIsOpen(false); + if (onClose) onClose(); + }} + className={`w-full px-4 py-3 text-left hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors ${ + isSelected ? 'bg-gray-50 dark:bg-gray-700' : '' + }`} + > + + + {ModeIcon ? : } + + + + + {mode.name} + + {isSelected && ( + + Active + + )} + + + {mode.description} + + {mode.prefix && ( + + {mode.prefix} + + )} + + + + ); + })} + + + + + Tip: Higher thinking modes take more time but provide more thorough analysis + + + + )} + + ); +} + +export default ThinkingModeSelector; +export { thinkingModes }; \ No newline at end of file
+ Extended thinking gives Claude more time to evaluate alternatives +
+ {mode.description} +
+ {mode.prefix} +
+ Tip: Higher thinking modes take more time but provide more thorough analysis +