From 7d897ad9bb5ee46839ec91992cbbf4593168f119 Mon Sep 17 00:00:00 2001 From: YurenHao0426 Date: Fri, 13 Feb 2026 03:02:36 +0000 Subject: Add Claude provider, OpenRouter fallback, and GFM markdown support - Add Claude (Anthropic) as third LLM provider with streaming support - Add OpenRouter as transparent fallback when official API keys are missing or fail - Add remark-gfm to ReactMarkdown for table/strikethrough rendering - Claude models: sonnet-4.5, opus-4, opus-4.5, opus-4.6 - Backend: new stream_claude(), stream_openrouter(), provider routing, API key CRUD - Frontend: model selectors, API key inputs for Claude and OpenRouter - Auto-migration for new DB columns (claude_api_key, openrouter_api_key) Co-Authored-By: Claude Opus 4.6 --- frontend/src/components/Sidebar.tsx | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'frontend/src/components/Sidebar.tsx') diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 5141081..78d2475 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -5,6 +5,7 @@ import { useAuthStore } from '../store/authStore'; import type { NodeData, Trace, Message, MergedTrace, MergeStrategy } from '../store/flowStore'; import type { Edge } from 'reactflow'; import ReactMarkdown from 'react-markdown'; +import remarkGfm from 'remark-gfm'; import { Play, Settings, Info, ChevronLeft, ChevronRight, Maximize2, Edit3, X, Check, FileText, MessageCircle, Send, GripVertical, GitMerge, Trash2, AlertCircle, Loader2, Navigation, Upload, Search, Link } from 'lucide-react'; interface SidebarProps { @@ -312,7 +313,7 @@ const Sidebar: React.FC = ({ isOpen, onToggle, onInteract }) => { scopes, merge_strategy: selectedNode.data.mergeStrategy || 'smart', config: { - provider: selectedNode.data.model.includes('gpt') || selectedNode.data.model === 'o3' ? 'openai' : 'google', + provider: selectedNode.data.model.includes('claude') ? 'claude' : (selectedNode.data.model.includes('gpt') || selectedNode.data.model === 'o3') ? 'openai' : 'google', model_name: selectedNode.data.model, temperature: selectedNode.data.temperature, system_prompt: selectedNode.data.systemPrompt, @@ -1004,7 +1005,9 @@ const Sidebar: React.FC = ({ isOpen, onToggle, onInteract }) => { try { // Determine provider + const isClaude = modelAtSend.includes('claude'); const isOpenAI = modelAtSend.includes('gpt') || modelAtSend === 'o3'; + const provider = isClaude ? 'claude' : isOpenAI ? 'openai' : 'google'; const reasoningModels = ['gpt-5', 'gpt-5-chat-latest', 'gpt-5-mini', 'gpt-5-nano', 'gpt-5-pro', 'gpt-5.1', 'gpt-5.1-chat-latest', 'gpt-5.2', 'gpt-5.2-chat-latest', 'gpt-5.2-pro', 'o3']; const isReasoning = reasoningModels.includes(modelAtSend); @@ -1024,7 +1027,7 @@ const Sidebar: React.FC = ({ isOpen, onToggle, onInteract }) => { scopes, merge_strategy: 'smart', config: { - provider: isOpenAI ? 'openai' : 'google', + provider, model_name: modelAtSend, temperature: isReasoning ? 1 : tempAtSend, enable_google_search: webSearchAtSend, @@ -1424,6 +1427,12 @@ const Sidebar: React.FC = ({ isOpen, onToggle, onInteract }) => { }} className="w-full border border-gray-300 rounded-md p-2 text-sm" > + + + + + + @@ -1841,7 +1850,7 @@ const Sidebar: React.FC = ({ isOpen, onToggle, onInteract }) => { ? 'bg-gray-900 border-gray-700 prose-invert text-gray-200' : 'bg-gray-50 border-gray-200 text-gray-900' }`}> - {selectedNode.data.response || (streamingNodeId === selectedNode.id ? streamBuffer : '')} + {selectedNode.data.response || (streamingNodeId === selectedNode.id ? streamBuffer : '')} )} @@ -2135,7 +2144,7 @@ const Sidebar: React.FC = ({ isOpen, onToggle, onInteract }) => { /> ) : (
- {selectedNode.data.response} + {selectedNode.data.response}
)} @@ -2419,6 +2428,12 @@ const Sidebar: React.FC = ({ isOpen, onToggle, onInteract }) => { isDark ? 'bg-gray-700 border-gray-600 text-gray-200' : 'border-gray-300 text-gray-900' }`} > + + + + + + @@ -2520,7 +2535,7 @@ const Sidebar: React.FC = ({ isOpen, onToggle, onInteract }) => {

{msg.content}

) : (
- {msg.content} + {msg.content}
)} -- cgit v1.2.3