// 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 方法 // 处理内部表单变化的通用回调 - 直接更新 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 回调 */}