Release 0.4.20 (#931)

This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-09-18 14:35:21 -03:00 • committed by GitHub
commit b6049aeb9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 3650 additions and 2079 deletions

24
poetry.lock generated
View file

@ -2923,13 +2923,13 @@ pytz = ">=2023.3,<2024.0"
[[package]] [[package]]
name = "langsmith" name = "langsmith"
version = "0.0.37" version = "0.0.38"
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
optional = false optional = false
python-versions = ">=3.8.1,<4.0" python-versions = ">=3.8.1,<4.0"
files = [ files = [
{file = "langsmith-0.0.37-py3-none-any.whl", hash = "sha256:bdfec3664162e672f89f9e4d82cbbd3f32587295d3064aab1746080a873ac3a0"}, {file = "langsmith-0.0.38-py3-none-any.whl", hash = "sha256:3bdb107d7b847e0f42a89ce67080aad086db230dec9647b13eb7af37e3d8ff1d"},
{file = "langsmith-0.0.37.tar.gz", hash = "sha256:a20e105329cae9a588414443b0a6eb56c776187e3aab47c327848bae0f1a4377"}, {file = "langsmith-0.0.38.tar.gz", hash = "sha256:508f2a949135055f27d82848ad4dc37b3c2f00f5e05e5296883c65ef528b148f"},
] ]
[package.dependencies] [package.dependencies]
@ -6855,13 +6855,13 @@ files = [
[[package]] [[package]]
name = "typing-extensions" name = "typing-extensions"
version = "4.7.1" version = "4.8.0"
description = "Backported and Experimental Type Hints for Python 3.7+" description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.8"
files = [ files = [
{file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"},
{file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"},
] ]
[[package]] [[package]]
@ -7463,17 +7463,17 @@ multidict = ">=4.0"
[[package]] [[package]]
name = "zipp" name = "zipp"
version = "3.16.2" version = "3.17.0"
description = "Backport of pathlib-compatible object wrapper for zip files" description = "Backport of pathlib-compatible object wrapper for zip files"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"},
{file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"},
] ]
[package.extras] [package.extras]
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"]
testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"]
[[package]] [[package]]

View file

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "langflow" name = "langflow"
version = "0.4.19" version = "0.4.20"
description = "A Python package with a built-in web application" description = "A Python package with a built-in web application"
authors = ["Logspace <contact@logspace.ai>"] authors = ["Logspace <contact@logspace.ai>"]
maintainers = [ maintainers = [

View file

@ -53,6 +53,16 @@ def post_validate_prompt(prompt_request: ValidatePromptRequest):
def get_old_custom_fields(prompt_request): def get_old_custom_fields(prompt_request):
try: try:
if (
len(prompt_request.frontend_node.custom_fields) == 1
and prompt_request.name == ""
):
# If there is only one custom field and the name is empty string
# then we are dealing with the first prompt request after the node was created
prompt_request.name = list(
prompt_request.frontend_node.custom_fields.keys()
)[0]
old_custom_fields = prompt_request.frontend_node.custom_fields[ old_custom_fields = prompt_request.frontend_node.custom_fields[
prompt_request.name prompt_request.name
].copy() ].copy()

View file

@ -290,31 +290,42 @@ def add_base_classes(frontend_node, return_types: List[str]):
def build_langchain_template_custom_component(custom_component: CustomComponent): def build_langchain_template_custom_component(custom_component: CustomComponent):
"""Build a custom component template for the langchain""" """Build a custom component template for the langchain"""
logger.debug("Building custom component template") try:
frontend_node = build_frontend_node(custom_component) logger.debug("Building custom component template")
frontend_node = build_frontend_node(custom_component)
if frontend_node is None: if frontend_node is None:
return None return None
logger.debug("Built base frontend node") logger.debug("Built base frontend node")
template_config = custom_component.build_template_config template_config = custom_component.build_template_config
update_attributes(frontend_node, template_config) update_attributes(frontend_node, template_config)
logger.debug("Updated attributes") logger.debug("Updated attributes")
field_config = build_field_config(custom_component) field_config = build_field_config(custom_component)
logger.debug("Built field config") logger.debug("Built field config")
add_extra_fields( add_extra_fields(
frontend_node, field_config, custom_component.get_function_entrypoint_args frontend_node, field_config, custom_component.get_function_entrypoint_args
) )
logger.debug("Added extra fields") logger.debug("Added extra fields")
frontend_node = add_code_field( frontend_node = add_code_field(
frontend_node, custom_component.code, field_config.get("code", {}) frontend_node, custom_component.code, field_config.get("code", {})
) )
logger.debug("Added code field") logger.debug("Added code field")
add_base_classes( add_base_classes(
frontend_node, custom_component.get_function_entrypoint_return_type frontend_node, custom_component.get_function_entrypoint_return_type
) )
logger.debug("Added base classes") logger.debug("Added base classes")
return frontend_node return frontend_node
except Exception as exc:
raise HTTPException(
status_code=400,
detail={
"error": (
"Invalid type convertion. Please check your code and try again."
),
"traceback": traceback.format_exc(),
},
) from exc
def load_files_from_path(path: str): def load_files_from_path(path: str):

View file

@ -131,6 +131,7 @@ def process_graph_cached(
result = langchain_object.dict() result = langchain_object.dict()
else: else:
logger.warning(f"Unknown langchain_object type: {type(langchain_object)}") logger.warning(f"Unknown langchain_object type: {type(langchain_object)}")
result = langchain_object
return result return result

File diff suppressed because it is too large Load diff

View file

@ -321,11 +321,16 @@ export default function ParameterComponent({
field_name={name} field_name={name}
setNodeClass={(nodeClass) => { setNodeClass={(nodeClass) => {
data.node = nodeClass; data.node = nodeClass;
const clone = cloneDeep(data);
clone.node = nodeClass;
setData(clone);
}} }}
nodeClass={data.node} nodeClass={data.node}
disabled={disabled} disabled={disabled}
value={data.node.template[name].value ?? ""} value={data.node.template[name].value ?? ""}
onChange={handleOnNewValue} onChange={(e) => {
handleOnNewValue(e);
}}
/> />
</div> </div>
) : ( ) : (

View file

@ -3,7 +3,7 @@ import { useEffect } from "react";
import { TypeModal } from "../../constants/enums"; import { TypeModal } from "../../constants/enums";
import { postValidatePrompt } from "../../controllers/API"; import { postValidatePrompt } from "../../controllers/API";
import GenericModal from "../../modals/genericModal"; import GenericModal from "../../modals/genericModal";
import { TextAreaComponentType } from "../../types/components"; import { PromptAreaComponentType } from "../../types/components";
import IconComponent from "../genericIconComponent"; import IconComponent from "../genericIconComponent";
export default function PromptAreaComponent({ export default function PromptAreaComponent({
@ -14,7 +14,7 @@ export default function PromptAreaComponent({
onChange, onChange,
disabled, disabled,
editNode = false, editNode = false,
}: TextAreaComponentType) { }: PromptAreaComponentType) {
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
onChange(""); onChange("");

View file

@ -1,4 +1,4 @@
import { Infinity } from "lucide-react"; import { InfinityIcon } from "lucide-react";
import { forwardRef } from "react"; import { forwardRef } from "react";
const GradientSparkles = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>( const GradientSparkles = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
@ -13,7 +13,7 @@ const GradientSparkles = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
</linearGradient> </linearGradient>
</defs> </defs>
</svg> </svg>
<Infinity stroke="url(#grad1)" ref={ref} {...props} /> <InfinityIcon stroke="url(#grad1)" ref={ref} {...props} />
</> </>
); );
} }

View file

@ -1,5 +1,12 @@
import { cloneDeep } from "lodash"; import { cloneDeep } from "lodash";
import { ReactNode, forwardRef, useContext, useEffect, useState } from "react"; import {
ReactNode,
forwardRef,
useContext,
useEffect,
useRef,
useState,
} from "react";
import CodeAreaComponent from "../../components/codeAreaComponent"; import CodeAreaComponent from "../../components/codeAreaComponent";
import Dropdown from "../../components/dropdownComponent"; import Dropdown from "../../components/dropdownComponent";
import FloatComponent from "../../components/floatComponent"; import FloatComponent from "../../components/floatComponent";
@ -44,40 +51,44 @@ const EditNodeModal = forwardRef(
ref ref
) => { ) => {
const [modalOpen, setModalOpen] = useState(false); const [modalOpen, setModalOpen] = useState(false);
const [myData, setMyData] = useState(data);
const { setTabsState, tabId } = useContext(TabsContext); const { setTabsState, tabId } = useContext(TabsContext);
const { reactFlowInstance } = useContext(typesContext); const { reactFlowInstance } = useContext(typesContext);
const myData = useRef(data);
let disabled = let disabled =
reactFlowInstance?.getEdges().some((e) => e.targetHandle === data.id) ?? reactFlowInstance?.getEdges().some((e) => e.targetHandle === data.id) ??
false; false;
function changeAdvanced(n) { function changeAdvanced(n) {
setMyData((old) => { let newData = cloneDeep(data);
let newData = cloneDeep(old); newData.node.template[n].advanced = !newData.node.template[n].advanced;
newData.node.template[n].advanced = !newData.node.template[n].advanced; myData.current = newData;
return newData;
});
} }
const handleOnNewValue = (newValue: any, name) => { const handleOnNewValue = (newValue: any, name) => {
setMyData((old) => { let newData = cloneDeep(data);
let newData = cloneDeep(old); newData.node.template[name].value = newValue;
newData.node.template[name].value = newValue; myData.current = newData;
return newData;
});
}; };
useEffect(() => { useEffect(() => {
setMyData(data); // reset data to what it is on node when opening modal myData.current = data;
}, [modalOpen]); }, [modalOpen]);
return ( return (
<BaseModal size="large-h-full" open={modalOpen} setOpen={setModalOpen}> <BaseModal
size="large-h-full"
open={modalOpen}
setOpen={setModalOpen}
onChangeOpenModal={(open) => {
let newData = cloneDeep(data);
myData.current = newData;
}}
>
<BaseModal.Trigger>{children}</BaseModal.Trigger> <BaseModal.Trigger>{children}</BaseModal.Trigger>
<BaseModal.Header description={myData.node?.description}> <BaseModal.Header description={myData.current.node?.description}>
<span className="pr-2">{myData.type}</span> <span className="pr-2">{myData.current.type}</span>
<Badge variant="secondary">ID: {myData.id}</Badge> <Badge variant="secondary">ID: {myData.current.id}</Badge>
</BaseModal.Header> </BaseModal.Header>
<BaseModal.Content> <BaseModal.Content>
<div className="flex pb-2"> <div className="flex pb-2">
@ -110,50 +121,57 @@ const EditNodeModal = forwardRef(
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody className="p-0"> <TableBody className="p-0">
{Object.keys(myData.node.template) {Object.keys(myData.current.node.template)
.filter( .filter(
(t) => (t) =>
t.charAt(0) !== "_" && t.charAt(0) !== "_" &&
myData.node.template[t].show && myData.current.node.template[t].show &&
(myData.node.template[t].type === "str" || (myData.current.node.template[t].type === "str" ||
myData.node.template[t].type === "bool" || myData.current.node.template[t].type === "bool" ||
myData.node.template[t].type === "float" || myData.current.node.template[t].type ===
myData.node.template[t].type === "code" || "float" ||
myData.node.template[t].type === "prompt" || myData.current.node.template[t].type === "code" ||
myData.node.template[t].type === "file" || myData.current.node.template[t].type ===
myData.node.template[t].type === "int") "prompt" ||
myData.current.node.template[t].type === "file" ||
myData.current.node.template[t].type === "int")
) )
.map((n, i) => ( .map((n, i) => (
<TableRow key={i} className="h-10"> <TableRow key={i} className="h-10">
<TableCell className="truncate p-0 text-center text-sm text-foreground sm:px-3"> <TableCell className="truncate p-0 text-center text-sm text-foreground sm:px-3">
{myData.node.template[n].name {myData.current.node.template[n].name
? myData.node.template[n].name ? myData.current.node.template[n].name
: myData.node.template[n].display_name} : myData.current.node.template[n].display_name}
</TableCell> </TableCell>
<TableCell className="w-[300px] p-0 text-center text-xs text-foreground "> <TableCell className="w-[300px] p-0 text-center text-xs text-foreground ">
{myData.node.template[n].type === "str" && {myData.current.node.template[n].type === "str" &&
!myData.node.template[n].options ? ( !myData.current.node.template[n].options ? (
<div className="mx-auto"> <div className="mx-auto">
{myData.node.template[n].list ? ( {myData.current.node.template[n].list ? (
<InputListComponent <InputListComponent
editNode={true} editNode={true}
disabled={disabled} disabled={disabled}
value={ value={
!myData.node.template[n].value || !myData.current.node.template[n]
myData.node.template[n].value === "" .value ||
myData.current.node.template[n]
.value === ""
? [""] ? [""]
: myData.node.template[n].value : myData.current.node.template[n]
.value
} }
onChange={(t: string[]) => { onChange={(t: string[]) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
/> />
) : myData.node.template[n].multiline ? ( ) : myData.current.node.template[n]
.multiline ? (
<TextAreaComponent <TextAreaComponent
disabled={disabled} disabled={disabled}
editNode={true} editNode={true}
value={ value={
myData.node.template[n].value ?? "" myData.current.node.template[n].value ??
""
} }
onChange={(t: string) => { onChange={(t: string) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
@ -164,11 +182,12 @@ const EditNodeModal = forwardRef(
editNode={true} editNode={true}
disabled={disabled} disabled={disabled}
password={ password={
myData.node.template[n].password ?? myData.current.node.template[n]
false .password ?? false
} }
value={ value={
myData.node.template[n].value ?? "" myData.current.node.template[n].value ??
""
} }
onChange={(t) => { onChange={(t) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
@ -176,89 +195,114 @@ const EditNodeModal = forwardRef(
/> />
)} )}
</div> </div>
) : myData.node.template[n].type === "bool" ? ( ) : myData.current.node.template[n].type ===
"bool" ? (
<div className="ml-auto"> <div className="ml-auto">
{" "} {" "}
<ToggleShadComponent <ToggleShadComponent
disabled={disabled} disabled={disabled}
enabled={myData.node.template[n].value} enabled={
myData.current.node.template[n].value
}
setEnabled={(t) => { setEnabled={(t) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
size="small" size="small"
/> />
</div> </div>
) : myData.node.template[n].type === "float" ? ( ) : myData.current.node.template[n].type ===
"float" ? (
<div className="mx-auto"> <div className="mx-auto">
<FloatComponent <FloatComponent
disabled={disabled} disabled={disabled}
editNode={true} editNode={true}
value={myData.node.template[n].value ?? ""} value={
myData.current.node.template[n].value ??
""
}
onChange={(t) => { onChange={(t) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
/> />
</div> </div>
) : myData.node.template[n].type === "str" && ) : myData.current.node.template[n].type ===
myData.node.template[n].options ? ( "str" &&
myData.current.node.template[n].options ? (
<div className="mx-auto"> <div className="mx-auto">
<Dropdown <Dropdown
numberOfOptions={nodeLength} numberOfOptions={nodeLength}
editNode={true} editNode={true}
options={myData.node.template[n].options} options={
myData.current.node.template[n].options
}
onSelect={(t) => handleOnNewValue(t, n)} onSelect={(t) => handleOnNewValue(t, n)}
value={ value={
myData.node.template[n].value ?? myData.current.node.template[n].value ??
"Choose an option" "Choose an option"
} }
></Dropdown> ></Dropdown>
</div> </div>
) : myData.node.template[n].type === "int" ? ( ) : myData.current.node.template[n].type ===
"int" ? (
<div className="mx-auto"> <div className="mx-auto">
<IntComponent <IntComponent
disabled={disabled} disabled={disabled}
editNode={true} editNode={true}
value={myData.node.template[n].value ?? ""} value={
myData.current.node.template[n].value ??
""
}
onChange={(t) => { onChange={(t) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
/> />
</div> </div>
) : myData.node.template[n].type === "file" ? ( ) : myData.current.node.template[n].type ===
"file" ? (
<div className="mx-auto"> <div className="mx-auto">
<InputFileComponent <InputFileComponent
editNode={true} editNode={true}
disabled={disabled} disabled={disabled}
value={myData.node.template[n].value ?? ""} value={
myData.current.node.template[n].value ??
""
}
onChange={(t: string) => { onChange={(t: string) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
fileTypes={ fileTypes={
myData.node.template[n].fileTypes myData.current.node.template[n].fileTypes
}
suffixes={
myData.current.node.template[n].suffixes
} }
suffixes={myData.node.template[n].suffixes}
onFileChange={(t: string) => { onFileChange={(t: string) => {
data.node.template[n].file_path = t; data.node.template[n].file_path = t;
}} }}
></InputFileComponent> ></InputFileComponent>
</div> </div>
) : myData.node.template[n].type === "prompt" ? ( ) : myData.current.node.template[n].type ===
"prompt" ? (
<div className="mx-auto"> <div className="mx-auto">
<PromptAreaComponent <PromptAreaComponent
field_name={n} field_name={n}
editNode={true} editNode={true}
disabled={disabled} disabled={disabled}
nodeClass={myData.node} nodeClass={myData.current.node}
setNodeClass={(nodeClass) => { setNodeClass={(nodeClass) => {
myData.node = nodeClass; myData.current.node = nodeClass;
}} }}
value={myData.node.template[n].value ?? ""} value={
myData.current.node.template[n].value ??
""
}
onChange={(t: string) => { onChange={(t: string) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
/> />
</div> </div>
) : myData.node.template[n].type === "code" ? ( ) : myData.current.node.template[n].type ===
"code" ? (
<div className="mx-auto"> <div className="mx-auto">
<CodeAreaComponent <CodeAreaComponent
dynamic={ dynamic={
@ -270,13 +314,17 @@ const EditNodeModal = forwardRef(
nodeClass={data.node} nodeClass={data.node}
disabled={disabled} disabled={disabled}
editNode={true} editNode={true}
value={myData.node.template[n].value ?? ""} value={
myData.current.node.template[n].value ??
""
}
onChange={(t: string) => { onChange={(t: string) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
/> />
</div> </div>
) : myData.node.template[n].type === "Any" ? ( ) : myData.current.node.template[n].type ===
"Any" ? (
"-" "-"
) : ( ) : (
<div className="hidden"></div> <div className="hidden"></div>
@ -285,7 +333,9 @@ const EditNodeModal = forwardRef(
<TableCell className="p-0 text-right"> <TableCell className="p-0 text-right">
<div className="items-center text-center"> <div className="items-center text-center">
<ToggleShadComponent <ToggleShadComponent
enabled={!myData.node.template[n].advanced} enabled={
!myData.current.node.template[n].advanced
}
setEnabled={(e) => changeAdvanced(n)} setEnabled={(e) => changeAdvanced(n)}
disabled={disabled} disabled={disabled}
size="small" size="small"
@ -306,7 +356,7 @@ const EditNodeModal = forwardRef(
<Button <Button
className="mt-3" className="mt-3"
onClick={() => { onClick={() => {
setData(cloneDeep(myData)); //saves data with actual state of modal setData(cloneDeep(myData.current)); //saves data with actual state of modal
setTabsState((prev) => { setTabsState((prev) => {
return { return {
...prev, ...prev,

View file

@ -1,4 +1,4 @@
import { ReactNode } from "react"; import { ReactNode, useEffect } from "react";
import React from "react"; import React from "react";
import { import {
@ -48,6 +48,7 @@ interface BaseModalProps {
setOpen?: (open: boolean) => void; setOpen?: (open: boolean) => void;
disable?: boolean; disable?: boolean;
size?: "smaller" | "small" | "medium" | "large" | "large-h-full"; size?: "smaller" | "small" | "medium" | "large" | "large-h-full";
onChangeOpenModal?: (open: boolean) => void;
} }
function BaseModal({ function BaseModal({
open, open,
@ -55,6 +56,7 @@ function BaseModal({
disable = false, disable = false,
children, children,
size = "large", size = "large",
onChangeOpenModal,
}: BaseModalProps) { }: BaseModalProps) {
const headerChild = React.Children.toArray(children).find( const headerChild = React.Children.toArray(children).find(
(child) => (child as React.ReactElement).type === Header (child) => (child as React.ReactElement).type === Header
@ -98,6 +100,12 @@ function BaseModal({
break; break;
} }
useEffect(() => {
if (onChangeOpenModal) {
onChangeOpenModal(open);
}
}, [open]);
//UPDATE COLORS AND STYLE CLASSSES //UPDATE COLORS AND STYLE CLASSSES
return ( return (
<Dialog open={open} onOpenChange={setOpen}> <Dialog open={open} onOpenChange={setOpen}>

View file

@ -172,18 +172,18 @@ export default function CodeAreaModal({
</div> </div>
<div <div
className={ className={
"w-full transition-all delay-500 " + "whitespace-break-spaces transition-all delay-500" +
(error?.detail.error !== undefined ? "h-2/6" : "h-0") (error?.detail?.error !== undefined ? "h-2/6" : "h-0")
} }
> >
<div className="mt-1 h-full w-full overflow-y-auto overflow-x-clip text-left custom-scroll"> <div className="mt-1 h-full max-h-[10rem] w-full overflow-y-auto overflow-x-clip text-left custom-scroll">
<h1 className="text-lg text-destructive"> <h1 className="text-lg text-destructive">
{error?.detail?.error} {error?.detail?.error}
</h1> </h1>
<div className="ml-2 w-full text-sm text-status-red word-break-break-word"> <div className="ml-2 w-full text-sm text-status-red word-break-break-word">
<pre className="w-full word-break-break-word"> <span className="w-full word-break-break-word">
{error?.detail?.traceback} {error?.detail?.traceback}
</pre> </span>
</div> </div>
</div> </div>
</div> </div>

View file

@ -130,24 +130,35 @@ export default function GenericModal({
: "code-nohighlight"; : "code-nohighlight";
} }
function validatePrompt(closeModal: boolean) { function validatePrompt(closeModal: boolean): void {
postValidatePrompt(field_name, inputValue, nodeClass) //nodeClass is always null on tweaks
postValidatePrompt(field_name, inputValue, nodeClass!)
.then((apiReturn) => { .then((apiReturn) => {
if (apiReturn.data) { if (apiReturn.data) {
setValue(inputValue);
apiReturn.data.frontend_node["template"]["template"]["value"] =
inputValue;
setNodeClass!(apiReturn?.data?.frontend_node);
let inputVariables = apiReturn.data.input_variables ?? []; let inputVariables = apiReturn.data.input_variables ?? [];
if (inputVariables && inputVariables.length === 0) { if (inputVariables && inputVariables.length === 0) {
setIsEdit(true); setIsEdit(true);
setNoticeData({ setNoticeData({
title: "Your template does not have any variables.", title: "Your template does not have any variables.",
}); });
setModalOpen(closeModal);
} else { } else {
setIsEdit(false); setIsEdit(false);
setSuccessData({ setSuccessData({
title: "Prompt is ready", title: "Prompt is ready",
}); });
setNodeClass(apiReturn.data?.frontend_node); if (
setModalOpen(closeModal); JSON.stringify(apiReturn.data?.frontend_node) !==
setValue(inputValue); JSON.stringify({})
) {
setModalOpen(closeModal);
}
} }
} else { } else {
setIsEdit(true); setIsEdit(true);
@ -157,7 +168,6 @@ export default function GenericModal({
} }
}) })
.catch((error) => { .catch((error) => {
console.log(error);
setIsEdit(true); setIsEdit(true);
return setErrorData({ return setErrorData({
title: "There is something wrong with this prompt, please review it", title: "There is something wrong with this prompt, please review it",
@ -169,7 +179,11 @@ export default function GenericModal({
const [modalOpen, setModalOpen] = useState(false); const [modalOpen, setModalOpen] = useState(false);
return ( return (
<BaseModal open={modalOpen} setOpen={setModalOpen}> <BaseModal
onChangeOpenModal={(open) => {}}
open={modalOpen}
setOpen={setModalOpen}
>
<BaseModal.Trigger>{children}</BaseModal.Trigger> <BaseModal.Trigger>{children}</BaseModal.Trigger>
<BaseModal.Header <BaseModal.Header
description={(() => { description={(() => {
@ -295,9 +309,7 @@ export default function GenericModal({
setModalOpen(false); setModalOpen(false);
break; break;
case TypeModal.PROMPT: case TypeModal.PROMPT:
!inputValue || inputValue === "" validatePrompt(false);
? setModalOpen(false)
: validatePrompt(false);
break; break;
default: default:

View file

@ -29,10 +29,28 @@ pre {
animation: slideUp 300ms ease-out; animation: slideUp 300ms ease-out;
} }
.gradient-end { .gradient-end {
animation: gradient-motion-end 3s infinite forwards; animation: gradient-motion-end 3s infinite forwards;
} }
.gradient-start { .gradient-start {
animation: gradient-motion-start 4s infinite forwards; animation: gradient-motion-start 4s infinite forwards;
} }
.ace_scrollbar::-webkit-scrollbar {
height: 8px;
width: 8px;
}
.ace_scrollbar::-webkit-scrollbar-track {
background-color: #f1f1f1;
}
.ace_scrollbar::-webkit-scrollbar-thumb {
background-color: #ccc;
border-radius: 999px;
}
.ace_scrollbar::-webkit-scrollbar-thumb:hover {
background-color: #bbb;
border-radius: 999px;
}

View file

@ -57,6 +57,16 @@ export type TextAreaComponentType = {
editNode?: boolean; editNode?: boolean;
}; };
export type PromptAreaComponentType = {
field_name?: string;
nodeClass?: APIClassType;
setNodeClass?: (value: APIClassType) => void;
disabled: boolean;
onChange: (value: string[] | string) => void;
value: string;
editNode?: boolean;
};
export type CodeAreaComponentType = { export type CodeAreaComponentType = {
disabled: boolean; disabled: boolean;
onChange: (value: string[] | string) => void; onChange: (value: string[] | string) => void;

View file

@ -239,7 +239,6 @@ export function handleKeyDown(
inputValue: string | string[] | null, inputValue: string | string[] | null,
block: string block: string
) { ) {
console.log(e, inputValue, block);
//condition to fix bug control+backspace on Windows/Linux //condition to fix bug control+backspace on Windows/Linux
if ( if (
(typeof inputValue === "string" && (typeof inputValue === "string" &&