Merge branch 'refactorUtils' into generic_icon_component
This commit is contained in:
commit
17c6c7e528
50 changed files with 910 additions and 1160 deletions
|
|
@ -17,16 +17,20 @@ import { PopUpContext } from "../../../../contexts/popUpContext";
|
|||
import { TabsContext } from "../../../../contexts/tabsContext";
|
||||
import { typesContext } from "../../../../contexts/typesContext";
|
||||
import { ParameterComponentType } from "../../../../types/components";
|
||||
import { cleanEdges } from "../../../../util/reactflowUtils";
|
||||
import {
|
||||
cleanEdges,
|
||||
isValidConnection,
|
||||
} from "../../../../utils/reactflowUtils";
|
||||
import {
|
||||
nodeColors,
|
||||
nodeIconsLucide,
|
||||
nodeNames,
|
||||
} from "../../../../utils/styleUtils";
|
||||
import {
|
||||
classNames,
|
||||
getRandomKeyByssmm,
|
||||
groupByFamily,
|
||||
isValidConnection,
|
||||
nodeColors,
|
||||
nodeIconsLucide,
|
||||
nodeNames,
|
||||
} from "../../../../utils";
|
||||
} from "../../../../utils/utils";
|
||||
|
||||
export default function ParameterComponent({
|
||||
left,
|
||||
|
|
|
|||
|
|
@ -10,12 +10,8 @@ import { typesContext } from "../../contexts/typesContext";
|
|||
import NodeModal from "../../modals/NodeModal";
|
||||
import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent";
|
||||
import { NodeDataType } from "../../types/flow";
|
||||
import {
|
||||
classNames,
|
||||
nodeColors,
|
||||
nodeIconsLucide,
|
||||
toTitleCase,
|
||||
} from "../../utils";
|
||||
import { nodeColors, nodeIconsLucide } from "../../utils/styleUtils";
|
||||
import { classNames, toTitleCase } from "../../utils/utils";
|
||||
import ParameterComponent from "./components/parameterComponent";
|
||||
|
||||
export default function GenericNode({
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { FC } from "react";
|
|||
import React from "react";
|
||||
import { Tooltip as ReactTooltip } from "react-tooltip";
|
||||
import "react-tooltip/dist/react-tooltip.css";
|
||||
import { classNames } from "../../utils";
|
||||
import { classNames } from "../../utils/utils";
|
||||
|
||||
type TooltipProps = {
|
||||
selector: string;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useContext } from "react";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { FlowType } from "../../types/flow";
|
||||
import { gradients } from "../../utils";
|
||||
import { gradients } from "../../utils/styleUtils";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
import {
|
||||
Card,
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import { alertContext } from "../../../contexts/alertContext";
|
|||
import { typesContext } from "../../../contexts/typesContext";
|
||||
import { postBuildInit } from "../../../controllers/API";
|
||||
import { FlowType } from "../../../types/flow";
|
||||
import { validateNodes } from "../../../utils";
|
||||
|
||||
import { TabsContext } from "../../../contexts/tabsContext";
|
||||
import { validateNodes } from "../../../utils/reactflowUtils";
|
||||
import RadialProgressComponent from "../../RadialProgress";
|
||||
import IconComponent from "../../genericIconComponent";
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { Listbox, Transition } from "@headlessui/react";
|
|||
import { Fragment, useContext, useEffect, useState } from "react";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { DropDownComponentType } from "../../types/components";
|
||||
import { classNames } from "../../utils";
|
||||
import { classNames } from "../../utils/utils";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
|
||||
export default function Dropdown({
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { useContext, useEffect, useState } from "react";
|
|||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { InputComponentType } from "../../types/components";
|
||||
import { classNames } from "../../utils";
|
||||
import { classNames } from "../../utils/utils";
|
||||
|
||||
export default function InputComponent({
|
||||
value,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { useContext, useEffect, useState } from "react";
|
||||
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import { postValidatePrompt } from "../../controllers/API";
|
||||
import GenericModal from "../../modals/genericModal";
|
||||
import { TextAreaComponentType } from "../../types/components";
|
||||
import { TypeModal } from "../../utils";
|
||||
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import { postValidatePrompt } from "../../controllers/API";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
|
||||
export default function PromptAreaComponent({
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import { useContext, useEffect, useState } from "react";
|
||||
import { TypeModal } from "../../constants";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import GenericModal from "../../modals/genericModal";
|
||||
import { TextAreaComponentType } from "../../types/components";
|
||||
import { TypeModal } from "../../utils";
|
||||
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
|
||||
export default function TextAreaComponent({
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Switch } from "@headlessui/react";
|
||||
import { useEffect } from "react";
|
||||
import { ToggleComponentType } from "../../types/components";
|
||||
import { classNames } from "../../utils";
|
||||
import { classNames } from "../../utils/utils";
|
||||
|
||||
export default function ToggleComponent({
|
||||
enabled,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import * as AccordionPrimitive from "@radix-ui/react-accordion";
|
||||
import { ChevronDownIcon } from "@radix-ui/react-icons";
|
||||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
const Accordion = AccordionPrimitive.Root;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
const badgeVariants = cva(
|
||||
"inline-flex items-center border rounded-full px-2.5 font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Slot } from "@radix-ui/react-slot";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
const Card = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
||||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
|
||||
const Checkbox = React.forwardRef<
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
|
||||
const Dialog = DialogPrimitive.Root;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
||||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
|
||||
const DropdownMenu = DropdownMenuPrimitive.Root;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
export interface InputProps
|
||||
extends React.InputHTMLAttributes<HTMLInputElement> {}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import * as LabelPrimitive from "@radix-ui/react-label";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
const labelVariants = cva(
|
||||
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import * as MenubarPrimitive from "@radix-ui/react-menubar";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
|
||||
const MenubarMenu = MenubarPrimitive.Menu;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import * as ProgressPrimitive from "@radix-ui/react-progress";
|
||||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
const Progress = React.forwardRef<
|
||||
React.ElementRef<typeof ProgressPrimitive.Root>,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useEffect, useRef, useState } from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
export default function RenameLabel(props) {
|
||||
const [internalState, setInternalState] = useState(false);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
||||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
const Separator = React.forwardRef<
|
||||
React.ElementRef<typeof SeparatorPrimitive.Root>,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import * as SwitchPrimitives from "@radix-ui/react-switch";
|
||||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
const Switch = React.forwardRef<
|
||||
React.ElementRef<typeof SwitchPrimitives.Root>,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
const Table = React.forwardRef<
|
||||
HTMLTableElement,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
||||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
const Tabs = TabsPrimitive.Root;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
export interface TextareaProps
|
||||
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
||||
import * as React from "react";
|
||||
import { cn } from "../../utils";
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
const TooltipProvider = TooltipPrimitive.Provider;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,87 @@
|
|||
// src/constants.tsx
|
||||
|
||||
import { MessageSquare } from "lucide-react";
|
||||
import { IVarHighlightType } from "./types/components";
|
||||
import { FlowType } from "./types/flow";
|
||||
import { TabsState } from "./types/tabs";
|
||||
import { buildInputs, buildTweaks } from "./utils";
|
||||
import { buildTweaks } from "./utils/reactflowUtils";
|
||||
import { buildInputs } from "./utils/utils";
|
||||
|
||||
/**
|
||||
* constants fpr programming languages box on chat form
|
||||
* @constant
|
||||
*/
|
||||
interface languageMap {
|
||||
[key: string]: string | undefined;
|
||||
}
|
||||
/**
|
||||
* invalid characters for flow name
|
||||
* @constant
|
||||
*/
|
||||
export const INVALID_CHARACTERS = [
|
||||
" ",
|
||||
",",
|
||||
".",
|
||||
":",
|
||||
";",
|
||||
"!",
|
||||
"?",
|
||||
"/",
|
||||
"\\",
|
||||
"(",
|
||||
")",
|
||||
"[",
|
||||
"]",
|
||||
"\n",
|
||||
];
|
||||
|
||||
/**
|
||||
* regex to highlight the variables in the text
|
||||
* @constant
|
||||
*/
|
||||
|
||||
export const regexHighlight = /\{([^}]+)\}/g;
|
||||
|
||||
export const varHighlightHTML = ({ name }: IVarHighlightType) => {
|
||||
const html = `<span class="font-semibold chat-message-highlight">{${name}}</span>`;
|
||||
return html;
|
||||
};
|
||||
|
||||
export const programmingLanguages: languageMap = {
|
||||
javascript: ".js",
|
||||
python: ".py",
|
||||
java: ".java",
|
||||
c: ".c",
|
||||
cpp: ".cpp",
|
||||
"c++": ".cpp",
|
||||
"c#": ".cs",
|
||||
ruby: ".rb",
|
||||
php: ".php",
|
||||
swift: ".swift",
|
||||
"objective-c": ".m",
|
||||
kotlin: ".kt",
|
||||
typescript: ".ts",
|
||||
go: ".go",
|
||||
perl: ".pl",
|
||||
rust: ".rs",
|
||||
scala: ".scala",
|
||||
haskell: ".hs",
|
||||
lua: ".lua",
|
||||
shell: ".sh",
|
||||
sql: ".sql",
|
||||
html: ".html",
|
||||
css: ".css",
|
||||
// add more file extensions here, make sure the key is same as language prop in CodeBlock.tsx component
|
||||
};
|
||||
|
||||
/**
|
||||
* enum for the different types of nodes
|
||||
* @enum
|
||||
*/
|
||||
export enum TypeModal {
|
||||
TEXT = 1,
|
||||
PROMPT = 2,
|
||||
}
|
||||
/**
|
||||
* Number maximum of components to scroll on tooltips
|
||||
* @constant
|
||||
|
|
@ -17,6 +94,12 @@ export const MAX_LENGTH_TO_SCROLL_TOOLTIP = 200;
|
|||
*/
|
||||
export const MAX_WORDS_HIGHLIGHT = 79;
|
||||
|
||||
/**
|
||||
* Limit of items before show scroll on fields modal
|
||||
* @constant
|
||||
*/
|
||||
export const limitScrollFieldsModal = 10;
|
||||
|
||||
/**
|
||||
* The base text for subtitle of Export Dialog (Toolbar)
|
||||
* @constant
|
||||
|
|
@ -20,12 +20,8 @@ import {
|
|||
import { APIClassType, APITemplateType } from "../types/api";
|
||||
import { FlowType, NodeType } from "../types/flow";
|
||||
import { TabsContextType, TabsState } from "../types/tabs";
|
||||
import {
|
||||
getRandomDescription,
|
||||
getRandomName,
|
||||
updateIds,
|
||||
updateTemplate,
|
||||
} from "../utils";
|
||||
import { updateIds, updateTemplate } from "../utils/reactflowUtils";
|
||||
import { getRandomDescription, getRandomName } from "../utils/utils";
|
||||
import { alertContext } from "./alertContext";
|
||||
import { typesContext } from "./typesContext";
|
||||
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ import { darkContext } from "../../contexts/darkContext";
|
|||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { FlowType } from "../../types/flow/index";
|
||||
import { buildTweaks, classNames } from "../../utils";
|
||||
|
||||
import { buildTweaks } from "../../utils/reactflowUtils";
|
||||
import { classNames } from "../../utils/utils";
|
||||
export default function ApiModal({ flow }: { flow: FlowType }) {
|
||||
const [open, setOpen] = useState(true);
|
||||
const { dark } = useContext(darkContext);
|
||||
|
|
|
|||
|
|
@ -29,11 +29,12 @@ import {
|
|||
TableHeader,
|
||||
TableRow,
|
||||
} from "../../components/ui/table";
|
||||
import { limitScrollFieldsModal } from "../../constants";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import { NodeDataType } from "../../types/flow";
|
||||
import { classNames, limitScrollFieldsModal } from "../../utils";
|
||||
import { classNames } from "../../utils/utils";
|
||||
|
||||
export default function EditNodeModal({ data }: { data: NodeDataType }) {
|
||||
const [open, setOpen] = useState(true);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import IntComponent from "../../../../components/intComponent";
|
|||
import PromptAreaComponent from "../../../../components/promptComponent";
|
||||
import TextAreaComponent from "../../../../components/textAreaComponent";
|
||||
import ToggleComponent from "../../../../components/toggleComponent";
|
||||
import { classNames } from "../../../../utils";
|
||||
import { classNames } from "../../../../utils/utils";
|
||||
|
||||
export default function ModalField({
|
||||
data,
|
||||
|
|
|
|||
|
|
@ -1,16 +1,12 @@
|
|||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { Fragment, useContext, useRef, useState } from "react";
|
||||
import IconComponent from "../../components/genericIconComponent";
|
||||
import { limitScrollFieldsModal } from "../../constants";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import { NodeDataType } from "../../types/flow";
|
||||
import {
|
||||
classNames,
|
||||
limitScrollFieldsModal,
|
||||
nodeColors,
|
||||
nodeIconsLucide,
|
||||
toTitleCase,
|
||||
} from "../../utils";
|
||||
import { nodeColors, nodeIconsLucide } from "../../utils/styleUtils";
|
||||
import { classNames, toTitleCase } from "../../utils/utils";
|
||||
import ModalField from "./components/ModalField";
|
||||
|
||||
export default function NodeModal({ data }: { data: NodeDataType }) {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import { EXPORT_DIALOG_SUBTITLE } from "../../constants";
|
|||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { removeApiKeys } from "../../utils";
|
||||
import { removeApiKeys } from "../../utils/reactflowUtils";
|
||||
|
||||
export default function ExportModal() {
|
||||
const [open, setOpen] = useState(true);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useEffect } from "react";
|
||||
import IconComponent from "../../../components/genericIconComponent";
|
||||
import { classNames } from "../../../utils";
|
||||
import { classNames } from "../../../utils/utils";
|
||||
|
||||
export default function ChatInput({
|
||||
lockChat,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { IconCheck, IconClipboard, IconDownload } from "@tabler/icons-react";
|
|||
import { useState } from "react";
|
||||
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||
import { oneDark } from "react-syntax-highlighter/dist/cjs/styles/prism";
|
||||
import { programmingLanguages } from "../../../../utils";
|
||||
import { programmingLanguages } from "../../../../constants";
|
||||
|
||||
interface Props {
|
||||
language: string;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import SanitizedHTMLWrapper from "../../../components/SanitizedHTMLWrapper";
|
|||
import IconComponent from "../../../components/genericIconComponent";
|
||||
import { THOUGHTS_ICON } from "../../../constants";
|
||||
import { ChatMessageType } from "../../../types/chat";
|
||||
import { classNames } from "../../../utils";
|
||||
import { classNames } from "../../../utils/utils";
|
||||
import FileCard from "../fileComponent";
|
||||
import { CodeBlock } from "./codeBlock";
|
||||
export default function ChatMessage({
|
||||
|
|
@ -81,7 +81,7 @@ export default function ChatMessage({
|
|||
remarkPlugins={[remarkGfm, remarkMath]}
|
||||
rehypePlugins={[rehypeMathjax]}
|
||||
className="markdown prose inline-block break-words text-primary
|
||||
dark:prose-invert sm:max-w-[30vw] lg:max-w-[40vw] sm:w-[30vw] lg:w-[40vw]"
|
||||
dark:prose-invert sm:w-[30vw] sm:max-w-[30vw] lg:w-[40vw] lg:max-w-[40vw]"
|
||||
components={{
|
||||
code: ({
|
||||
node,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { typesContext } from "../../contexts/typesContext";
|
|||
import { sendAllProps } from "../../types/api";
|
||||
import { ChatMessageType } from "../../types/chat";
|
||||
import { FlowType } from "../../types/flow";
|
||||
import { classNames, validateNodes } from "../../utils";
|
||||
import { classNames } from "../../utils/utils";
|
||||
import ChatInput from "./chatInput";
|
||||
import ChatMessage from "./chatMessage";
|
||||
|
||||
|
|
@ -29,6 +29,7 @@ import {
|
|||
import { Textarea } from "../../components/ui/textarea";
|
||||
import { CHAT_FORM_DIALOG_SUBTITLE, THOUGHTS_ICON } from "../../constants";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { validateNodes } from "../../utils/reactflowUtils";
|
||||
|
||||
export default function FormModal({
|
||||
flow,
|
||||
|
|
|
|||
|
|
@ -6,20 +6,21 @@ import { Badge } from "../../components/ui/badge";
|
|||
import { Button } from "../../components/ui/button";
|
||||
import { DialogTitle } from "../../components/ui/dialog";
|
||||
import { Textarea } from "../../components/ui/textarea";
|
||||
import { MAX_WORDS_HIGHLIGHT, PROMPT_DIALOG_SUBTITLE, TEXT_DIALOG_SUBTITLE } from "../../constants";
|
||||
import {
|
||||
INVALID_CHARACTERS,
|
||||
MAX_WORDS_HIGHLIGHT,
|
||||
PROMPT_DIALOG_SUBTITLE,
|
||||
TEXT_DIALOG_SUBTITLE,
|
||||
TypeModal,
|
||||
regexHighlight,
|
||||
varHighlightHTML,
|
||||
} from "../../constants";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { darkContext } from "../../contexts/darkContext";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { postValidatePrompt } from "../../controllers/API";
|
||||
import { APIClassType } from "../../types/api";
|
||||
import {
|
||||
INVALID_CHARACTERS,
|
||||
TypeModal,
|
||||
classNames,
|
||||
getRandomKeyByssmm,
|
||||
regexHighlight,
|
||||
varHighlightHTML,
|
||||
} from "../../utils";
|
||||
import { classNames, getRandomKeyByssmm } from "../../utils/utils";
|
||||
import BaseModal from "../baseModal";
|
||||
|
||||
export default function GenericModal({
|
||||
|
|
@ -120,15 +121,16 @@ export default function GenericModal({
|
|||
);
|
||||
};
|
||||
|
||||
function getClassByNumberLength(){
|
||||
function getClassByNumberLength() {
|
||||
let sumOfCaracteres: number = 0;
|
||||
wordsHighlight.forEach(element => {
|
||||
sumOfCaracteres = sumOfCaracteres + element.replace(/[{}]/g, "").length
|
||||
wordsHighlight.forEach((element) => {
|
||||
sumOfCaracteres = sumOfCaracteres + element.replace(/[{}]/g, "").length;
|
||||
});
|
||||
return sumOfCaracteres > MAX_WORDS_HIGHLIGHT ? "code-highlight" : "code-nohighlight"
|
||||
return sumOfCaracteres > MAX_WORDS_HIGHLIGHT
|
||||
? "code-highlight"
|
||||
: "code-nohighlight";
|
||||
}
|
||||
|
||||
|
||||
function validatePrompt(closeModal: boolean) {
|
||||
postValidatePrompt(field_name, inputValue, nodeClass)
|
||||
.then((apiReturn) => {
|
||||
|
|
@ -234,7 +236,10 @@ export default function GenericModal({
|
|||
<div className="mb-auto flex-1">
|
||||
{type === TypeModal.PROMPT && (
|
||||
<div className=" mr-2">
|
||||
<div ref={divRef} className="max-h-20 overflow-y-auto custom-scroll">
|
||||
<div
|
||||
ref={divRef}
|
||||
className="max-h-20 overflow-y-auto custom-scroll"
|
||||
>
|
||||
<div className="flex flex-wrap items-center">
|
||||
<IconComponent
|
||||
name="Variable"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { ReactNode } from "react";
|
||||
import { classNames } from "../../../utils";
|
||||
import { classNames } from "../../../utils/utils";
|
||||
|
||||
export default function ButtonBox({
|
||||
onClick,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import { PopUpContext } from "../../contexts/popUpContext";
|
|||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { getExamples } from "../../controllers/API";
|
||||
import { FlowType } from "../../types/flow";
|
||||
import { classNames } from "../../utils";
|
||||
import { classNames } from "../../utils/utils";
|
||||
import ButtonBox from "./buttonBox";
|
||||
|
||||
export default function ImportModal() {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import { typesContext } from "../../../../contexts/typesContext";
|
|||
import { undoRedoContext } from "../../../../contexts/undoRedoContext";
|
||||
import { APIClassType } from "../../../../types/api";
|
||||
import { FlowType, NodeType } from "../../../../types/flow";
|
||||
import { isValidConnection } from "../../../../utils";
|
||||
import { isValidConnection } from "../../../../utils/reactflowUtils";
|
||||
import ConnectionLineComponent from "../ConnectionLineComponent";
|
||||
import ExtraSidebar from "../extraSidebarComponent";
|
||||
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ import ApiModal from "../../../../modals/ApiModal";
|
|||
import ExportModal from "../../../../modals/exportModal";
|
||||
import { APIClassType, APIObjectType } from "../../../../types/api";
|
||||
import {
|
||||
classNames,
|
||||
nodeColors,
|
||||
nodeIconsLucide,
|
||||
nodeNames,
|
||||
} from "../../../../utils";
|
||||
} from "../../../../utils/styleUtils";
|
||||
import { classNames } from "../../../../utils/utils";
|
||||
import DisclosureComponent from "../DisclosureComponent";
|
||||
|
||||
export default function ExtraSidebar() {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import ShadTooltip from "../../../../components/ShadTooltipComponent";
|
|||
import IconComponent from "../../../../components/genericIconComponent";
|
||||
import { TabsContext } from "../../../../contexts/tabsContext";
|
||||
import EditNodeModal from "../../../../modals/EditNodeModal";
|
||||
import { classNames } from "../../../../utils";
|
||||
import { classNames } from "../../../../utils/utils";
|
||||
|
||||
const NodeToolbarComponent = (props) => {
|
||||
const [nodeLength, setNodeLength] = useState(
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
import _ from "lodash";
|
||||
import { cleanEdgesType } from "./../types/utils/reactflowUtils";
|
||||
|
||||
export function cleanEdges({
|
||||
flow: { edges, nodes },
|
||||
updateEdge,
|
||||
}: cleanEdgesType) {
|
||||
let newEdges = _.cloneDeep(edges);
|
||||
edges.forEach((edge) => {
|
||||
// check if the source and target node still exists
|
||||
const sourceNode = nodes.find((node) => node.id === edge.source);
|
||||
const targetNode = nodes.find((node) => node.id === edge.target);
|
||||
if (!sourceNode || !targetNode) {
|
||||
newEdges = newEdges.filter((e) => e.id !== edge.id);
|
||||
}
|
||||
// check if the source and target handle still exists
|
||||
if (sourceNode && targetNode) {
|
||||
const sourceHandle = edge.sourceHandle; //right
|
||||
const targetHandle = edge.targetHandle; //left
|
||||
if (targetHandle) {
|
||||
const field = targetHandle.split("|")[1];
|
||||
const id =
|
||||
(targetNode.data.node.template[field]?.input_types?.join(";") ??
|
||||
targetNode.data.node.template[field]?.type) +
|
||||
"|" +
|
||||
field +
|
||||
"|" +
|
||||
targetNode.data.id;
|
||||
if (id !== targetHandle) {
|
||||
newEdges = newEdges.filter((e) => e.id !== edge.id);
|
||||
}
|
||||
}
|
||||
if (sourceHandle) {
|
||||
const id = [
|
||||
sourceNode.data.type,
|
||||
sourceNode.data.id,
|
||||
...sourceNode.data.node.base_classes,
|
||||
].join("|");
|
||||
if (id !== sourceHandle) {
|
||||
newEdges = newEdges.filter((e) => e.id !== edge.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
updateEdge(newEdges);
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
221
src/frontend/src/utils/reactflowUtils.ts
Normal file
221
src/frontend/src/utils/reactflowUtils.ts
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
import _ from "lodash";
|
||||
import { Connection, ReactFlowInstance } from "reactflow";
|
||||
import { APITemplateType } from "../types/api";
|
||||
import { FlowType, NodeType } from "../types/flow";
|
||||
import { cleanEdgesType } from "../types/utils/reactflowUtils";
|
||||
import { toNormalCase } from "./utils";
|
||||
|
||||
export function cleanEdges({
|
||||
flow: { edges, nodes },
|
||||
updateEdge,
|
||||
}: cleanEdgesType) {
|
||||
let newEdges = _.cloneDeep(edges);
|
||||
edges.forEach((edge) => {
|
||||
// check if the source and target node still exists
|
||||
const sourceNode = nodes.find((node) => node.id === edge.source);
|
||||
const targetNode = nodes.find((node) => node.id === edge.target);
|
||||
if (!sourceNode || !targetNode) {
|
||||
newEdges = newEdges.filter((e) => e.id !== edge.id);
|
||||
}
|
||||
// check if the source and target handle still exists
|
||||
if (sourceNode && targetNode) {
|
||||
const sourceHandle = edge.sourceHandle; //right
|
||||
const targetHandle = edge.targetHandle; //left
|
||||
if (targetHandle) {
|
||||
const field = targetHandle.split("|")[1];
|
||||
const id =
|
||||
(targetNode.data.node.template[field]?.input_types?.join(";") ??
|
||||
targetNode.data.node.template[field]?.type) +
|
||||
"|" +
|
||||
field +
|
||||
"|" +
|
||||
targetNode.data.id;
|
||||
if (id !== targetHandle) {
|
||||
newEdges = newEdges.filter((e) => e.id !== edge.id);
|
||||
}
|
||||
}
|
||||
if (sourceHandle) {
|
||||
const id = [
|
||||
sourceNode.data.type,
|
||||
sourceNode.data.id,
|
||||
...sourceNode.data.node.base_classes,
|
||||
].join("|");
|
||||
if (id !== sourceHandle) {
|
||||
newEdges = newEdges.filter((e) => e.id !== edge.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
updateEdge(newEdges);
|
||||
}
|
||||
|
||||
export function isValidConnection(
|
||||
{ source, target, sourceHandle, targetHandle }: Connection,
|
||||
reactFlowInstance: ReactFlowInstance
|
||||
) {
|
||||
if (
|
||||
targetHandle
|
||||
.split("|")[0]
|
||||
.split(";")
|
||||
.some((n) => n === sourceHandle.split("|")[0]) ||
|
||||
sourceHandle
|
||||
.split("|")
|
||||
.slice(2)
|
||||
.some((t) =>
|
||||
targetHandle
|
||||
.split("|")[0]
|
||||
.split(";")
|
||||
.some((n) => n === t)
|
||||
) ||
|
||||
targetHandle.split("|")[0] === "str"
|
||||
) {
|
||||
let targetNode = reactFlowInstance?.getNode(target)?.data?.node;
|
||||
if (!targetNode) {
|
||||
if (
|
||||
!reactFlowInstance
|
||||
.getEdges()
|
||||
.find((e) => e.targetHandle === targetHandle)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
} else if (
|
||||
(!targetNode.template[targetHandle.split("|")[1]].list &&
|
||||
!reactFlowInstance
|
||||
.getEdges()
|
||||
.find((e) => e.targetHandle === targetHandle)) ||
|
||||
targetNode.template[targetHandle.split("|")[1]].list
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function removeApiKeys(flow: FlowType): FlowType {
|
||||
let cleanFLow = _.cloneDeep(flow);
|
||||
cleanFLow.data.nodes.forEach((node) => {
|
||||
for (const key in node.data.node.template) {
|
||||
if (node.data.node.template[key].password) {
|
||||
node.data.node.template[key].value = "";
|
||||
}
|
||||
}
|
||||
});
|
||||
return cleanFLow;
|
||||
}
|
||||
|
||||
export function updateTemplate(
|
||||
reference: APITemplateType,
|
||||
objectToUpdate: APITemplateType
|
||||
): APITemplateType {
|
||||
let clonedObject: APITemplateType = _.cloneDeep(reference);
|
||||
|
||||
// Loop through each key in the reference object
|
||||
for (const key in clonedObject) {
|
||||
// If the key is not in the object to update, add it
|
||||
if (objectToUpdate[key] && objectToUpdate[key].value) {
|
||||
clonedObject[key].value = objectToUpdate[key].value;
|
||||
}
|
||||
if (
|
||||
objectToUpdate[key] &&
|
||||
objectToUpdate[key].advanced !== null &&
|
||||
objectToUpdate[key].advanced !== undefined
|
||||
) {
|
||||
clonedObject[key].advanced = objectToUpdate[key].advanced;
|
||||
}
|
||||
}
|
||||
return clonedObject;
|
||||
}
|
||||
|
||||
export function updateIds(newFlow, getNodeId) {
|
||||
let idsMap = {};
|
||||
|
||||
newFlow.nodes.forEach((n: NodeType) => {
|
||||
// Generate a unique node ID
|
||||
let newId = getNodeId(n.data.type);
|
||||
idsMap[n.id] = newId;
|
||||
n.id = newId;
|
||||
n.data.id = newId;
|
||||
// Add the new node to the list of nodes in state
|
||||
});
|
||||
|
||||
newFlow.edges.forEach((e) => {
|
||||
e.source = idsMap[e.source];
|
||||
e.target = idsMap[e.target];
|
||||
let sourceHandleSplitted = e.sourceHandle.split("|");
|
||||
e.sourceHandle =
|
||||
sourceHandleSplitted[0] +
|
||||
"|" +
|
||||
e.source +
|
||||
"|" +
|
||||
sourceHandleSplitted.slice(2).join("|");
|
||||
let targetHandleSplitted = e.targetHandle.split("|");
|
||||
e.targetHandle =
|
||||
targetHandleSplitted.slice(0, -1).join("|") + "|" + e.target;
|
||||
e.id =
|
||||
"reactflow__edge-" +
|
||||
e.source +
|
||||
e.sourceHandle +
|
||||
"-" +
|
||||
e.target +
|
||||
e.targetHandle;
|
||||
});
|
||||
}
|
||||
|
||||
export function buildTweaks(flow) {
|
||||
return flow.data.nodes.reduce((acc, node) => {
|
||||
acc[node.data.id] = {};
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
export function validateNode(
|
||||
n: NodeType,
|
||||
reactFlowInstance: ReactFlowInstance
|
||||
): Array<string> {
|
||||
if (!n.data?.node?.template || !Object.keys(n.data.node.template)) {
|
||||
return [
|
||||
"We've noticed a potential issue with a node in the flow. Please review it and, if necessary, submit a bug report with your exported flow file. Thank you for your help!",
|
||||
];
|
||||
}
|
||||
|
||||
const {
|
||||
type,
|
||||
node: { template },
|
||||
} = n.data;
|
||||
|
||||
return Object.keys(template).reduce(
|
||||
(errors: Array<string>, t) =>
|
||||
errors.concat(
|
||||
template[t].required &&
|
||||
template[t].show &&
|
||||
(template[t].value === undefined ||
|
||||
template[t].value === null ||
|
||||
template[t].value === "") &&
|
||||
!reactFlowInstance
|
||||
.getEdges()
|
||||
.some(
|
||||
(e) =>
|
||||
e.targetHandle.split("|")[1] === t &&
|
||||
e.targetHandle.split("|")[2] === n.id
|
||||
)
|
||||
? [
|
||||
`${type} is missing ${
|
||||
template.display_name || toNormalCase(template[t].name)
|
||||
}.`,
|
||||
]
|
||||
: []
|
||||
),
|
||||
[] as string[]
|
||||
);
|
||||
}
|
||||
|
||||
export function validateNodes(reactFlowInstance: ReactFlowInstance) {
|
||||
if (reactFlowInstance.getNodes().length === 0) {
|
||||
return [
|
||||
"No nodes found in the flow. Please add at least one node to the flow.",
|
||||
];
|
||||
}
|
||||
return reactFlowInstance
|
||||
.getNodes()
|
||||
.flatMap((n: NodeType) => validateNode(n, reactFlowInstance));
|
||||
}
|
||||
268
src/frontend/src/utils/styleUtils.ts
Normal file
268
src/frontend/src/utils/styleUtils.ts
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
import {
|
||||
Bell,
|
||||
Check,
|
||||
CheckCircle2,
|
||||
ChevronDown,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
ChevronsUpDown,
|
||||
Circle,
|
||||
Clipboard,
|
||||
Code2,
|
||||
Compass,
|
||||
Copy,
|
||||
Cpu,
|
||||
Download,
|
||||
DownloadCloud,
|
||||
Eraser,
|
||||
ExternalLink,
|
||||
File,
|
||||
FileDown,
|
||||
FileSearch,
|
||||
FileSearch2,
|
||||
FileText,
|
||||
FileUp,
|
||||
Fingerprint,
|
||||
Gift,
|
||||
GitFork,
|
||||
GithubIcon,
|
||||
Hammer,
|
||||
HelpCircle,
|
||||
Home,
|
||||
Info,
|
||||
Laptop2,
|
||||
Layers,
|
||||
Lightbulb,
|
||||
Link,
|
||||
Lock,
|
||||
LucideSend,
|
||||
Menu,
|
||||
MessageCircle,
|
||||
MessagesSquare,
|
||||
MoonIcon,
|
||||
Paperclip,
|
||||
Plus,
|
||||
Redo,
|
||||
Rocket,
|
||||
Save,
|
||||
Scissors,
|
||||
Search,
|
||||
Settings2,
|
||||
SlackIcon,
|
||||
Sparkles,
|
||||
SunIcon,
|
||||
TerminalSquare,
|
||||
Trash2,
|
||||
Undo,
|
||||
Upload,
|
||||
Users2,
|
||||
Variable,
|
||||
Wand2,
|
||||
Wrench,
|
||||
X,
|
||||
XCircle,
|
||||
Zap,
|
||||
} from "lucide-react";
|
||||
import { Edge, Node } from "reactflow";
|
||||
import { AirbyteIcon } from "../icons/Airbyte";
|
||||
import { AnthropicIcon } from "../icons/Anthropic";
|
||||
import { BingIcon } from "../icons/Bing";
|
||||
import { ChromaIcon } from "../icons/ChromaIcon";
|
||||
import { CohereIcon } from "../icons/Cohere";
|
||||
import { EvernoteIcon } from "../icons/Evernote";
|
||||
import { FBIcon } from "../icons/FacebookMessenger";
|
||||
import { GitBookIcon } from "../icons/GitBook";
|
||||
import { GoogleIcon } from "../icons/Google";
|
||||
import { HuggingFaceIcon } from "../icons/HuggingFace";
|
||||
import { IFixIcon } from "../icons/IFixIt";
|
||||
import { MetaIcon } from "../icons/Meta";
|
||||
import { MidjourneyIcon } from "../icons/Midjorney";
|
||||
import { MongoDBIcon } from "../icons/MongoDB";
|
||||
import { NotionIcon } from "../icons/Notion";
|
||||
import { OpenAiIcon } from "../icons/OpenAi";
|
||||
import { PineconeIcon } from "../icons/Pinecone";
|
||||
import { QDrantIcon } from "../icons/QDrant";
|
||||
import { SearxIcon } from "../icons/Searx";
|
||||
import { VertexAIIcon } from "../icons/VertexAI";
|
||||
import { HackerNewsIcon } from "../icons/hackerNews";
|
||||
import { SupabaseIcon } from "../icons/supabase";
|
||||
|
||||
export const gradients = [
|
||||
"bg-gradient-to-br from-gray-800 via-rose-700 to-violet-900",
|
||||
"bg-gradient-to-br from-green-200 via-green-300 to-blue-500",
|
||||
"bg-gradient-to-br from-yellow-200 via-yellow-400 to-yellow-700",
|
||||
"bg-gradient-to-br from-green-200 via-green-400 to-purple-700",
|
||||
"bg-gradient-to-br from-blue-100 via-blue-300 to-blue-500",
|
||||
"bg-gradient-to-br from-purple-400 to-yellow-400",
|
||||
"bg-gradient-to-br from-red-800 via-yellow-600 to-yellow-500",
|
||||
"bg-gradient-to-br from-blue-300 via-green-200 to-yellow-300",
|
||||
"bg-gradient-to-br from-blue-700 via-blue-800 to-gray-900",
|
||||
"bg-gradient-to-br from-green-300 to-purple-400",
|
||||
"bg-gradient-to-br from-yellow-200 via-pink-200 to-pink-400",
|
||||
"bg-gradient-to-br from-green-500 to-green-700",
|
||||
"bg-gradient-to-br from-rose-400 via-fuchsia-500 to-indigo-500",
|
||||
"bg-gradient-to-br from-sky-400 to-blue-500",
|
||||
"bg-gradient-to-br from-green-200 via-green-400 to-green-500",
|
||||
"bg-gradient-to-br from-red-400 via-gray-300 to-blue-500",
|
||||
"bg-gradient-to-br from-gray-900 to-gray-600 bg-gradient-to-r",
|
||||
"bg-gradient-to-br from-rose-500 via-red-400 to-red-500",
|
||||
"bg-gradient-to-br from-fuchsia-600 to-pink-600",
|
||||
"bg-gradient-to-br from-emerald-500 to-lime-600",
|
||||
"bg-gradient-to-br from-rose-500 to-indigo-700",
|
||||
"bg-gradient-to-br bg-gradient-to-tr from-violet-500 to-orange-300",
|
||||
"bg-gradient-to-br from-gray-900 via-purple-900 to-violet-600",
|
||||
"bg-gradient-to-br from-yellow-200 via-red-500 to-fuchsia-500",
|
||||
"bg-gradient-to-br from-sky-400 to-indigo-900",
|
||||
"bg-gradient-to-br from-amber-200 via-violet-600 to-sky-900",
|
||||
"bg-gradient-to-br from-amber-700 via-orange-300 to-rose-800",
|
||||
"bg-gradient-to-br from-gray-300 via-fuchsia-600 to-orange-600",
|
||||
"bg-gradient-to-br from-fuchsia-500 via-red-600 to-orange-400",
|
||||
"bg-gradient-to-br from-sky-400 via-rose-400 to-lime-400",
|
||||
"bg-gradient-to-br from-lime-600 via-yellow-300 to-red-600",
|
||||
];
|
||||
|
||||
export const nodeColors: { [char: string]: string } = {
|
||||
prompts: "#4367BF",
|
||||
llms: "#6344BE",
|
||||
chains: "#FE7500",
|
||||
agents: "#903BBE",
|
||||
tools: "#FF3434",
|
||||
memories: "#F5B85A",
|
||||
advanced: "#000000",
|
||||
chat: "#198BF6",
|
||||
thought: "#272541",
|
||||
embeddings: "#42BAA7",
|
||||
documentloaders: "#7AAE42",
|
||||
vectorstores: "#AA8742",
|
||||
textsplitters: "#B47CB5",
|
||||
toolkits: "#DB2C2C",
|
||||
wrappers: "#E6277A",
|
||||
utilities: "#31A3CC",
|
||||
output_parsers: "#E6A627",
|
||||
str: "#049524",
|
||||
retrievers: "#e6b25a",
|
||||
unknown: "#9CA3AF",
|
||||
};
|
||||
|
||||
export const nodeNames: { [char: string]: string } = {
|
||||
prompts: "Prompts",
|
||||
llms: "LLMs",
|
||||
chains: "Chains",
|
||||
agents: "Agents",
|
||||
tools: "Tools",
|
||||
memories: "Memories",
|
||||
advanced: "Advanced",
|
||||
chat: "Chat",
|
||||
embeddings: "Embeddings",
|
||||
documentloaders: "Loaders",
|
||||
vectorstores: "Vector Stores",
|
||||
toolkits: "Toolkits",
|
||||
wrappers: "Wrappers",
|
||||
textsplitters: "Text Splitters",
|
||||
retrievers: "Retrievers",
|
||||
utilities: "Utilities",
|
||||
output_parsers: "Output Parsers",
|
||||
unknown: "Unknown",
|
||||
};
|
||||
|
||||
export const nodeIconsLucide = {
|
||||
Chroma: ChromaIcon,
|
||||
AirbyteJSONLoader: AirbyteIcon,
|
||||
Anthropic: AnthropicIcon,
|
||||
ChatAnthropic: AnthropicIcon,
|
||||
BingSearchAPIWrapper: BingIcon,
|
||||
BingSearchRun: BingIcon,
|
||||
Cohere: CohereIcon,
|
||||
CohereEmbeddings: CohereIcon,
|
||||
EverNoteLoader: EvernoteIcon,
|
||||
FacebookChatLoader: FBIcon,
|
||||
GitbookLoader: GitBookIcon,
|
||||
GoogleSearchAPIWrapper: GoogleIcon,
|
||||
GoogleSearchResults: GoogleIcon,
|
||||
GoogleSearchRun: GoogleIcon,
|
||||
HNLoader: HackerNewsIcon,
|
||||
HuggingFaceHub: HuggingFaceIcon,
|
||||
HuggingFaceEmbeddings: HuggingFaceIcon,
|
||||
IFixitLoader: IFixIcon,
|
||||
Meta: MetaIcon,
|
||||
Midjorney: MidjourneyIcon,
|
||||
MongoDBAtlasVectorSearch: MongoDBIcon,
|
||||
NotionDirectoryLoader: NotionIcon,
|
||||
ChatOpenAI: OpenAiIcon,
|
||||
OpenAI: OpenAiIcon,
|
||||
OpenAIEmbeddings: OpenAiIcon,
|
||||
Pinecone: PineconeIcon,
|
||||
Qdrant: QDrantIcon,
|
||||
Searx: SearxIcon,
|
||||
SlackDirectoryLoader: SlackIcon,
|
||||
SupabaseVectorStore: SupabaseIcon,
|
||||
VertexAI: VertexAIIcon,
|
||||
ChatVertexAI: VertexAIIcon,
|
||||
agents: Rocket,
|
||||
chains: Link,
|
||||
memories: Cpu,
|
||||
llms: Lightbulb,
|
||||
prompts: TerminalSquare,
|
||||
tools: Wrench,
|
||||
advanced: Laptop2,
|
||||
chat: MessageCircle,
|
||||
embeddings: Fingerprint,
|
||||
documentloaders: Paperclip,
|
||||
vectorstores: Layers,
|
||||
toolkits: Hammer,
|
||||
textsplitters: Scissors,
|
||||
wrappers: Gift,
|
||||
utilities: Wand2,
|
||||
output_parsers: Compass,
|
||||
retrievers: FileSearch,
|
||||
unknown: HelpCircle,
|
||||
Trash2,
|
||||
X,
|
||||
XCircle,
|
||||
Info,
|
||||
CheckCircle2,
|
||||
Zap,
|
||||
MessagesSquare,
|
||||
ExternalLink,
|
||||
ChevronsUpDown,
|
||||
Check,
|
||||
Home,
|
||||
Users2,
|
||||
SunIcon,
|
||||
MoonIcon,
|
||||
Bell,
|
||||
ChevronLeft,
|
||||
ChevronDown,
|
||||
Plus,
|
||||
Redo,
|
||||
Settings2,
|
||||
Undo,
|
||||
FileSearch2,
|
||||
ChevronRight,
|
||||
Circle,
|
||||
Clipboard,
|
||||
Code2,
|
||||
Variable,
|
||||
Download,
|
||||
Eraser,
|
||||
Lock,
|
||||
LucideSend,
|
||||
Sparkles,
|
||||
DownloadCloud,
|
||||
File,
|
||||
FileText,
|
||||
GitFork,
|
||||
GithubIcon,
|
||||
FileDown,
|
||||
FileUp,
|
||||
Menu,
|
||||
Save,
|
||||
Search,
|
||||
Copy,
|
||||
Upload,
|
||||
};
|
||||
export function getConnectedNodes(edge: Edge, nodes: Array<Node>): Array<Node> {
|
||||
const sourceId = edge.source;
|
||||
const targetId = edge.target;
|
||||
return nodes.filter((node) => node.id === targetId || node.id === sourceId);
|
||||
}
|
||||
253
src/frontend/src/utils/utils.ts
Normal file
253
src/frontend/src/utils/utils.ts
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
import clsx, { ClassValue } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { ADJECTIVES, DESCRIPTIONS, NOUNS } from "../flow_constants";
|
||||
|
||||
export function classNames(...classes: Array<string>) {
|
||||
return classes.filter(Boolean).join(" ");
|
||||
}
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
||||
export function toNormalCase(str: string) {
|
||||
let result = str
|
||||
.split("_")
|
||||
.map((word, index) => {
|
||||
if (index === 0) {
|
||||
return word[0].toUpperCase() + word.slice(1).toLowerCase();
|
||||
}
|
||||
return word.toLowerCase();
|
||||
})
|
||||
.join(" ");
|
||||
|
||||
return result
|
||||
.split("-")
|
||||
.map((word, index) => {
|
||||
if (index === 0) {
|
||||
return word[0].toUpperCase() + word.slice(1).toLowerCase();
|
||||
}
|
||||
return word.toLowerCase();
|
||||
})
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
export function normalCaseToSnakeCase(str: string) {
|
||||
return str
|
||||
.split(" ")
|
||||
.map((word, index) => {
|
||||
if (index === 0) {
|
||||
return word[0].toUpperCase() + word.slice(1).toLowerCase();
|
||||
}
|
||||
return word.toLowerCase();
|
||||
})
|
||||
.join("_");
|
||||
}
|
||||
|
||||
export function toTitleCase(str: string) {
|
||||
let result = str
|
||||
.split("_")
|
||||
.map((word, index) => {
|
||||
if (index === 0) {
|
||||
return checkUpperWords(
|
||||
word[0].toUpperCase() + word.slice(1).toLowerCase()
|
||||
);
|
||||
}
|
||||
return checkUpperWords(word.toLowerCase());
|
||||
})
|
||||
.join(" ");
|
||||
|
||||
return result
|
||||
.split("-")
|
||||
.map((word, index) => {
|
||||
if (index === 0) {
|
||||
return checkUpperWords(
|
||||
word[0].toUpperCase() + word.slice(1).toLowerCase()
|
||||
);
|
||||
}
|
||||
return checkUpperWords(word.toLowerCase());
|
||||
})
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
export const upperCaseWords: string[] = ["llm", "uri"];
|
||||
export function checkUpperWords(str: string) {
|
||||
const words = str.split(" ").map((word) => {
|
||||
return upperCaseWords.includes(word.toLowerCase())
|
||||
? word.toUpperCase()
|
||||
: word[0].toUpperCase() + word.slice(1).toLowerCase();
|
||||
});
|
||||
|
||||
return words.join(" ");
|
||||
}
|
||||
|
||||
export function groupByFamily(data, baseClasses, left, type) {
|
||||
let parentOutput: string;
|
||||
let arrOfParent: string[] = [];
|
||||
let arrOfType: { family: string; type: string; component: string }[] = [];
|
||||
let arrOfLength: { length: number; type: string }[] = [];
|
||||
let lastType = "";
|
||||
Object.keys(data).map((d) => {
|
||||
Object.keys(data[d]).map((n) => {
|
||||
try {
|
||||
if (
|
||||
data[d][n].base_classes.some((r) =>
|
||||
baseClasses.split("\n").includes(r)
|
||||
)
|
||||
) {
|
||||
arrOfParent.push(d);
|
||||
}
|
||||
if (n === type) {
|
||||
parentOutput = d;
|
||||
}
|
||||
|
||||
if (d !== lastType) {
|
||||
arrOfLength.push({
|
||||
length: Object.keys(data[d]).length,
|
||||
type: d,
|
||||
});
|
||||
|
||||
lastType = d;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Object.keys(data).map((d) => {
|
||||
Object.keys(data[d]).map((n) => {
|
||||
try {
|
||||
baseClasses.split("\n").forEach((tol) => {
|
||||
data[d][n].base_classes.forEach((data) => {
|
||||
if (tol == data) {
|
||||
arrOfType.push({
|
||||
family: d,
|
||||
type: data,
|
||||
component: n,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (left === false) {
|
||||
let groupedBy = arrOfType.filter((object, index, self) => {
|
||||
const foundIndex = self.findIndex(
|
||||
(o) => o.family === object.family && o.type === object.type
|
||||
);
|
||||
return foundIndex === index;
|
||||
});
|
||||
|
||||
return groupedBy.reduce((result, item) => {
|
||||
const existingGroup = result.find(
|
||||
(group) => group.family === item.family
|
||||
);
|
||||
|
||||
if (existingGroup) {
|
||||
existingGroup.type += `, ${item.type}`;
|
||||
} else {
|
||||
result.push({
|
||||
family: item.family,
|
||||
type: item.type,
|
||||
component: item.component,
|
||||
});
|
||||
}
|
||||
|
||||
if (left === false) {
|
||||
let resFil = result.filter((group) => group.family === parentOutput);
|
||||
result = resFil;
|
||||
}
|
||||
|
||||
return result;
|
||||
}, []);
|
||||
} else {
|
||||
const groupedArray = [];
|
||||
const groupedData = {};
|
||||
|
||||
arrOfType.forEach((item) => {
|
||||
const { family, type, component } = item;
|
||||
const key = `${family}-${type}`;
|
||||
|
||||
if (!groupedData[key]) {
|
||||
groupedData[key] = { family, type, component: [component] };
|
||||
} else {
|
||||
groupedData[key].component.push(component);
|
||||
}
|
||||
});
|
||||
|
||||
for (const key in groupedData) {
|
||||
groupedArray.push(groupedData[key]);
|
||||
}
|
||||
|
||||
groupedArray.forEach((object, index, self) => {
|
||||
const findObj = arrOfLength.find((x) => x.type === object.family);
|
||||
if (object.component.length === findObj.length) {
|
||||
self[index]["type"] = "";
|
||||
} else {
|
||||
self[index]["type"] = object.component.join(", ");
|
||||
}
|
||||
});
|
||||
return groupedArray;
|
||||
}
|
||||
}
|
||||
|
||||
export function buildInputs(tabsState, id) {
|
||||
return tabsState &&
|
||||
tabsState[id] &&
|
||||
tabsState[id].formKeysData &&
|
||||
tabsState[id].formKeysData.input_keys &&
|
||||
Object.keys(tabsState[id].formKeysData.input_keys).length > 0
|
||||
? JSON.stringify(tabsState[id].formKeysData.input_keys)
|
||||
: '{"input": "message"}';
|
||||
}
|
||||
|
||||
export function getRandomElement<T>(array: T[]): T {
|
||||
return array[Math.floor(Math.random() * array.length)];
|
||||
}
|
||||
export function getRandomDescription(): string {
|
||||
return getRandomElement(DESCRIPTIONS);
|
||||
}
|
||||
|
||||
export function getRandomName(
|
||||
retry: number = 0,
|
||||
noSpace: boolean = false,
|
||||
maxRetries: number = 3
|
||||
): string {
|
||||
const left: string[] = ADJECTIVES;
|
||||
const right: string[] = NOUNS;
|
||||
|
||||
const lv = getRandomElement(left);
|
||||
const rv = getRandomElement(right);
|
||||
|
||||
// Condition to avoid "boring wozniak"
|
||||
if (lv === "boring" && rv === "wozniak") {
|
||||
if (retry < maxRetries) {
|
||||
return getRandomName(retry + 1, noSpace, maxRetries);
|
||||
} else {
|
||||
console.warn("Max retries reached, returning as is");
|
||||
}
|
||||
}
|
||||
|
||||
// Append a suffix if retrying and noSpace is true
|
||||
if (retry > 0 && noSpace) {
|
||||
const retrySuffix = Math.floor(Math.random() * 10);
|
||||
return `${lv}_${rv}${retrySuffix}`;
|
||||
}
|
||||
|
||||
// Construct the final name
|
||||
let final_name = noSpace ? `${lv}_${rv}` : `${lv} ${rv}`;
|
||||
// Return title case final name
|
||||
return toTitleCase(final_name);
|
||||
}
|
||||
|
||||
export function getRandomKeyByssmm(): string {
|
||||
const now = new Date();
|
||||
const seconds = String(now.getSeconds()).padStart(2, "0");
|
||||
const milliseconds = String(now.getMilliseconds()).padStart(3, "0");
|
||||
return seconds + milliseconds + Math.abs(Math.floor(Math.random() * 10001));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue