prettier
This commit is contained in:
parent
e4b4cf19a2
commit
2bc1fdd32e
12 changed files with 454 additions and 399 deletions
|
|
@ -1,8 +1,4 @@
|
||||||
import {
|
import { useEffect, useRef, useState } from "react";
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from "react";
|
|
||||||
|
|
||||||
import { ChatMessageType, ChatType } from "../../types/chat";
|
import { ChatMessageType, ChatType } from "../../types/chat";
|
||||||
import ChatTrigger from "./chatTrigger";
|
import ChatTrigger from "./chatTrigger";
|
||||||
|
|
@ -14,9 +10,12 @@ export default function Chat({ flow }: ChatType) {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleKeyDown = (event: KeyboardEvent) => {
|
const handleKeyDown = (event: KeyboardEvent) => {
|
||||||
event.preventDefault()
|
// event.preventDefault()
|
||||||
if ((event.key === "K"||event.key==="k") && (event.metaKey||event.ctrlKey)) {
|
if (
|
||||||
setOpen(oldState=>!oldState);
|
(event.key === "K" || event.key === "k") &&
|
||||||
|
(event.metaKey || event.ctrlKey)
|
||||||
|
) {
|
||||||
|
setOpen((oldState) => !oldState);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
document.addEventListener("keydown", handleKeyDown);
|
document.addEventListener("keydown", handleKeyDown);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { PromptTypeAPI, errorsTypeAPI } from './../../types/api/index';
|
import { PromptTypeAPI, errorsTypeAPI } from "./../../types/api/index";
|
||||||
import { APIObjectType, sendAllProps } from '../../types/api/index';
|
import { APIObjectType, sendAllProps } from "../../types/api/index";
|
||||||
import axios, { AxiosResponse } from "axios";
|
import axios, { AxiosResponse } from "axios";
|
||||||
import { FlowType } from '../../types/flow';
|
import { FlowType } from "../../types/flow";
|
||||||
|
|
||||||
export async function getAll(): Promise<AxiosResponse<APIObjectType>> {
|
export async function getAll(): Promise<AxiosResponse<APIObjectType>> {
|
||||||
return await axios.get(`/all`);
|
return await axios.get(`/all`);
|
||||||
|
|
@ -11,22 +11,25 @@ export async function sendAll(data:sendAllProps) {
|
||||||
return await axios.post(`/predict`, data);
|
return await axios.post(`/predict`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkCode(code:string):Promise<AxiosResponse<errorsTypeAPI>>{
|
export async function checkCode(
|
||||||
|
code: string
|
||||||
return await axios.post('/validate/code',{code})
|
): Promise<AxiosResponse<errorsTypeAPI>> {
|
||||||
|
return await axios.post("/validate/code", { code });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkPrompt(template:string):Promise<AxiosResponse<PromptTypeAPI>>{
|
export async function checkPrompt(
|
||||||
|
template: string
|
||||||
return await axios.post('/validate/prompt',{template})
|
): Promise<AxiosResponse<PromptTypeAPI>> {
|
||||||
|
return await axios.post("/validate/prompt", { template });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getExamples(): Promise<FlowType[]> {
|
export async function getExamples(): Promise<FlowType[]> {
|
||||||
const url = 'https://api.github.com/repos/logspace-ai/langflow_examples/contents/examples';
|
const url =
|
||||||
|
"https://api.github.com/repos/logspace-ai/langflow_examples/contents/examples";
|
||||||
const response = await axios.get(url);
|
const response = await axios.get(url);
|
||||||
|
|
||||||
const jsonFiles = response.data.filter((file: any) => {
|
const jsonFiles = response.data.filter((file: any) => {
|
||||||
return file.name.endsWith('.json');
|
return file.name.endsWith(".json");
|
||||||
});
|
});
|
||||||
|
|
||||||
const contentsPromises = jsonFiles.map(async (file: any) => {
|
const contentsPromises = jsonFiles.map(async (file: any) => {
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,7 @@ const nodeTypes = {
|
||||||
var _ = require("lodash");
|
var _ = require("lodash");
|
||||||
|
|
||||||
export default function FlowPage({ flow }: { flow: FlowType }) {
|
export default function FlowPage({ flow }: { flow: FlowType }) {
|
||||||
let { updateFlow, incrementNodeId} =
|
let { updateFlow, incrementNodeId } = useContext(TabsContext);
|
||||||
useContext(TabsContext);
|
|
||||||
const { types, reactFlowInstance, setReactFlowInstance } =
|
const { types, reactFlowInstance, setReactFlowInstance } =
|
||||||
useContext(typesContext);
|
useContext(typesContext);
|
||||||
const reactFlowWrapper = useRef(null);
|
const reactFlowWrapper = useRef(null);
|
||||||
|
|
@ -45,7 +44,7 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
|
||||||
flow.data?.edges ?? []
|
flow.data?.edges ?? []
|
||||||
);
|
);
|
||||||
const { setViewport } = useReactFlow();
|
const { setViewport } = useReactFlow();
|
||||||
const edgeUpdateSuccessful = useRef(true)
|
const edgeUpdateSuccessful = useRef(true);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (reactFlowInstance && flow) {
|
if (reactFlowInstance && flow) {
|
||||||
|
|
@ -110,7 +109,9 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
|
||||||
const reactflowBounds = reactFlowWrapper.current.getBoundingClientRect();
|
const reactflowBounds = reactFlowWrapper.current.getBoundingClientRect();
|
||||||
|
|
||||||
// Extract the data from the drag event and parse it as a JSON object
|
// Extract the data from the drag event and parse it as a JSON object
|
||||||
let data:{type:string,node?:APIClassType} = JSON.parse(event.dataTransfer.getData("json"));
|
let data: { type: string; node?: APIClassType } = JSON.parse(
|
||||||
|
event.dataTransfer.getData("json")
|
||||||
|
);
|
||||||
|
|
||||||
// If data type is not "chatInput" or if there are no "chatInputNode" nodes present in the ReactFlow instance, create a new node
|
// If data type is not "chatInput" or if there are no "chatInputNode" nodes present in the ReactFlow instance, create a new node
|
||||||
if (
|
if (
|
||||||
|
|
@ -153,22 +154,27 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
|
||||||
[incrementNodeId, reactFlowInstance, setErrorData, setNodes]
|
[incrementNodeId, reactFlowInstance, setErrorData, setNodes]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
const onDelete = (mynodes) => {
|
const onDelete = (mynodes) => {
|
||||||
setEdges(edges.filter((ns) => !nodes.some((n) => ns.source === n.id || ns.target === n.id)));
|
setEdges(
|
||||||
}
|
edges.filter(
|
||||||
|
(ns) => !nodes.some((n) => ns.source === n.id || ns.target === n.id)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const onEdgeUpdateStart = useCallback(() => {
|
const onEdgeUpdateStart = useCallback(() => {
|
||||||
edgeUpdateSuccessful.current = false;
|
edgeUpdateSuccessful.current = false;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const onEdgeUpdate = useCallback(
|
||||||
const onEdgeUpdate = useCallback((oldEdge:Edge, newConnection:Connection) => {
|
(oldEdge: Edge, newConnection: Connection) => {
|
||||||
if (isValidConnection(newConnection, reactFlowInstance)) {
|
if (isValidConnection(newConnection, reactFlowInstance)) {
|
||||||
edgeUpdateSuccessful.current = true;
|
edgeUpdateSuccessful.current = true;
|
||||||
setEdges((els) => updateEdge(oldEdge, newConnection, els));
|
setEdges((els) => updateEdge(oldEdge, newConnection, els));
|
||||||
}
|
}
|
||||||
}, []);
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
const onEdgeUpdateEnd = useCallback((_, edge) => {
|
const onEdgeUpdateEnd = useCallback((_, edge) => {
|
||||||
if (!edgeUpdateSuccessful.current) {
|
if (!edgeUpdateSuccessful.current) {
|
||||||
|
|
@ -203,8 +209,7 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
|
||||||
onNodesDelete={onDelete}
|
onNodesDelete={onDelete}
|
||||||
>
|
>
|
||||||
<Background className="dark:bg-gray-900" />
|
<Background className="dark:bg-gray-900" />
|
||||||
<Controls className="[&>button]:text-black [&>button]:dark:bg-gray-800 hover:[&>button]:dark:bg-gray-700 [&>button]:dark:text-gray-400 [&>button]:dark:fill-gray-400 [&>button]:dark:border-gray-600">
|
<Controls className="[&>button]:text-black [&>button]:dark:bg-gray-800 hover:[&>button]:dark:bg-gray-700 [&>button]:dark:text-gray-400 [&>button]:dark:fill-gray-400 [&>button]:dark:border-gray-600"></Controls>
|
||||||
</Controls>
|
|
||||||
</ReactFlow>
|
</ReactFlow>
|
||||||
<Chat flow={flow} reactFlowInstance={reactFlowInstance} />
|
<Chat flow={flow} reactFlowInstance={reactFlowInstance} />
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { ReportHandler } from 'web-vitals';
|
import { ReportHandler } from "web-vitals";
|
||||||
|
|
||||||
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
|
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
|
||||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||||
getCLS(onPerfEntry);
|
getCLS(onPerfEntry);
|
||||||
getFID(onPerfEntry);
|
getFID(onPerfEntry);
|
||||||
getFCP(onPerfEntry);
|
getFCP(onPerfEntry);
|
||||||
|
|
|
||||||
3
src/frontend/src/svg.d.ts
vendored
3
src/frontend/src/svg.d.ts
vendored
|
|
@ -1,5 +1,4 @@
|
||||||
declare module '*.svg' {
|
declare module "*.svg" {
|
||||||
const content: any;
|
const content: any;
|
||||||
export default content;
|
export default content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,20 +1,40 @@
|
||||||
import { Node,Edge,Viewport } from "reactflow"
|
import { Node, Edge, Viewport } from "reactflow";
|
||||||
//kind and class are just representative names to represent the actual structure of the object received by the API
|
//kind and class are just representative names to represent the actual structure of the object received by the API
|
||||||
|
|
||||||
export type APIObjectType = {kind:APIKindType,[key:string]:APIKindType}
|
export type APIObjectType = { kind: APIKindType; [key: string]: APIKindType };
|
||||||
export type APIKindType= {class:APIClassType,[key:string]:APIClassType}
|
export type APIKindType = { class: APIClassType; [key: string]: APIClassType };
|
||||||
export type APITemplateType = {variable:TemplateVariableType,[key:string]:TemplateVariableType}
|
export type APITemplateType = {
|
||||||
export type APIClassType ={base_classes:Array<string>,description:string,template:APITemplateType,[key:string]:Array<string>|string|APITemplateType}
|
variable: TemplateVariableType;
|
||||||
export type TemplateVariableType = {type:string,required:boolean,placeholder?:string,list:boolean,show:boolean,multiline?:boolean,value?:any,[key:string]:any}
|
[key: string]: TemplateVariableType;
|
||||||
|
};
|
||||||
|
export type APIClassType = {
|
||||||
|
base_classes: Array<string>;
|
||||||
|
description: string;
|
||||||
|
template: APITemplateType;
|
||||||
|
[key: string]: Array<string> | string | APITemplateType;
|
||||||
|
};
|
||||||
|
export type TemplateVariableType = {
|
||||||
|
type: string;
|
||||||
|
required: boolean;
|
||||||
|
placeholder?: string;
|
||||||
|
list: boolean;
|
||||||
|
show: boolean;
|
||||||
|
multiline?: boolean;
|
||||||
|
value?: any;
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
export type sendAllProps = {
|
export type sendAllProps = {
|
||||||
nodes: Node[];
|
nodes: Node[];
|
||||||
edges: Edge[];
|
edges: Edge[];
|
||||||
name:string,
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
viewport: Viewport;
|
viewport: Viewport;
|
||||||
message: string;
|
message: string;
|
||||||
|
|
||||||
chatHistory:{message:string,isSend:boolean}[],
|
chatHistory: { message: string; isSend: boolean }[];
|
||||||
};
|
};
|
||||||
export type errorsTypeAPI={function:{errors:Array<string>},imports:{errors:Array<string>}}
|
export type errorsTypeAPI = {
|
||||||
export type PromptTypeAPI = {input_variables:Array<string>}
|
function: { errors: Array<string> };
|
||||||
|
imports: { errors: Array<string> };
|
||||||
|
};
|
||||||
|
export type PromptTypeAPI = { input_variables: Array<string> };
|
||||||
|
|
|
||||||
|
|
@ -66,16 +66,20 @@ export type FloatComponentType = {
|
||||||
onChange: (value: string) => void;
|
onChange: (value: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TooltipComponentType={children:ReactElement,title:string,placement?:
|
export type TooltipComponentType = {
|
||||||
| 'bottom-end'
|
children: ReactElement;
|
||||||
| 'bottom-start'
|
title: string;
|
||||||
| 'bottom'
|
placement?:
|
||||||
| 'left-end'
|
| "bottom-end"
|
||||||
| 'left-start'
|
| "bottom-start"
|
||||||
| 'left'
|
| "bottom"
|
||||||
| 'right-end'
|
| "left-end"
|
||||||
| 'right-start'
|
| "left-start"
|
||||||
| 'right'
|
| "left"
|
||||||
| 'top-end'
|
| "right-end"
|
||||||
| 'top-start'
|
| "right-start"
|
||||||
| 'top';}
|
| "right"
|
||||||
|
| "top-end"
|
||||||
|
| "top-start"
|
||||||
|
| "top";
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
import { HomeIcon } from "@heroicons/react/24/outline";
|
import { HomeIcon } from "@heroicons/react/24/outline";
|
||||||
|
|
||||||
export type sidebarNavigationItemType = { name: string, href: string, icon: React.ForwardRefExoticComponent<React.SVGProps<SVGSVGElement>>, current: boolean }
|
export type sidebarNavigationItemType = {
|
||||||
|
name: string;
|
||||||
|
href: string;
|
||||||
|
icon: React.ForwardRefExoticComponent<React.SVGProps<SVGSVGElement>>;
|
||||||
|
current: boolean;
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { ChatMessageType } from './../chat/index';
|
import { ChatMessageType } from "./../chat/index";
|
||||||
import { APIClassType } from '../api/index';
|
import { APIClassType } from "../api/index";
|
||||||
import { ReactFlowJsonObject, XYPosition } from "reactflow";
|
import { ReactFlowJsonObject, XYPosition } from "reactflow";
|
||||||
|
|
||||||
export type FlowType = {
|
export type FlowType = {
|
||||||
|
|
@ -8,5 +8,15 @@ export type FlowType = {
|
||||||
data: ReactFlowJsonObject;
|
data: ReactFlowJsonObject;
|
||||||
description: string;
|
description: string;
|
||||||
};
|
};
|
||||||
export type NodeType = {id:string,type:string,position:XYPosition,data:NodeDataType}
|
export type NodeType = {
|
||||||
export type NodeDataType = {type:string,node?:APIClassType,id:string,value:any}
|
id: string;
|
||||||
|
type?: string;
|
||||||
|
position: XYPosition;
|
||||||
|
data: NodeDataType;
|
||||||
|
};
|
||||||
|
export type NodeDataType = {
|
||||||
|
type: string;
|
||||||
|
node?: APIClassType;
|
||||||
|
id: string;
|
||||||
|
value: any;
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { ReactFlowInstance } from "reactflow";
|
import { ReactFlowInstance } from "reactflow";
|
||||||
|
|
||||||
const types:{[char: string]: string}={}
|
const types: { [char: string]: string } = {};
|
||||||
|
|
||||||
export type typesContextType = {
|
export type typesContextType = {
|
||||||
reactFlowInstance: ReactFlowInstance | null;
|
reactFlowInstance: ReactFlowInstance | null;
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,11 @@ import {
|
||||||
FingerPrintIcon,
|
FingerPrintIcon,
|
||||||
ScissorsIcon,
|
ScissorsIcon,
|
||||||
CircleStackIcon,
|
CircleStackIcon,
|
||||||
Squares2X2Icon
|
Squares2X2Icon,
|
||||||
} from "@heroicons/react/24/outline";
|
} from "@heroicons/react/24/outline";
|
||||||
import { Connection, Edge, Node, ReactFlowInstance } from "reactflow";
|
import { Connection, Edge, Node, ReactFlowInstance } from "reactflow";
|
||||||
import { FlowType } from "./types/flow";
|
import { FlowType } from "./types/flow";
|
||||||
var _ = require('lodash')
|
var _ = require("lodash");
|
||||||
|
|
||||||
export function classNames(...classes: Array<string>) {
|
export function classNames(...classes: Array<string>) {
|
||||||
return classes.filter(Boolean).join(" ");
|
return classes.filter(Boolean).join(" ");
|
||||||
|
|
@ -87,7 +87,7 @@ export const nodeColors: {[char: string]: string} = {
|
||||||
toolkits: "#DB2C2C",
|
toolkits: "#DB2C2C",
|
||||||
wrappers: "#E6277A",
|
wrappers: "#E6277A",
|
||||||
utilities: "#31A3CC",
|
utilities: "#31A3CC",
|
||||||
unknown:"#9CA3AF"
|
unknown: "#9CA3AF",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const nodeNames: { [char: string]: string } = {
|
export const nodeNames: { [char: string]: string } = {
|
||||||
|
|
@ -106,10 +106,14 @@ export const nodeNames:{[char: string]: string} = {
|
||||||
wrappers: "Wrappers",
|
wrappers: "Wrappers",
|
||||||
textsplitters: "Text Splitters",
|
textsplitters: "Text Splitters",
|
||||||
utilities: "Utilities",
|
utilities: "Utilities",
|
||||||
unknown:"Unknown"
|
unknown: "Unknown",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const nodeIcons:{[char: string]: React.ForwardRefExoticComponent<React.SVGProps<SVGSVGElement>>} = {
|
export const nodeIcons: {
|
||||||
|
[char: string]: React.ForwardRefExoticComponent<
|
||||||
|
React.SVGProps<SVGSVGElement>
|
||||||
|
>;
|
||||||
|
} = {
|
||||||
agents: RocketLaunchIcon,
|
agents: RocketLaunchIcon,
|
||||||
chains: LinkIcon,
|
chains: LinkIcon,
|
||||||
memories: CpuChipIcon,
|
memories: CpuChipIcon,
|
||||||
|
|
@ -125,7 +129,7 @@ export const nodeIcons:{[char: string]: React.ForwardRefExoticComponent<React.SV
|
||||||
textsplitters: ScissorsIcon,
|
textsplitters: ScissorsIcon,
|
||||||
wrappers: GiftIcon,
|
wrappers: GiftIcon,
|
||||||
utilities: Squares2X2Icon,
|
utilities: Squares2X2Icon,
|
||||||
unknown:QuestionMarkCircleIcon
|
unknown: QuestionMarkCircleIcon,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const bgColors = {
|
export const bgColors = {
|
||||||
|
|
@ -270,7 +274,11 @@ export function measureTextWidth(text: string, fontSize:number) {
|
||||||
return wordWidth;
|
return wordWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function measureTextHeight(text: string, width:number, fontSize:number) {
|
export function measureTextHeight(
|
||||||
|
text: string,
|
||||||
|
width: number,
|
||||||
|
fontSize: number
|
||||||
|
) {
|
||||||
const charHeight = fontSize;
|
const charHeight = fontSize;
|
||||||
const lineHeight = charHeight * 1.5;
|
const lineHeight = charHeight * 1.5;
|
||||||
const words = text.split(" ");
|
const words = text.split(" ");
|
||||||
|
|
@ -349,8 +357,11 @@ export function isValidConnection(
|
||||||
reactFlowInstance: ReactFlowInstance
|
reactFlowInstance: ReactFlowInstance
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
sourceHandle.split('|')[0] === targetHandle.split("|")[0] ||
|
sourceHandle.split("|")[0] === targetHandle.split("|")[0] ||
|
||||||
sourceHandle.split('|').slice(2).some((t) => t === targetHandle.split("|")[0]) ||
|
sourceHandle
|
||||||
|
.split("|")
|
||||||
|
.slice(2)
|
||||||
|
.some((t) => t === targetHandle.split("|")[0]) ||
|
||||||
targetHandle.split("|")[0] === "str"
|
targetHandle.split("|")[0] === "str"
|
||||||
) {
|
) {
|
||||||
let targetNode = reactFlowInstance.getNode(target).data.node;
|
let targetNode = reactFlowInstance.getNode(target).data.node;
|
||||||
|
|
@ -376,15 +387,14 @@ export function isValidConnection(
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeApiKeys(flow: FlowType): FlowType {
|
export function removeApiKeys(flow: FlowType): FlowType {
|
||||||
let cleanFLow = _.cloneDeep(flow)
|
let cleanFLow = _.cloneDeep(flow);
|
||||||
cleanFLow.data.nodes.forEach(node=>{
|
cleanFLow.data.nodes.forEach((node) => {
|
||||||
for(const key in node.data.node.template)
|
for (const key in node.data.node.template) {
|
||||||
{
|
if (key.includes("api")) {
|
||||||
if(key.includes('api')){
|
console.log(node.data.node.template[key]);
|
||||||
console.log(node.data.node.template[key])
|
node.data.node.template[key].value = "";
|
||||||
node.data.node.template[key].value = ''
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
return cleanFLow
|
return cleanFLow;
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue