List logic implemented at the nodes
This commit is contained in:
parent
590b9bdc09
commit
2a0547279c
9 changed files with 331 additions and 299 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
import { Bars3CenterLeftIcon, TrashIcon } from "@heroicons/react/24/outline";
|
import { Bars3CenterLeftIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||||
import { Input } from "@mui/material";
|
import { Input } from "@mui/material";
|
||||||
import { Handle, Position } from "reactflow";
|
import { Handle, Position } from "reactflow";
|
||||||
import { nodeColors } from "../../utils";
|
import { isValidConnection, nodeColors } from "../../utils";
|
||||||
import ToggleComponent from "../../components/toggleComponent";
|
import ToggleComponent from "../../components/toggleComponent";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
|
@ -32,11 +32,7 @@ export default function BooleanNode({ data }) {
|
||||||
type="target"
|
type="target"
|
||||||
position={Position.Right}
|
position={Position.Right}
|
||||||
id={data.name}
|
id={data.name}
|
||||||
isValidConnection={({ sourceHandle, targetHandle }) =>
|
isValidConnection={(connection) => isValidConnection(data,connection)}
|
||||||
targetHandle === sourceHandle ||
|
|
||||||
data.types[targetHandle] === sourceHandle ||
|
|
||||||
sourceHandle === "str"
|
|
||||||
}
|
|
||||||
className="-mr-1 bg-transparent border-solid border-l-8 border-y-transparent border-y-8 border-r-0 rounded-none"
|
className="-mr-1 bg-transparent border-solid border-l-8 border-y-transparent border-y-8 border-r-0 rounded-none"
|
||||||
style={{ borderLeftColor: nodeColors[data.type] }}
|
style={{ borderLeftColor: nodeColors[data.type] }}
|
||||||
></Handle>
|
></Handle>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { ChatBubbleBottomCenterTextIcon } from "@heroicons/react/24/outline";
|
import { ChatBubbleBottomCenterTextIcon } from "@heroicons/react/24/outline";
|
||||||
import Input from "../../components/inputComponent";
|
import Input from "../../components/inputComponent";
|
||||||
import { snakeToNormalCase } from "../../utils";
|
import { isValidConnection, snakeToNormalCase } from "../../utils";
|
||||||
import { Handle, Position } from "reactflow";
|
import { Handle, Position } from "reactflow";
|
||||||
import Tooltip from "../../components/TooltipComponent";
|
import Tooltip from "../../components/TooltipComponent";
|
||||||
|
|
||||||
|
|
@ -11,8 +11,8 @@ export default function ChatInputNode({ data }) {
|
||||||
<Handle
|
<Handle
|
||||||
type="target"
|
type="target"
|
||||||
position={Position.Right}
|
position={Position.Right}
|
||||||
id={data.name}
|
id='str'
|
||||||
isValidConnection={({sourceHandle, targetHandle}) => (targetHandle === sourceHandle || data.types[targetHandle] === sourceHandle || sourceHandle === 'str')}
|
isValidConnection={(connection) => isValidConnection(data,connection)}
|
||||||
className="-mr-1 bg-transparent border-solid border-l-8 border-l-blue-600 border-y-transparent border-y-8 border-r-0 rounded-none"
|
className="-mr-1 bg-transparent border-solid border-l-8 border-l-blue-600 border-y-transparent border-y-8 border-r-0 rounded-none"
|
||||||
></Handle>
|
></Handle>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { ChatBubbleBottomCenterTextIcon } from "@heroicons/react/24/outline";
|
import { ChatBubbleBottomCenterTextIcon } from "@heroicons/react/24/outline";
|
||||||
import { Handle, Position } from "reactflow";
|
import { Handle, Position } from "reactflow";
|
||||||
import Input from "../../components/inputComponent";
|
import Input from "../../components/inputComponent";
|
||||||
import { snakeToNormalCase } from "../../utils";
|
import { isValidConnection, snakeToNormalCase } from "../../utils";
|
||||||
import Tooltip from "../../components/TooltipComponent";
|
import Tooltip from "../../components/TooltipComponent";
|
||||||
|
|
||||||
export default function ChatOutputNode({ data }) {
|
export default function ChatOutputNode({ data }) {
|
||||||
|
|
@ -10,13 +10,9 @@ export default function ChatOutputNode({ data }) {
|
||||||
<Tooltip title="Message: str">
|
<Tooltip title="Message: str">
|
||||||
<Handle
|
<Handle
|
||||||
type="source"
|
type="source"
|
||||||
isValidConnection={({ sourceHandle, targetHandle }) =>
|
isValidConnection={(connection) => isValidConnection(data,connection)}
|
||||||
targetHandle === sourceHandle ||
|
|
||||||
data.types[targetHandle] === sourceHandle ||
|
|
||||||
sourceHandle === "str"
|
|
||||||
}
|
|
||||||
position={Position.Left}
|
position={Position.Left}
|
||||||
id="str"
|
id={"str|output|"+data.id}
|
||||||
className="ml-1 bg-transparent border-solid border-l-8 border-l-white border-y-transparent border-y-8 border-r-0 rounded-none"
|
className="ml-1 bg-transparent border-solid border-l-8 border-l-white border-y-transparent border-y-8 border-r-0 rounded-none"
|
||||||
></Handle>
|
></Handle>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,9 @@ import {
|
||||||
import { Handle, Position } from "reactflow";
|
import { Handle, Position } from "reactflow";
|
||||||
import Dropdown from "../../components/dropdownComponent";
|
import Dropdown from "../../components/dropdownComponent";
|
||||||
import Input from "../../components/inputComponent";
|
import Input from "../../components/inputComponent";
|
||||||
import { nodeColors, nodeIcons, snakeToNormalCase } from "../../utils";
|
import { isValidConnection, nodeColors, nodeIcons, snakeToNormalCase } from "../../utils";
|
||||||
import Tooltip from "../../components/TooltipComponent";
|
import Tooltip from "../../components/TooltipComponent";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
export default function GenericNode({ data }) {
|
export default function GenericNode({ data }) {
|
||||||
const Icon = nodeIcons[data.type];
|
const Icon = nodeIcons[data.type];
|
||||||
|
|
@ -36,12 +37,8 @@ export default function GenericNode({ data }) {
|
||||||
<Handle
|
<Handle
|
||||||
type="source"
|
type="source"
|
||||||
position={Position.Left}
|
position={Position.Left}
|
||||||
id={data.node.template[t].type}
|
id={data.node.template[t].type + "|" + t + "|" + data.id}
|
||||||
isValidConnection={({ sourceHandle, targetHandle }) =>
|
isValidConnection={(connection) => isValidConnection(data,connection)}
|
||||||
targetHandle === sourceHandle ||
|
|
||||||
data.types[targetHandle] === sourceHandle ||
|
|
||||||
sourceHandle === "str"
|
|
||||||
}
|
|
||||||
className="ml-1 bg-transparent border-solid border-l-8 border-y-transparent border-y-8 border-r-0 rounded-none"
|
className="ml-1 bg-transparent border-solid border-l-8 border-y-transparent border-y-8 border-r-0 rounded-none"
|
||||||
style={{
|
style={{
|
||||||
borderLeftColor: (nodeColors[(data.types[data.node.template[t].type] ?? data.node.template[t].type)]) ?? "gray",
|
borderLeftColor: (nodeColors[(data.types[data.node.template[t].type] ?? data.node.template[t].type)]) ?? "gray",
|
||||||
|
|
@ -58,11 +55,7 @@ export default function GenericNode({ data }) {
|
||||||
type="target"
|
type="target"
|
||||||
position={Position.Right}
|
position={Position.Right}
|
||||||
id={data.name}
|
id={data.name}
|
||||||
isValidConnection={({ sourceHandle, targetHandle }) =>
|
isValidConnection={(connection) => isValidConnection(data,connection)}
|
||||||
targetHandle === sourceHandle ||
|
|
||||||
data.types[targetHandle] === sourceHandle ||
|
|
||||||
sourceHandle === "str"
|
|
||||||
}
|
|
||||||
className="-mr-1 bg-transparent border-solid border-l-8 border-y-transparent border-y-8 border-r-0 rounded-none"
|
className="-mr-1 bg-transparent border-solid border-l-8 border-y-transparent border-y-8 border-r-0 rounded-none"
|
||||||
style={{ borderLeftColor: nodeColors[data.type] }}
|
style={{ borderLeftColor: nodeColors[data.type] }}
|
||||||
></Handle>
|
></Handle>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Bars3CenterLeftIcon, TrashIcon } from "@heroicons/react/24/outline";
|
import { Bars3CenterLeftIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||||
import Input from "../../components/inputComponent";
|
import Input from "../../components/inputComponent";
|
||||||
import { nodeColors, nodeIcons, snakeToNormalCase } from "../../utils";
|
import { isValidConnection, nodeColors, nodeIcons, snakeToNormalCase } from "../../utils";
|
||||||
import { Handle, Position } from "reactflow";
|
import { Handle, Position } from "reactflow";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ export default function InputNode({ data }) {
|
||||||
type="target"
|
type="target"
|
||||||
position={Position.Right}
|
position={Position.Right}
|
||||||
id={data.name}
|
id={data.name}
|
||||||
isValidConnection={({sourceHandle, targetHandle}) => (targetHandle === sourceHandle || data.types[targetHandle] === sourceHandle || sourceHandle === 'str')}
|
isValidConnection={(connection) => isValidConnection(data,connection)}
|
||||||
className="-mr-1 bg-transparent border-solid border-l-8 border-y-transparent border-y-8 border-r-0 rounded-none"
|
className="-mr-1 bg-transparent border-solid border-l-8 border-y-transparent border-y-8 border-r-0 rounded-none"
|
||||||
style={{borderLeftColor: nodeColors[data.type]}}
|
style={{borderLeftColor: nodeColors[data.type]}}
|
||||||
></Handle>
|
></Handle>
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,6 @@ export default function ExtraSidebar() {
|
||||||
onDragStart(event, {
|
onDragStart(event, {
|
||||||
type: 'elements',
|
type: 'elements',
|
||||||
name: 'str',
|
name: 'str',
|
||||||
types: types
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ export default function FlowPage() {
|
||||||
id: newId,
|
id: newId,
|
||||||
type: data.name === 'str' ? 'inputNode' : (data.name === 'chatInput' ? 'chatInputNode' : (data.name === 'chatOutput' ? 'chatOutputNode' : (data.name === 'bool' ? 'booleanNode' : 'genericNode'))),
|
type: data.name === 'str' ? 'inputNode' : (data.name === 'chatInput' ? 'chatInputNode' : (data.name === 'chatOutput' ? 'chatOutputNode' : (data.name === 'bool' ? 'booleanNode' : 'genericNode'))),
|
||||||
position,
|
position,
|
||||||
data: { ...data, input: '', enabled: false, instance: reactFlowInstance, onDelete: () => {setNodes(reactFlowInstance.getNodes().filter((n)=>n.id !== newId))} },
|
data: { ...data, id: newId, input: '', enabled: false, reactFlowInstance, onDelete: () => {setNodes(reactFlowInstance.getNodes().filter((n)=>n.id !== newId))} },
|
||||||
};
|
};
|
||||||
setNodes((nds) => nds.concat(newNode));
|
setNodes((nds) => nds.concat(newNode));
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,12 @@
|
||||||
import { RocketLaunchIcon, LinkIcon, CpuChipIcon, LightBulbIcon, CommandLineIcon, WrenchScrewdriverIcon, ComputerDesktopIcon } from "@heroicons/react/24/outline";
|
import {
|
||||||
|
RocketLaunchIcon,
|
||||||
|
LinkIcon,
|
||||||
|
CpuChipIcon,
|
||||||
|
LightBulbIcon,
|
||||||
|
CommandLineIcon,
|
||||||
|
WrenchScrewdriverIcon,
|
||||||
|
ComputerDesktopIcon,
|
||||||
|
} from "@heroicons/react/24/outline";
|
||||||
import { Edge, Node } from "reactflow";
|
import { Edge, Node } from "reactflow";
|
||||||
|
|
||||||
export function classNames(...classes) {
|
export function classNames(...classes) {
|
||||||
|
|
@ -94,8 +102,8 @@ export function classNames(...classes) {
|
||||||
agents: "#903BBE",
|
agents: "#903BBE",
|
||||||
tools: "#FF3434",
|
tools: "#FF3434",
|
||||||
memories: "#FF9135",
|
memories: "#FF9135",
|
||||||
elements: "#6344BE"
|
elements: "#6344BE",
|
||||||
}
|
};
|
||||||
|
|
||||||
export const nodeNames = {
|
export const nodeNames = {
|
||||||
prompts: "Prompts",
|
prompts: "Prompts",
|
||||||
|
|
@ -105,8 +113,7 @@ export function classNames(...classes) {
|
||||||
tools: "Tools",
|
tools: "Tools",
|
||||||
memories: "Memories",
|
memories: "Memories",
|
||||||
elements: "Elements",
|
elements: "Elements",
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
export const nodeIcons = {
|
export const nodeIcons = {
|
||||||
agents: RocketLaunchIcon,
|
agents: RocketLaunchIcon,
|
||||||
|
|
@ -115,8 +122,8 @@ export function classNames(...classes) {
|
||||||
llms: LightBulbIcon,
|
llms: LightBulbIcon,
|
||||||
prompts: CommandLineIcon,
|
prompts: CommandLineIcon,
|
||||||
tools: WrenchScrewdriverIcon,
|
tools: WrenchScrewdriverIcon,
|
||||||
elements: ComputerDesktopIcon
|
elements: ComputerDesktopIcon,
|
||||||
}
|
};
|
||||||
|
|
||||||
export const bgColors = {
|
export const bgColors = {
|
||||||
white: "bg-white",
|
white: "bg-white",
|
||||||
|
|
@ -213,7 +220,7 @@ export function classNames(...classes) {
|
||||||
"!": 0.2,
|
"!": 0.2,
|
||||||
'"': 0.3,
|
'"': 0.3,
|
||||||
"#": 0.5,
|
"#": 0.5,
|
||||||
"$": 0.5,
|
$: 0.5,
|
||||||
"%": 0.5,
|
"%": 0.5,
|
||||||
"&": 0.5,
|
"&": 0.5,
|
||||||
"(": 0.2,
|
"(": 0.2,
|
||||||
|
|
@ -235,7 +242,7 @@ export function classNames(...classes) {
|
||||||
"\\": 0.5,
|
"\\": 0.5,
|
||||||
"]": 0.2,
|
"]": 0.2,
|
||||||
"^": 0.5,
|
"^": 0.5,
|
||||||
"_": 0.2,
|
_: 0.2,
|
||||||
"`": 0.5,
|
"`": 0.5,
|
||||||
"{": 0.2,
|
"{": 0.2,
|
||||||
"|": 0.2,
|
"|": 0.2,
|
||||||
|
|
@ -282,32 +289,73 @@ export function classNames(...classes) {
|
||||||
|
|
||||||
export function toCamelCase(str: string) {
|
export function toCamelCase(str: string) {
|
||||||
return str
|
return str
|
||||||
.split(' ')
|
.split(" ")
|
||||||
.map((word, index) => (index === 0 ? word.toLowerCase() : word[0].toUpperCase() + word.slice(1).toLowerCase()))
|
.map((word, index) =>
|
||||||
.join('');
|
index === 0
|
||||||
};
|
? word.toLowerCase()
|
||||||
|
: word[0].toUpperCase() + word.slice(1).toLowerCase()
|
||||||
|
)
|
||||||
|
.join("");
|
||||||
|
}
|
||||||
export function toFirstUpperCase(str: string) {
|
export function toFirstUpperCase(str: string) {
|
||||||
return str
|
return str
|
||||||
.split(' ')
|
.split(" ")
|
||||||
.map((word, index) => (word[0].toUpperCase() + word.slice(1).toLowerCase()))
|
.map((word, index) => word[0].toUpperCase() + word.slice(1).toLowerCase())
|
||||||
.join('');
|
.join("");
|
||||||
};
|
}
|
||||||
|
|
||||||
export function snakeToNormalCase(str: string) {
|
export function snakeToNormalCase(str: string) {
|
||||||
return str
|
return str
|
||||||
.split('_')
|
.split("_")
|
||||||
.map((word, index) => {if(index === 0){return word[0].toUpperCase() + word.slice(1).toLowerCase()} return word.toLowerCase()})
|
.map((word, index) => {
|
||||||
.join(' ');
|
if (index === 0) {
|
||||||
};
|
return word[0].toUpperCase() + word.slice(1).toLowerCase();
|
||||||
|
}
|
||||||
export function roundNumber(x, decimals){
|
return word.toLowerCase();
|
||||||
return Math.round(x * Math.pow(10, decimals))/Math.pow(10, decimals)
|
})
|
||||||
|
.join(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function roundNumber(x, decimals) {
|
||||||
|
return Math.round(x * Math.pow(10, decimals)) / Math.pow(10, decimals);
|
||||||
|
}
|
||||||
|
|
||||||
export function getConnectedNodes(edge: Edge, nodes: Array<Node>): Array<Node> {
|
export function getConnectedNodes(edge: Edge, nodes: Array<Node>): Array<Node> {
|
||||||
const sourceId = edge.source;
|
const sourceId = edge.source;
|
||||||
const targetId = edge.target;
|
const targetId = edge.target;
|
||||||
const connectedNodes = nodes.filter(node=>node.id===sourceId||node.id===targetId)
|
const connectedNodes = nodes.filter(
|
||||||
return connectedNodes
|
(node) => node.id === sourceId || node.id === targetId
|
||||||
|
);
|
||||||
|
return connectedNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isValidConnection(
|
||||||
|
data,
|
||||||
|
{ source, target, sourceHandle, targetHandle }
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
targetHandle === sourceHandle.split("|")[0] ||
|
||||||
|
sourceHandle.split("|")[0] === "str" ||
|
||||||
|
data.types[targetHandle] === sourceHandle.split("|")[0]
|
||||||
|
) {
|
||||||
|
let sourceNode = data.reactFlowInstance.getNode(source).data.node;
|
||||||
|
if (!sourceNode) {
|
||||||
|
if (
|
||||||
|
!data.reactFlowInstance
|
||||||
|
.getEdges()
|
||||||
|
.find((e) => e.sourceHandle === sourceHandle)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
(!sourceNode.template[sourceHandle.split("|")[1]].list &&
|
||||||
|
!data.reactFlowInstance
|
||||||
|
.getEdges()
|
||||||
|
.find((e) => e.sourceHandle === sourceHandle)) ||
|
||||||
|
sourceNode.template[sourceHandle.split("|")[1]].list
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue