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 ( +
+ + + {isOpen && ( +
+
+
+

+ Thinking Mode +

+ +
+

+ Extended thinking gives Claude more time to evaluate alternatives +

+
+ +
+ {thinkingModes.map((mode) => { + const ModeIcon = mode.icon; + const isSelected = mode.id === selectedMode; + + return ( + + ); + })} +
+ +
+

+ Tip: Higher thinking modes take more time but provide more thorough analysis +

+
+
+ )} +
+ ); +} + +export default ThinkingModeSelector; +export { thinkingModes }; \ No newline at end of file