From 08bc989084e44d3d7795bb836cf81848678e37e0 Mon Sep 17 00:00:00 2001 From: Shahmeer Khan Date: Thu, 17 Jul 2025 11:36:27 +0100 Subject: [PATCH] updates to add 3.7 --- src/components/ClaudeCodeSession.tsx | 51 ++++++++++++++++++++++---- src/components/FloatingPromptInput.tsx | 14 +++++-- src/components/UsageDashboard.tsx | 2 + 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/components/ClaudeCodeSession.tsx b/src/components/ClaudeCodeSession.tsx index 2dc9a9b6..752c34d0 100644 --- a/src/components/ClaudeCodeSession.tsx +++ b/src/components/ClaudeCodeSession.tsx @@ -94,7 +94,12 @@ export const ClaudeCodeSession: React.FC = ({ const [forkSessionName, setForkSessionName] = useState(""); // Queued prompts state - const [queuedPrompts, setQueuedPrompts] = useState>([]); + const [queuedPrompts, setQueuedPrompts] = useState>([]); // New state for preview feature const [showPreview, setShowPreview] = useState(false); @@ -110,7 +115,12 @@ export const ClaudeCodeSession: React.FC = ({ const unlistenRefs = useRef([]); const hasActiveSessionRef = useRef(false); const floatingPromptRef = useRef(null); - const queuedPromptsRef = useRef>([]); + const queuedPromptsRef = useRef>([]); const isMountedRef = useRef(true); const isListeningRef = useRef(false); @@ -398,9 +408,14 @@ export const ClaudeCodeSession: React.FC = ({ } }; - const handleSendPrompt = async (prompt: string, model: "sonnet" | "opus") => { + const handleSendPrompt = async (prompt: string, model: "sonnet" | "opus" | "sonnet-3-7") => { console.log('[ClaudeCodeSession] handleSendPrompt called with:', { prompt, model, projectPath, claudeSessionId, effectiveSession }); + // Map UI model selection to the actual model ID to send to Claude CLI + const modelId = model === "sonnet-3-7" + ? "us.anthropic.claude-3-7-sonnet-20250219-v1:0" + : model; + if (!projectPath) { setError("Please select a project directory first"); return; @@ -411,7 +426,8 @@ export const ClaudeCodeSession: React.FC = ({ const newPrompt = { id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, prompt, - model + model, // Keep the UI model value for type safety + _modelId: modelId // Store the mapped model ID for actual API calls }; setQueuedPrompts(prev => [...prev, newPrompt]); return; @@ -556,7 +572,28 @@ export const ClaudeCodeSession: React.FC = ({ // Small delay to ensure UI updates setTimeout(() => { - handleSendPrompt(nextPrompt.prompt, nextPrompt.model); + // If we have a stored _modelId from mapping, use that directly + if (nextPrompt._modelId) { + // Here we directly call the API with the stored modelId + const modelId = nextPrompt._modelId; + (async () => { + try { + setIsLoading(true); + if (effectiveSession && !isFirstPrompt) { + await api.resumeClaudeCode(projectPath, effectiveSession.id, nextPrompt.prompt, modelId); + } else { + setIsFirstPrompt(false); + await api.executeClaudeCode(projectPath, nextPrompt.prompt, modelId); + } + } catch (err) { + console.error("Failed to process queued prompt:", err); + setIsLoading(false); + } + })(); + } else { + // Fall back to normal flow if _modelId isn't available + handleSendPrompt(nextPrompt.prompt, nextPrompt.model); + } }, 100); } }; @@ -595,11 +632,11 @@ export const ClaudeCodeSession: React.FC = ({ // Execute the appropriate command if (effectiveSession && !isFirstPrompt) { console.log('[ClaudeCodeSession] Resuming session:', effectiveSession.id); - await api.resumeClaudeCode(projectPath, effectiveSession.id, prompt, model); + await api.resumeClaudeCode(projectPath, effectiveSession.id, prompt, modelId); } else { console.log('[ClaudeCodeSession] Starting new session'); setIsFirstPrompt(false); - await api.executeClaudeCode(projectPath, prompt, model); + await api.executeClaudeCode(projectPath, prompt, modelId); } } } catch (err) { diff --git a/src/components/FloatingPromptInput.tsx b/src/components/FloatingPromptInput.tsx index be3507e4..6c8da610 100644 --- a/src/components/FloatingPromptInput.tsx +++ b/src/components/FloatingPromptInput.tsx @@ -25,7 +25,7 @@ interface FloatingPromptInputProps { /** * Callback when prompt is sent */ - onSend: (prompt: string, model: "sonnet" | "opus") => void; + onSend: (prompt: string, model: "sonnet" | "opus" | "sonnet-3-7") => void; /** * Whether the input is loading */ @@ -37,7 +37,7 @@ interface FloatingPromptInputProps { /** * Default model to select */ - defaultModel?: "sonnet" | "opus"; + defaultModel?: "sonnet" | "opus" | "sonnet-3-7"; /** * Project path for file picker */ @@ -129,7 +129,7 @@ const ThinkingModeIndicator: React.FC<{ level: number }> = ({ level }) => { }; type Model = { - id: "sonnet" | "opus"; + id: "sonnet" | "opus" | "sonnet-3-7"; name: string; description: string; icon: React.ReactNode; @@ -147,6 +147,12 @@ const MODELS: Model[] = [ name: "Claude 4 Opus", description: "More capable, better for complex tasks", icon: + }, + { + id: "sonnet-3-7", + name: "Claude 3.7 Sonnet", + description: "Latest Sonnet model with improved capabilities", + icon: } ]; @@ -174,7 +180,7 @@ const FloatingPromptInputInner = ( ref: React.Ref, ) => { const [prompt, setPrompt] = useState(""); - const [selectedModel, setSelectedModel] = useState<"sonnet" | "opus">(defaultModel); + const [selectedModel, setSelectedModel] = useState<"sonnet" | "opus" | "sonnet-3-7">(defaultModel); const [selectedThinkingMode, setSelectedThinkingMode] = useState("auto"); const [isExpanded, setIsExpanded] = useState(false); const [modelPickerOpen, setModelPickerOpen] = useState(false); diff --git a/src/components/UsageDashboard.tsx b/src/components/UsageDashboard.tsx index 81890fb3..8fc85002 100644 --- a/src/components/UsageDashboard.tsx +++ b/src/components/UsageDashboard.tsx @@ -114,8 +114,10 @@ export const UsageDashboard: React.FC = ({ onBack }) => { const modelMap: Record = { "claude-4-opus": "Opus 4", "claude-4-sonnet": "Sonnet 4", + "claude-3.7-sonnet": "Sonnet 3.7", "claude-3.5-sonnet": "Sonnet 3.5", "claude-3-opus": "Opus 3", + "us.anthropic.claude-3-7-sonnet-20250219-v1:0": "Sonnet 3.7", }; return modelMap[model] || model; };