Colors fixed

This commit is contained in:
Lucas Oliveira 2023-02-17 16:28:40 -03:00
commit 799f044aaf
8 changed files with 123 additions and 80 deletions

View file

@ -1,4 +1,4 @@
import { ChatBubbleBottomCenterTextIcon } from "@heroicons/react/24/outline"; import { Bars3CenterLeftIcon, ChatBubbleBottomCenterTextIcon } from "@heroicons/react/24/outline";
import Input from "../../components/inputComponent"; import Input from "../../components/inputComponent";
import { isValidConnection, nodeColors, snakeToNormalCase } from "../../utils"; import { isValidConnection, nodeColors, snakeToNormalCase } from "../../utils";
import { Handle, Position } from "reactflow"; import { Handle, Position } from "reactflow";
@ -6,7 +6,7 @@ import Tooltip from "../../components/TooltipComponent";
export default function ChatInputNode({ data }) { export default function ChatInputNode({ data }) {
return ( return (
<div className="prompt-node relative rounded-lg solid border flex justify-center align-center py-3 px-6 bg-blue-600"> <div className="prompt-node relative rounded-lg solid border flex justify-center align-center py-3 px-6 bg-gray-50" style={{color: nodeColors['chat']}}>
<Tooltip title="Prefix: str"> <Tooltip title="Prefix: str">
<Handle <Handle
type="source" type="source"
@ -25,11 +25,12 @@ export default function ChatInputNode({ data }) {
position={Position.Right} position={Position.Right}
id={'str|str|'+data.id} id={'str|str|'+data.id}
isValidConnection={(connection) => isValidConnection(data,connection)} 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-y-transparent border-y-8 border-r-0 rounded-none"
style={{borderLeftColor: nodeColors['chat']}}
></Handle> ></Handle>
</Tooltip> </Tooltip>
<div className="flex gap-3 text-lg font-medium text-white items-center"> <div className="flex gap-3 text-lg font-medium items-center" style={{color: nodeColors['chat']}}>
<ChatBubbleBottomCenterTextIcon className="h-8 w-8 mt-1" /> <Bars3CenterLeftIcon className="h-8 w-8 mt-1" />
Input Input
</div> </div>
</div> </div>

View file

@ -1,25 +1,26 @@
import { ChatBubbleBottomCenterTextIcon } from "@heroicons/react/24/outline"; import { Bars3CenterLeftIcon, 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 { isValidConnection, snakeToNormalCase } from "../../utils"; import { isValidConnection, nodeColors, snakeToNormalCase } from "../../utils";
import Tooltip from "../../components/TooltipComponent"; import Tooltip from "../../components/TooltipComponent";
export default function ChatOutputNode({ data }) { export default function ChatOutputNode({ data }) {
return ( return (
<div className="prompt-node relative rounded-lg solid border flex justify-center align-center py-3 px-6 bg-blue-600"> <div className="prompt-node relative rounded-lg solid border flex justify-center align-center py-3 px-6 bg-gray-50" style={{color: nodeColors['chat']}}>
<Tooltip title="Message: str"> <Tooltip title="Message: str">
<Handle <Handle
type="source" type="source"
isValidConnection={(connection) => isValidConnection(data,connection)} isValidConnection={(connection) => isValidConnection(data,connection)}
position={Position.Left} position={Position.Left}
id={"str|output|"+data.id} 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-y-transparent border-y-8 border-r-0 rounded-none"
style={{borderLeftColor: nodeColors['chat']}}
></Handle> ></Handle>
</Tooltip> </Tooltip>
<div className="flex gap-3 text-lg font-medium text-white items-center"> <div className="flex gap-3 text-lg font-medium items-center" style={{color: nodeColors['chat']}}>
Output Output
<ChatBubbleBottomCenterTextIcon className="h-8 w-8 mt-1" /> <Bars3CenterLeftIcon className="h-8 w-8 mt-1" />
</div> </div>
</div> </div>
); );

View file

@ -6,6 +6,8 @@ import {
snakeToNormalCase, snakeToNormalCase,
} from "../../../../utils"; } from "../../../../utils";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import Input from "../../../../components/inputComponent";
import ToggleComponent from "../../../../components/toggleComponent";
export default function ParameterComponent({ export default function ParameterComponent({
left, left,
@ -14,41 +16,69 @@ export default function ParameterComponent({
tooltipTitle, tooltipTitle,
title, title,
color, color,
type,
name = "",
}) { }) {
const ref = useRef(null); const ref = useRef(null);
const updateNodeInternals = useUpdateNodeInternals(); const updateNodeInternals = useUpdateNodeInternals();
const [position, setPosition] = useState(0); const [position, setPosition] = useState(0);
useEffect(() => { useEffect(() => {
if (ref.current && ref.current.offsetTop && ref.current.clientHeight) { if (ref.current && ref.current.offsetTop && ref.current.clientHeight) {
setPosition(ref.current.offsetTop + (ref.current.clientHeight / 2)); setPosition(ref.current.offsetTop + ref.current.clientHeight / 2);
updateNodeInternals(data.id); updateNodeInternals(data.id);
} }
}, [data.id, ref, updateNodeInternals]); }, [data.id, ref, updateNodeInternals]);
useEffect(() => { useEffect(() => {
updateNodeInternals(data.id); updateNodeInternals(data.id);
}, [data.id, position, updateNodeInternals]) }, [data.id, position, updateNodeInternals]);
const [enabled, setEnabled] = useState(data.node.template[name]?.value ?? false);
return ( return (
<div ref={ref} className="w-full bg-gray-50 mt-1 px-5 py-2"> <div ref={ref} className="w-full flex flex-wrap justify-between items-center bg-gray-50 mt-1 px-5 py-2">
<> <>
<div className="text-sm truncate">{title}</div> <div className="text-sm truncate">{title}</div>
<Tooltip title={tooltipTitle}> <Tooltip title={tooltipTitle}>
<Handle <Handle
type={left ? "source" : "target"} type={left ? "source" : "target"}
position={left ? Position.Left : Position.Right} position={left ? Position.Left : Position.Right}
id={id} id={id}
isValidConnection={(connection) => isValidConnection={(connection) =>
isValidConnection(data, connection) isValidConnection(data, connection)
} }
className={(left ? "-ml-0.5 " : "-mr-0.5 ") +"w-3 h-3 rounded-full border-2 bg-white"} className={
style={{ (left ? "-ml-0.5 " : "-mr-0.5 ") +
borderColor: color, "w-3 h-3 rounded-full border-2 bg-white"
top: position, }
style={{
borderColor: color,
top: position,
}}
></Handle>
</Tooltip>
{left === true && type === "str" ? (
<div className="mt-2 w-full">
<Input
onChange={(t) => {
data.node.template[name].value = t;
}} }}
></Handle> />
</Tooltip> </div>
</> ) : left === true && type === "bool" ? (
<div className="mt-2">
<ToggleComponent
enabled={enabled}
setEnabled={(t) => {
data.node.template[name].value = t;
setEnabled(t);
}}
/>
</div>
) : (
<></>
)}
</>
</div> </div>
); );
} }

View file

@ -1,19 +1,11 @@
import { import {
ArrowUpRightIcon,
TrashIcon, TrashIcon,
PlayIcon,
} from "@heroicons/react/24/outline"; } from "@heroicons/react/24/outline";
import { Handle, Position } from "reactflow";
import Dropdown from "../../components/dropdownComponent";
import Input from "../../components/inputComponent";
import { import {
isValidConnection,
nodeColors, nodeColors,
nodeIcons, nodeIcons,
snakeToNormalCase, snakeToNormalCase,
} from "../../utils"; } from "../../utils";
import Tooltip from "../../components/TooltipComponent";
import { useEffect, useRef, useState } from "react";
import ParameterComponent from "./components/parameterComponent"; import ParameterComponent from "./components/parameterComponent";
export default function GenericNode({ data }) { export default function GenericNode({ data }) {
@ -24,8 +16,8 @@ export default function GenericNode({ data }) {
<div className="w-full flex items-center justify-between p-4 gap-8 bg-gray-50 border-b "> <div className="w-full flex items-center justify-between p-4 gap-8 bg-gray-50 border-b ">
<div className="w-full flex items-center truncate gap-4 text-lg"> <div className="w-full flex items-center truncate gap-4 text-lg">
<Icon <Icon
className="w-10 h-10 p-1 text-white rounded" className="w-10 h-10 p-1 rounded"
style={{ background: nodeColors[data.type] }} style={{ color: nodeColors[data.type] }}
/> />
<div className="truncate">{data.name}</div> <div className="truncate">{data.name}</div>
</div> </div>
@ -34,7 +26,7 @@ export default function GenericNode({ data }) {
</button> </button>
</div> </div>
<div className="w-full h-full py-5 pointer-events-none"> <div className="w-full h-full py-5">
<div className="w-full text-gray-500 px-5 text-sm"> <div className="w-full text-gray-500 px-5 text-sm">
{data.node.description} {data.node.description}
</div> </div>
@ -61,6 +53,7 @@ export default function GenericNode({ data }) {
snakeToNormalCase(t) + snakeToNormalCase(t) +
(data.node.template[t].required ? " (required)" : "") (data.node.template[t].required ? " (required)" : "")
} }
name={t}
tooltipTitle={ tooltipTitle={
"Type: " + "Type: " +
data.node.template[t].type + data.node.template[t].type +
@ -69,6 +62,7 @@ export default function GenericNode({ data }) {
} }
id={data.node.template[t].type + "|" + t + "|" + data.id} id={data.node.template[t].type + "|" + t + "|" + data.id}
left={true} left={true}
type={data.node.template[t].type}
/> />
) : ( ) : (
<></> <></>
@ -82,6 +76,7 @@ export default function GenericNode({ data }) {
title={data.name + " | " + data.node.base_class} title={data.name + " | " + data.node.base_class}
tooltipTitle={"Type: str"} tooltipTitle={"Type: str"}
id={data.name + "|" + data.node.base_class + "|" + data.id} id={data.name + "|" + data.node.base_class + "|" + data.id}
type={'str'}
left={false} left={false}
/> />
</> </>

View file

@ -1,5 +1,6 @@
import { Transition } from "@headlessui/react"; import { Transition } from "@headlessui/react";
import { import {
Bars3CenterLeftIcon,
ChatBubbleBottomCenterTextIcon, ChatBubbleBottomCenterTextIcon,
PaperAirplaneIcon, PaperAirplaneIcon,
XMarkIcon, XMarkIcon,
@ -7,6 +8,7 @@ import {
import { useContext, useEffect, useRef, useState } from "react"; import { useContext, useEffect, useRef, useState } from "react";
import { sendAll } from "../../controllers/NodesServices"; import { sendAll } from "../../controllers/NodesServices";
import { alertContext } from "../../contexts/alertContext"; import { alertContext } from "../../contexts/alertContext";
import { nodeColors } from "../../utils";
const _ = require("lodash"); const _ = require("lodash");
@ -26,7 +28,8 @@ export default function Chat({ reactFlowInstance }) {
ref.current.scrollIntoView({behavior: 'smooth'}); ref.current.scrollIntoView({behavior: 'smooth'});
}, [chatHistory]) }, [chatHistory])
function validateNodes(){ function validateNodes(){
if(reactFlowInstance.getNodes().some((n) => (n.data.node && Object.keys(n.data.node.template).some((t: any) => (n.data.node.template[t].required && !reactFlowInstance.getEdges().some((e) => (e.sourceHandle.split('|')[1] === t && e.sourceHandle.split('|')[2] === n.id))))))){ console.log(reactFlowInstance.getNodes());
if(reactFlowInstance.getNodes().some((n) => (n.data.node && Object.keys(n.data.node.template).some((t: any) => ((n.data.node.template[t].required && n.data.node.template[t].value === "") && (n.data.node.template[t].required && !reactFlowInstance.getEdges().some((e) => (e.sourceHandle.split('|')[1] === t && e.sourceHandle.split('|')[2] === n.id)))))))){
return false; return false;
} }
return true; return true;
@ -55,7 +58,7 @@ export default function Chat({ reactFlowInstance }) {
<div className="border h-full rounded-xl rounded-b-none bg-white shadow"> <div className="border h-full rounded-xl rounded-b-none bg-white shadow">
<div className="flex justify-between items-center px-5 py-3 border-b"> <div className="flex justify-between items-center px-5 py-3 border-b">
<div className="flex gap-3 text-xl font-medium items-center"> <div className="flex gap-3 text-xl font-medium items-center">
<ChatBubbleBottomCenterTextIcon className="h-8 w-8 mt-1 text-blue-600" /> <Bars3CenterLeftIcon className="h-8 w-8 mt-1" style={{color: nodeColors['chat']}} />
Chat Chat
</div> </div>
<button <button
@ -77,7 +80,7 @@ export default function Chat({ reactFlowInstance }) {
</div> </div>
) : ( ) : (
<div className="w-full text-end"> <div className="w-full text-end">
<div className="text-start inline-block bg-blue-600 rounded-xl p-3 overflow-hidden w-fit max-w-[280px] px-5 text-sm text-white font-normal rounded-tr-none"> <div style={{color: nodeColors['chat']}} className="text-start inline-block rounded-xl p-3 overflow-hidden w-fit max-w-[280px] px-5 text-sm text-white font-normal rounded-tr-none">
{c.message} {c.message}
</div> </div>
</div> </div>
@ -154,7 +157,7 @@ export default function Chat({ reactFlowInstance }) {
}} }}
> >
<div className="flex gap-3 text-lg font-medium items-center"> <div className="flex gap-3 text-lg font-medium items-center">
<ChatBubbleBottomCenterTextIcon className="h-8 w-8 mt-1 text-blue-600" /> <Bars3CenterLeftIcon className="h-8 w-8 mt-1" style={{color: nodeColors['chat']}}/>
Chat Chat
</div> </div>
</button> </button>

View file

@ -1,10 +1,11 @@
import { Switch } from "@headlessui/react"; import { Switch } from "@headlessui/react";
import { classNames } from "../../utils"; import { classNames } from "../../utils";
import { useState } from "react";
export default function ToggleComponent({enabled, setEnabled}){ export default function ToggleComponent({enabled, setEnabled}){
return (<Switch return (<Switch
checked={enabled} checked={enabled}
onChange={setEnabled} onChange={(x) => {setEnabled(x);}}
className={classNames( className={classNames(
enabled ? 'bg-indigo-600' : 'bg-gray-200', enabled ? 'bg-indigo-600' : 'bg-gray-200',
'relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2' 'relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2'

View file

@ -14,7 +14,7 @@ export default function ExtraSidebar() {
}); });
console.log(acc); console.log(acc);
return acc; return acc;
}, {str: 'elements', bool: 'elements'}); }, {str: 'advanced', bool: 'advanced', chatOutput: 'chat', chatInput: 'chat'});
useEffect(() => { useEffect(() => {
getAll().then((d) => { getAll().then((d) => {
@ -62,36 +62,17 @@ export default function ExtraSidebar() {
</DisclosureComponent> </DisclosureComponent>
))} ))}
<DisclosureComponent <DisclosureComponent
button={{ title: nodeNames['elements'], Icon: nodeIcons['elements'] }} button={{ title: nodeNames['chat'], Icon: nodeIcons['chat'] }}
> >
<div className="p-2 flex flex-col gap-2"> <div className="p-2 flex flex-col gap-2">
<div> <div>
<div <div
draggable draggable
className={" cursor-grab border-l-8 rounded-l-md"} className={" cursor-grab border-l-8 rounded-l-md"}
style={{ borderLeftColor: nodeColors['elements'] }} style={{ borderLeftColor: nodeColors['chat'] }}
onDragStart={(event) => onDragStart={(event) =>
onDragStart(event, { onDragStart(event, {
type: 'elements', type: 'chat',
name: 'str',
types,
})
}
>
<div className="flex w-full justify-between text-sm px-4 py-3 items-center border-dashed border-gray-400 border-l-0 rounded-md rounded-l-none border-2">
<span className="text-black w-36 truncate">String</span>
<Bars2Icon className="w-6 h-6 text-gray-400" />
</div>
</div>
</div>
<div>
<div
draggable
className={" cursor-grab border-l-8 rounded-l-md"}
style={{ borderLeftColor: nodeColors['elements'] }}
onDragStart={(event) =>
onDragStart(event, {
type: 'elements',
name: 'chatInput', name: 'chatInput',
types, types,
}) })
@ -107,10 +88,10 @@ export default function ExtraSidebar() {
<div <div
draggable draggable
className={" cursor-grab border-l-8 rounded-l-md"} className={" cursor-grab border-l-8 rounded-l-md"}
style={{ borderLeftColor: nodeColors['elements'] }} style={{ borderLeftColor: nodeColors['chat'] }}
onDragStart={(event) => onDragStart={(event) =>
onDragStart(event, { onDragStart(event, {
type: 'elements', type: 'chat',
name: 'chatOutput', name: 'chatOutput',
types, types,
}) })
@ -122,14 +103,39 @@ export default function ExtraSidebar() {
</div> </div>
</div> </div>
</div> </div>
</div>
</DisclosureComponent>
<DisclosureComponent
button={{ title: nodeNames['advanced'], Icon: nodeIcons['advanced'] }}
>
<div className="p-2 flex flex-col gap-2">
<div> <div>
<div <div
draggable draggable
className={" cursor-grab border-l-8 rounded-l-md"} className={" cursor-grab border-l-8 rounded-l-md"}
style={{ borderLeftColor: nodeColors['elements'] }} style={{ borderLeftColor: nodeColors['advanced'] }}
onDragStart={(event) => onDragStart={(event) =>
onDragStart(event, { onDragStart(event, {
type: 'elements', type: 'advanced',
name: 'str',
types,
})
}
>
<div className="flex w-full justify-between text-sm px-4 py-3 items-center border-dashed border-gray-400 border-l-0 rounded-md rounded-l-none border-2">
<span className="text-black w-36 truncate">String</span>
<Bars2Icon className="w-6 h-6 text-gray-400" />
</div>
</div>
</div>
<div>
<div
draggable
className={" cursor-grab border-l-8 rounded-l-md"}
style={{ borderLeftColor: nodeColors['advanced'] }}
onDragStart={(event) =>
onDragStart(event, {
type: 'advanced',
name: 'bool', name: 'bool',
types, types,
}) })
@ -143,6 +149,7 @@ export default function ExtraSidebar() {
</div> </div>
</div> </div>
</DisclosureComponent> </DisclosureComponent>
</div> </div>
); );
} }

View file

@ -6,6 +6,7 @@ import {
CommandLineIcon, CommandLineIcon,
WrenchScrewdriverIcon, WrenchScrewdriverIcon,
ComputerDesktopIcon, ComputerDesktopIcon,
Bars3CenterLeftIcon,
} from "@heroicons/react/24/outline"; } from "@heroicons/react/24/outline";
import { Edge, Node } from "reactflow"; import { Edge, Node } from "reactflow";
@ -96,13 +97,14 @@ export const borderLColors = {
} */ } */
export const nodeColors = { export const nodeColors = {
prompts: "#7C7C7C", prompts: "#4367BF",
llms: "#35ADAE", llms: "#6344BE",
chains: "#FFDC35", chains: "#FE7500",
agents: "#903BBE", agents: "#903BBE",
tools: "#FF3434", tools: "#FF3434",
memories: "#FF9135", memories: "#FF9135",
elements: "#6344BE", advanced: "#000000",
chat: "#2563EB",
}; };
export const nodeNames = { export const nodeNames = {
@ -112,7 +114,9 @@ export const nodeNames = {
agents: "Agents", agents: "Agents",
tools: "Tools", tools: "Tools",
memories: "Memories", memories: "Memories",
elements: "Elements", advanced: "Advanced",
chat: "Chat",
}; };
export const nodeIcons = { export const nodeIcons = {
@ -122,7 +126,8 @@ export const nodeIcons = {
llms: LightBulbIcon, llms: LightBulbIcon,
prompts: CommandLineIcon, prompts: CommandLineIcon,
tools: WrenchScrewdriverIcon, tools: WrenchScrewdriverIcon,
elements: ComputerDesktopIcon, advanced: ComputerDesktopIcon,
chat: Bars3CenterLeftIcon,
}; };
export const bgColors = { export const bgColors = {