summaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'frontend')
-rw-r--r--frontend/src/components/LeftSidebar.tsx106
1 files changed, 64 insertions, 42 deletions
diff --git a/frontend/src/components/LeftSidebar.tsx b/frontend/src/components/LeftSidebar.tsx
index d802fde..dc2e7b3 100644
--- a/frontend/src/components/LeftSidebar.tsx
+++ b/frontend/src/components/LeftSidebar.tsx
@@ -63,6 +63,7 @@ const LeftSidebar: React.FC<LeftSidebarProps> = ({ isOpen, onToggle }) => {
const [openaiApiKey, setOpenaiApiKey] = useState('');
const [geminiApiKey, setGeminiApiKey] = useState('');
const [showGuide, setShowGuide] = useState(false);
+ const [guideSection, setGuideSection] = useState<string | null>(null);
const [claudeApiKey, setClaudeApiKey] = useState('');
const [openrouterApiKey, setOpenrouterApiKey] = useState('');
const [showOpenaiKey, setShowOpenaiKey] = useState(false);
@@ -748,48 +749,69 @@ const LeftSidebar: React.FC<LeftSidebarProps> = ({ isOpen, onToggle }) => {
</button>
{showGuide && (
- <div className={`mt-3 text-xs space-y-3 ${isDark ? 'text-gray-400' : 'text-gray-600'}`}>
- <div>
- <p className={`font-medium mb-1 ${isDark ? 'text-gray-300' : 'text-gray-700'}`}>🎯 Basic Operations</p>
- <ul className="list-disc list-inside space-y-1 ml-1">
- <li><span className="font-medium">Right-click</span> canvas to create a node</li>
- <li><span className="font-medium">Drag</span> from handle to connect nodes</li>
- <li><span className="font-medium">Click</span> node to edit in right sidebar</li>
- <li><span className="font-medium">Delete</span> key to remove selected node</li>
- </ul>
- </div>
-
- <div>
- <p className={`font-medium mb-1 ${isDark ? 'text-gray-300' : 'text-gray-700'}`}>🔀 Traces & Branching</p>
- <ul className="list-disc list-inside space-y-1 ml-1">
- <li><span className="font-medium">Traces</span> = conversation paths through nodes</li>
- <li><span className="font-medium">Fork</span> a trace by connecting to new node</li>
- <li><span className="font-medium">Merge</span> traces by connecting multiple inputs</li>
- <li>Select active traces in the right sidebar</li>
- </ul>
- </div>
-
- <div>
- <p className={`font-medium mb-1 ${isDark ? 'text-gray-300' : 'text-gray-700'}`}>💬 Quick Chat</p>
- <ul className="list-disc list-inside space-y-1 ml-1">
- <li>Right-click node → <span className="font-medium">Quick Chat</span></li>
- <li>Continue conversation from any trace</li>
- <li>Auto-creates connected nodes as you chat</li>
- </ul>
- </div>
-
- <div>
- <p className={`font-medium mb-1 ${isDark ? 'text-gray-300' : 'text-gray-700'}`}>📎 File Attachments (OpenAI only)</p>
- <ul className="list-disc list-inside space-y-1 ml-1">
- <li>Upload files in <span className="font-medium">Files</span> tab (left sidebar)</li>
- <li>Attach to nodes in <span className="font-medium">Settings</span> tab (right)</li>
- <li>LLM can search attached files via <span className="font-medium">file_search</span></li>
- </ul>
- </div>
-
- <div className={`p-2 rounded ${isDark ? 'bg-blue-900/30' : 'bg-blue-50'}`}>
- <p className={`font-medium ${isDark ? 'text-blue-400' : 'text-blue-600'}`}>💡 Tip</p>
- <p>Use <span className="font-medium">Ctrl+S</span> to save, or enable auto-save below.</p>
+ <div className={`mt-2 text-xs ${isDark ? 'text-gray-400' : 'text-gray-600'}`}>
+ {[
+ { key: 'canvas', icon: '🎯', title: 'Canvas & Nodes', items: [
+ <><span className="font-medium">Right-click</span> canvas to create a node</>,
+ <><span className="font-medium">Drag</span> from handle to connect nodes</>,
+ <><span className="font-medium">Click</span> node to edit in right sidebar</>,
+ <><span className="font-medium">Shift-drag</span> to select multiple nodes</>,
+ <><span className="font-medium">Delete</span> key to remove selected</>,
+ <><span className="font-medium">Auto Layout</span> arranges nodes hierarchically</>,
+ ]},
+ { key: 'traces', icon: '🔀', title: 'Traces & Branching', items: [
+ <><span className="font-medium">Traces</span> = conversation paths through nodes</>,
+ <><span className="font-medium">Fork</span> by connecting to a new node</>,
+ <><span className="font-medium">Merge</span> 2+ traces with summarization & strategy</>,
+ <><span className="font-medium">Unfold</span> a merged trace back to components</>,
+ <>Select active traces in right sidebar to control context</>,
+ ]},
+ { key: 'chat', icon: '💬', title: 'Quick Chat', items: [
+ <>Open from right sidebar on any node/trace</>,
+ <>Auto-creates connected nodes as you chat</>,
+ <>Supports <span className="font-medium">Council mode</span> toggle</>,
+ <>Supports file attachments & image paste</>,
+ ]},
+ { key: 'council', icon: '👥', title: 'Council Mode', items: [
+ <>Select 2+ models in right sidebar</>,
+ <>Stage 1: models answer independently</>,
+ <>Stage 2: models rank each other</>,
+ <>Stage 3: chairman synthesizes final answer</>,
+ <>View in <span className="font-medium">Final / Responses / Rankings</span> tabs</>,
+ ]},
+ { key: 'debate', icon: '⚔️', title: 'Debate Mode', items: [
+ <>Select 2+ models + judge in right sidebar</>,
+ <>Multi-round turn-based structured debate</>,
+ <>Judges: External, Self-Convergence, Display Only</>,
+ <>View in <span className="font-medium">Timeline / Per-Model / Final</span> tabs</>,
+ ]},
+ { key: 'files', icon: '📎', title: 'Files & Attachments', items: [
+ <>Upload in <span className="font-medium">Files</span> tab (PDF, TXT, images, etc.)</>,
+ <>Attach to nodes in <span className="font-medium">Settings</span> tab</>,
+ <>Paste images with <span className="font-medium">Ctrl+V</span></>,
+ <>Works with OpenAI, Claude & Gemini (48h expiry)</>,
+ ]},
+ { key: 'keys', icon: '⌨️', title: 'Shortcuts', items: [
+ <><span className="font-medium">Ctrl+S</span> save &nbsp; <span className="font-medium">Enter</span> send &nbsp; <span className="font-medium">Shift+Enter</span> newline &nbsp; <span className="font-medium">Del</span> remove</>,
+ ]},
+ ].map(section => (
+ <div key={section.key} className={`border-b last:border-b-0 ${isDark ? 'border-gray-700/50' : 'border-gray-200/70'}`}>
+ <button
+ onClick={() => setGuideSection(guideSection === section.key ? null : section.key)}
+ className={`w-full flex items-center justify-between py-1.5 text-xs font-medium ${isDark ? 'text-gray-300' : 'text-gray-700'}`}
+ >
+ <span>{section.icon} {section.title}</span>
+ <ChevronRight size={12} className={`transition-transform ${guideSection === section.key ? 'rotate-90' : ''}`} />
+ </button>
+ {guideSection === section.key && (
+ <ul className={`list-disc list-inside space-y-0.5 ml-1 pb-2 ${isDark ? 'text-gray-400' : 'text-gray-600'}`}>
+ {section.items.map((item, i) => <li key={i}>{item}</li>)}
+ </ul>
+ )}
+ </div>
+ ))}
+ <div className={`mt-1 p-1.5 rounded text-[11px] ${isDark ? 'bg-blue-900/30 text-blue-400' : 'bg-blue-50 text-blue-600'}`}>
+ 💡 Enable <span className="font-medium">web search</span> for live answers &middot; Turn on <span className="font-medium">auto-save</span> below
</div>
</div>
)}