// File: frontend/app/workflow/components/LLMNode.tsx // Description: 自定义 LLM 节点组件 import React, { useState, useCallback, useEffect, memo, ChangeEvent } from 'react'; import { Handle, Position, useUpdateNodeInternals, useReactFlow, Node } from 'reactflow'; import { BrainCircuit } from 'lucide-react'; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Slider } from "@/components/ui/slider"; import { Label } from "@/components/ui/label"; import { type LLMNodeData, type CustomNodeProps, availableModels } from './types'; // 导入类型和模型列表 const LLMNodeComponent = ({ id, data, isConnectable }: CustomNodeProps) => { // const [currentData, setCurrentData] = useState(data); const updateNodeInternals = useUpdateNodeInternals(); const { setNodes } = useReactFlow(); // 获取 setNodes 方法 // 从 props 更新内部状态 (如果外部数据变化) // useEffect(() => { // setCurrentData(data); // }, [data]); // 处理内部表单变化的通用回调 - 直接更新 React Flow 主状态 const handleDataChange = useCallback((key: keyof LLMNodeData, value: any) => { // 使用 setNodes 更新特定节点的数据 setNodes((nds: Node[]) => // 显式指定类型 nds.map((node) => { if (node.id === id) { // 创建一个新的 data 对象 const updatedData = { ...node.data, [key]: value }; return { ...node, data: updatedData }; } return node; }) ); console.log(`(LLMNode) Node ${id} data updated:`, { [key]: value }); }, [id, setNodes]); // 依赖 id 和 setNodes const handleSliderChange = useCallback((value: number[]) => { handleDataChange('temperature', value[0]); }, [handleDataChange]); const handleSelectChange = useCallback((value: string) => { handleDataChange('model', value); }, [handleDataChange]); const handleTextChange = useCallback((event: ChangeEvent) => { const { name, value } = event.target; handleDataChange(name as keyof LLMNodeData, value); }, [handleDataChange]); // 检查 inputConnected 状态是否需要更新 (如果外部更新了) // 注意:这个逻辑依赖于父组件正确更新了 data.inputConnected useEffect(() => { // 可以在这里添加逻辑,如果 props.data.inputConnected 和 UI 显示不一致时触发更新 // 但通常连接状态由 onConnect/onEdgesChange 在父组件处理更佳 // updateNodeInternals(id); // 如果 Handle 显示依赖 inputConnected,可能需要调用 }, [data.inputConnected, id, updateNodeInternals]); return ( // 调整宽度,例如 w-96 (24rem)
LLM 调用

使用大语言模型生成文本

{/* 直接使用 props.data.inputConnected */} {!data.inputConnected &&

连接文本或提示

}
{/* 直接使用 props.data 和 onChange 回调 */}