Merge remote-tracking branch 'origin/dynamicNode' into form_io
This commit is contained in:
commit
43c06e0c4f
7 changed files with 324 additions and 49 deletions
|
|
@ -5,6 +5,239 @@ from langflow.api import router
|
|||
from langflow.database.base import create_db_and_tables
|
||||
from langflow.interface.utils import setup_llm_caching
|
||||
|
||||
template_node = {
|
||||
"template": {
|
||||
"code": {
|
||||
"required": True,
|
||||
"placeholder": "",
|
||||
"show": True,
|
||||
"multiline": True,
|
||||
"value": "\ndef my_user_python_function(text: str) -> str:\n \"\"\"This is a default python function that returns the input text\"\"\"\n return text.upper()\n",
|
||||
"password": False,
|
||||
"name": "code",
|
||||
"advanced": False,
|
||||
"type": "code",
|
||||
"list": False
|
||||
},
|
||||
"lc_kwargs": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": False,
|
||||
"multiline": False,
|
||||
"password": False,
|
||||
"name": "lc_kwargs",
|
||||
"advanced": True,
|
||||
"type": "code",
|
||||
"list": False
|
||||
},
|
||||
"verbose": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": False,
|
||||
"multiline": False,
|
||||
"value": False,
|
||||
"password": False,
|
||||
"name": "verbose",
|
||||
"advanced": False,
|
||||
"type": "bool",
|
||||
"list": False
|
||||
},
|
||||
"callbacks": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": False,
|
||||
"multiline": False,
|
||||
"password": False,
|
||||
"name": "callbacks",
|
||||
"advanced": False,
|
||||
"type": "langchain.callbacks.base.BaseCallbackHandler",
|
||||
"list": True
|
||||
},
|
||||
"tags": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": False,
|
||||
"multiline": False,
|
||||
"password": False,
|
||||
"name": "tags",
|
||||
"advanced": False,
|
||||
"type": "str",
|
||||
"list": True
|
||||
},
|
||||
"client": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": False,
|
||||
"multiline": False,
|
||||
"password": False,
|
||||
"name": "client",
|
||||
"advanced": False,
|
||||
"type": "Any",
|
||||
"list": False
|
||||
},
|
||||
"model_name": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": True,
|
||||
"multiline": False,
|
||||
"value": "gpt-3.5-turbo",
|
||||
"password": False,
|
||||
"options": [
|
||||
"gpt-3.5-turbo-0613",
|
||||
"gpt-3.5-turbo",
|
||||
"gpt-3.5-turbo-16k-0613",
|
||||
"gpt-3.5-turbo-16k",
|
||||
"gpt-4-0613",
|
||||
"gpt-4-32k-0613",
|
||||
"gpt-4",
|
||||
"gpt-4-32k"
|
||||
],
|
||||
"name": "model_name",
|
||||
"advanced": False,
|
||||
"type": "str",
|
||||
"list": True
|
||||
},
|
||||
"temperature": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": True,
|
||||
"multiline": False,
|
||||
"value": 0.7,
|
||||
"password": False,
|
||||
"name": "temperature",
|
||||
"advanced": False,
|
||||
"type": "float",
|
||||
"list": False
|
||||
},
|
||||
"model_kwargs": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": True,
|
||||
"multiline": False,
|
||||
"password": False,
|
||||
"name": "model_kwargs",
|
||||
"advanced": True,
|
||||
"type": "code",
|
||||
"list": False
|
||||
},
|
||||
"openai_api_key": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": True,
|
||||
"multiline": False,
|
||||
"value": "",
|
||||
"password": True,
|
||||
"name": "openai_api_key",
|
||||
"display_name": "OpenAI API Key",
|
||||
"advanced": False,
|
||||
"type": "str",
|
||||
"list": False
|
||||
},
|
||||
"openai_api_base": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": True,
|
||||
"multiline": False,
|
||||
"password": False,
|
||||
"name": "openai_api_base",
|
||||
"display_name": "OpenAI API Base",
|
||||
"advanced": False,
|
||||
"type": "str",
|
||||
"list": False
|
||||
},
|
||||
"openai_organization": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": False,
|
||||
"multiline": False,
|
||||
"password": False,
|
||||
"name": "openai_organization",
|
||||
"display_name": "OpenAI Organization",
|
||||
"advanced": False,
|
||||
"type": "str",
|
||||
"list": False
|
||||
},
|
||||
"openai_proxy": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": False,
|
||||
"multiline": False,
|
||||
"password": False,
|
||||
"name": "openai_proxy",
|
||||
"display_name": "OpenAI Proxy",
|
||||
"advanced": False,
|
||||
"type": "str",
|
||||
"list": False
|
||||
},
|
||||
"request_timeout": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": False,
|
||||
"multiline": False,
|
||||
"password": False,
|
||||
"name": "request_timeout",
|
||||
"advanced": False,
|
||||
"type": "float",
|
||||
"list": False
|
||||
},
|
||||
"max_retries": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": False,
|
||||
"multiline": False,
|
||||
"value": 6,
|
||||
"password": False,
|
||||
"name": "max_retries",
|
||||
"advanced": False,
|
||||
"type": "int",
|
||||
"list": False
|
||||
},
|
||||
"streaming": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": False,
|
||||
"multiline": False,
|
||||
"value": False,
|
||||
"password": False,
|
||||
"name": "streaming",
|
||||
"advanced": False,
|
||||
"type": "bool",
|
||||
"list": False
|
||||
},
|
||||
"n": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": False,
|
||||
"multiline": False,
|
||||
"value": 1,
|
||||
"password": False,
|
||||
"name": "n",
|
||||
"advanced": False,
|
||||
"type": "int",
|
||||
"list": False
|
||||
},
|
||||
"max_tokens": {
|
||||
"required": False,
|
||||
"placeholder": "",
|
||||
"show": True,
|
||||
"multiline": False,
|
||||
"password": True,
|
||||
"name": "max_tokens",
|
||||
"advanced": False,
|
||||
"type": "int",
|
||||
"list": False
|
||||
},
|
||||
"_type": "ChatOpenAI"
|
||||
},
|
||||
"base_classes": [
|
||||
"BaseChatModel",
|
||||
"Serializable",
|
||||
"BaseLanguageModel",
|
||||
"ChatOpenAI"
|
||||
],
|
||||
"description": "Wrapper around OpenAI Chat large language models."
|
||||
}
|
||||
|
||||
|
||||
def create_app():
|
||||
"""Create the FastAPI app and include the router."""
|
||||
|
|
@ -19,6 +252,10 @@ def create_app():
|
|||
def get_health():
|
||||
return {"status": "OK"}
|
||||
|
||||
@app.get("/dynamic_node")
|
||||
def get_dynamic_nome():
|
||||
return template_node
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=origins,
|
||||
|
|
|
|||
|
|
@ -229,6 +229,8 @@ export default function ParameterComponent({
|
|||
</div>
|
||||
) : left === true && type === "code" ? (
|
||||
<CodeAreaComponent
|
||||
setNodeClass={(nodeClass)=>{data.node = nodeClass}}
|
||||
nodeClass={data.node}
|
||||
disabled={disabled}
|
||||
value={data.node.template[name].value ?? ""}
|
||||
onChange={handleOnNewValue}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ export default function GenericNode({
|
|||
}
|
||||
|
||||
useEffect(() => {}, [closePopUp, data.node.template]);
|
||||
|
||||
console.log({data})
|
||||
return (
|
||||
<>
|
||||
<NodeToolbar>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { useContext, useEffect, useState } from "react";
|
|||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import CodeAreaModal from "../../modals/codeAreaModal";
|
||||
import TextAreaModal from "../../modals/textAreaModal";
|
||||
import { TextAreaComponentType } from "../../types/components";
|
||||
import { CodeAreaComponentType, TextAreaComponentType } from "../../types/components";
|
||||
import { INPUT_STYLE } from "../../constants";
|
||||
import { ExternalLink } from "lucide-react";
|
||||
|
||||
|
|
@ -11,7 +11,9 @@ export default function CodeAreaComponent({
|
|||
onChange,
|
||||
disabled,
|
||||
editNode = false,
|
||||
}: TextAreaComponentType) {
|
||||
nodeClass,
|
||||
setNodeClass,
|
||||
}: CodeAreaComponentType) {
|
||||
const [myValue, setMyValue] = useState(value);
|
||||
const { openPopUp } = useContext(PopUpContext);
|
||||
useEffect(() => {
|
||||
|
|
@ -37,6 +39,8 @@ export default function CodeAreaComponent({
|
|||
openPopUp(
|
||||
<CodeAreaModal
|
||||
value={myValue}
|
||||
nodeClass={nodeClass}
|
||||
setNodeClass={setNodeClass}
|
||||
setValue={(t: string) => {
|
||||
setMyValue(t);
|
||||
onChange(t);
|
||||
|
|
@ -59,7 +63,9 @@ export default function CodeAreaComponent({
|
|||
onClick={() => {
|
||||
openPopUp(
|
||||
<CodeAreaModal
|
||||
setNodeClass={setNodeClass}
|
||||
value={myValue}
|
||||
nodeClass={nodeClass}
|
||||
setValue={(t: string) => {
|
||||
setMyValue(t);
|
||||
onChange(t);
|
||||
|
|
|
|||
|
|
@ -336,3 +336,9 @@ export async function uploadFile(
|
|||
formData.append("file", file);
|
||||
return await axios.post(`/api/v1/upload/${id}`, formData);
|
||||
}
|
||||
export async function UpdateTemplate(
|
||||
type: string,
|
||||
nodeClass: APIClassType
|
||||
): Promise<AxiosResponse<APIClassType>> {
|
||||
return await axios.get(`/dynamic_node`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Fragment, useContext, useRef, useState } from "react";
|
||||
import { useContext, useRef, useState } from "react";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import AceEditor from "react-ace";
|
||||
import "ace-builds/src-noconflict/mode-python";
|
||||
|
|
@ -7,9 +7,8 @@ import "ace-builds/src-noconflict/theme-twilight";
|
|||
import "ace-builds/src-noconflict/ext-language_tools";
|
||||
// import "ace-builds/webpack-resolver";
|
||||
import { darkContext } from "../../contexts/darkContext";
|
||||
import { postValidateCode } from "../../controllers/API";
|
||||
import { UpdateTemplate, postValidateCode } from "../../controllers/API";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
|
|
@ -22,16 +21,22 @@ import {
|
|||
import { Button } from "../../components/ui/button";
|
||||
import { CODE_PROMPT_DIALOG_SUBTITLE } from "../../constants";
|
||||
import { TerminalSquare } from "lucide-react";
|
||||
import { APIClassType } from "../../types/api";
|
||||
|
||||
export default function CodeAreaModal({
|
||||
value,
|
||||
setValue,
|
||||
nodeClass,
|
||||
setNodeClass,
|
||||
}: {
|
||||
setValue: (value: string) => void;
|
||||
value: string;
|
||||
nodeClass: APIClassType;
|
||||
setNodeClass: (Class: APIClassType) => void;
|
||||
}) {
|
||||
const [open, setOpen] = useState(true);
|
||||
const [code, setCode] = useState(value);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { dark } = useContext(darkContext);
|
||||
const { setErrorData, setSuccessData } = useContext(alertContext);
|
||||
const { closePopUp } = useContext(PopUpContext);
|
||||
|
|
@ -44,6 +49,56 @@ export default function CodeAreaModal({
|
|||
}, 300);
|
||||
}
|
||||
}
|
||||
|
||||
function handleClick() {
|
||||
setLoading(true);
|
||||
postValidateCode(code)
|
||||
.then((apiReturn) => {
|
||||
setLoading(false);
|
||||
if (apiReturn.data) {
|
||||
let importsErrors = apiReturn.data.imports.errors;
|
||||
let funcErrors = apiReturn.data.function.errors;
|
||||
if (funcErrors.length === 0 && importsErrors.length === 0) {
|
||||
setSuccessData({
|
||||
title: "Code is ready to run",
|
||||
});
|
||||
// setValue(code);
|
||||
} else {
|
||||
if (funcErrors.length !== 0) {
|
||||
setErrorData({
|
||||
title: "There is an error in your function",
|
||||
list: funcErrors,
|
||||
});
|
||||
}
|
||||
if (importsErrors.length !== 0) {
|
||||
setErrorData({
|
||||
title: "There is an error in your imports",
|
||||
list: importsErrors,
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setErrorData({
|
||||
title: "Something went wrong, please try again",
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((_) => {
|
||||
setLoading(false);
|
||||
setErrorData({
|
||||
title: "There is something wrong with this code, please review it",
|
||||
});
|
||||
});
|
||||
UpdateTemplate("code", nodeClass).then((apiReturn) => {
|
||||
const data = apiReturn.data;
|
||||
if (data) {
|
||||
console.log(data);
|
||||
setNodeClass(data);
|
||||
setModalOpen(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog open={true} onOpenChange={setModalOpen}>
|
||||
<DialogTrigger></DialogTrigger>
|
||||
|
|
@ -78,49 +133,8 @@ export default function CodeAreaModal({
|
|||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button
|
||||
className="mt-3"
|
||||
onClick={() => {
|
||||
postValidateCode(code)
|
||||
.then((apiReturn) => {
|
||||
if (apiReturn.data) {
|
||||
let importsErrors = apiReturn.data.imports.errors;
|
||||
let funcErrors = apiReturn.data.function.errors;
|
||||
if (funcErrors.length === 0 && importsErrors.length === 0) {
|
||||
setSuccessData({
|
||||
title: "Code is ready to run",
|
||||
});
|
||||
setModalOpen(false);
|
||||
setValue(code);
|
||||
} else {
|
||||
if (funcErrors.length !== 0) {
|
||||
setErrorData({
|
||||
title: "There is an error in your function",
|
||||
list: funcErrors,
|
||||
});
|
||||
}
|
||||
if (importsErrors.length !== 0) {
|
||||
setErrorData({
|
||||
title: "There is an error in your imports",
|
||||
list: importsErrors,
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setErrorData({
|
||||
title: "Something went wrong, please try again",
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((_) =>
|
||||
setErrorData({
|
||||
title:
|
||||
"There is something wrong with this code, please review it",
|
||||
})
|
||||
);
|
||||
}}
|
||||
type="submit"
|
||||
>
|
||||
<Button className="mt-3" onClick={handleClick} type="submit">
|
||||
{/* {loading?(<Loading/>):'Check & Save'} */}
|
||||
Check & Save
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import {
|
|||
} from "react";
|
||||
import { NodeDataType } from "../flow/index";
|
||||
import { typesContextType } from "../typesContext";
|
||||
import { APIClassType, APITemplateType } from "../api";
|
||||
export type InputComponentType = {
|
||||
value: string;
|
||||
disabled?: boolean;
|
||||
|
|
@ -56,6 +57,15 @@ export type TextAreaComponentType = {
|
|||
editNode?: boolean;
|
||||
};
|
||||
|
||||
export type CodeAreaComponentType = {
|
||||
disabled: boolean;
|
||||
onChange: (value: string[] | string) => void;
|
||||
value: string;
|
||||
editNode?: boolean;
|
||||
nodeClass: APIClassType;
|
||||
setNodeClass: (value: APIClassType) => void;
|
||||
};
|
||||
|
||||
export type FileComponentType = {
|
||||
disabled: boolean;
|
||||
onChange: (value: string[] | string) => void;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue