| import React, { useCallback, useEffect, useState } from 'react'; |
| import ReactFlow, { Controls, useNodesState, useEdgesState, addEdge, Node, Edge } from 'reactflow'; |
| import { FiFile } from 'react-icons/fi'; |
|
|
| import 'reactflow/dist/base.css'; |
| import './index.css'; |
| import TurboNode, { TurboNodeData } from './TurboNode'; |
| import TurboEdge from './TurboEdge'; |
| import FunctionIcon from './FunctionIcon'; |
| import Sidebar from './Sidebar'; |
|
|
| const initialNodes: Node<TurboNodeData>[] = [ |
| { |
| id: '1', |
| position: { x: 0, y: 0 }, |
| data: { |
| icon: <FunctionIcon />, |
| title: 'LLM Provider', |
| subline: 'Select the LLM provider', |
| inputFields: [], |
| options: [ |
| { id: 'provider-openai', label: 'OpenAI', checked: true }, |
| { id: 'provider-azure', label: 'Azure', checked: false }, |
| { id: 'provider-cohere', label: 'Cohere', checked: false }, |
| { id: 'provider-huggingface', label: 'Hugging Face', checked: false }, |
| { id: 'provider-anthropic', label: 'Anthropic', checked: false }, |
| ], |
| }, |
| type: 'turbo', |
| }, |
| { |
| id: '2', |
| position: { x: 250, y: 0 }, |
| data: { |
| icon: <FunctionIcon />, |
| title: 'Model Selection', |
| subline: 'Choose the LLM model', |
| inputFields: [], |
| options: [ |
| { id: 'model-gpt-3.5-turbo', label: 'GPT-3.5-turbo', checked: true }, |
| { id: 'model-gpt-4', label: 'GPT-4', checked: false }, |
| { id: 'model-claude', label: 'Claude', checked: false }, |
| { id: 'model-flan-t5', label: 'Flan-T5', checked: false }, |
| ], |
| }, |
| type: 'turbo', |
| }, |
| { |
| id: '3', |
| position: { x: 500, y: 0 }, |
| data: { |
| icon: <FunctionIcon />, |
| title: 'Prompt Engineering', |
| subline: 'Configure prompt settings', |
| inputFields: [ |
| { id: 'prompt-template', label: 'Prompt Template', value: '' }, |
| { id: 'prompt-examples', label: 'Prompt Examples', value: '' }, |
| ], |
| options: [ |
| { id: 'prompt-fewshot', label: 'Few-shot Learning', checked: false }, |
| { id: 'prompt-cot', label: 'Chain-of-Thought', checked: false }, |
| ], |
| }, |
| type: 'turbo', |
| }, |
| { |
| id: '4', |
| position: { x: 750, y: 0 }, |
| data: { |
| icon: <FunctionIcon />, |
| title: 'API Settings', |
| subline: 'Set API parameters', |
| inputFields: [ |
| { id: 'api-key', label: 'API Key', value: '' }, |
| { id: 'api-base', label: 'API Base URL', value: '' }, |
| ], |
| options: [ |
| { id: 'api-streaming', label: 'Enable Streaming', checked: false }, |
| { id: 'api-retry', label: 'Enable Auto-Retry', checked: true }, |
| ], |
| }, |
| type: 'turbo', |
| }, |
| { |
| id: '5', |
| position: { x: 1000, y: 0 }, |
| data: { |
| icon: <FiFile />, |
| title: 'Output', |
| subline: 'Generated output from LLM', |
| }, |
| type: 'turbo', |
| }, |
| ]; |
|
|
| const initialEdges: Edge[] = [ |
| { |
| id: 'e1-2', |
| source: '1', |
| target: '2', |
| }, |
| { |
| id: 'e2-3', |
| source: '2', |
| target: '3', |
| }, |
| { |
| id: 'e3-4', |
| source: '3', |
| target: '4', |
| }, |
| { |
| id: 'e4-5', |
| source: '4', |
| target: '5', |
| }, |
| ]; |
|
|
| const nodeTypes = { |
| turbo: TurboNode, |
| }; |
|
|
| const edgeTypes = { |
| turbo: TurboEdge, |
| }; |
|
|
| const defaultEdgeOptions = { |
| type: 'turbo', |
| markerEnd: 'edge-circle', |
| }; |
|
|
| const App = () => { |
| const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); |
| const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); |
| const [recursiveSteps, setRecursiveSteps] = useState(1); |
| const [inputData, setInputData] = useState(''); |
|
|
| const onConnect = useCallback((params) => setEdges((els) => addEdge(params, els)), []); |
|
|
| const addRecursiveStep = () => { |
| setRecursiveSteps((prevSteps) => prevSteps + 1); |
| }; |
|
|
| const removeRecursiveStep = () => { |
| if (recursiveSteps > 1) { |
| setRecursiveSteps((prevSteps) => prevSteps - 1); |
| } |
| }; |
|
|
| const handleInputChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => { |
| setInputData(event.target.value); |
| }; |
|
|
| useEffect(() => { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| }, [recursiveSteps, inputData]); |
|
|
| return ( |
| <div className="flow-container"> |
| <ReactFlow |
| nodes={nodes} |
| edges={edges} |
| onNodesChange={onNodesChange} |
| onEdgesChange={onEdgesChange} |
| onConnect={onConnect} |
| fitView |
| nodeTypes={nodeTypes} |
| edgeTypes={edgeTypes} |
| defaultEdgeOptions={defaultEdgeOptions} |
| > |
| <Controls showInteractive={false} /> |
| <svg> |
| <defs> |
| <linearGradient id="edge-gradient"> |
| <stop offset="0%" stopColor="#ae53ba" /> |
| <stop offset="100%" stopColor="#2a8af6" /> |
| </linearGradient> |
| |
| <marker |
| id="edge-circle" |
| viewBox="-5 -5 10 10" |
| refX="0" |
| refY="0" |
| markerUnits="strokeWidth" |
| markerWidth="10" |
| markerHeight="10" |
| orient="auto" |
| > |
| <circle stroke="#2a8af6" strokeOpacity="0.75" r="2" cx="0" cy="0" /> |
| </marker> |
| </defs> |
| </svg> |
| </ReactFlow> |
| <Sidebar |
| recursiveSteps={recursiveSteps} |
| addRecursiveStep={addRecursiveStep} |
| removeRecursiveStep={removeRecursiveStep} |
| inputData={inputData} |
| handleInputChange={handleInputChange} |
| /> |
| </div> |
| ); |
| }; |
|
|
| export default App; |