Merge branch 'dev' into tailwind-modal-constants
This commit is contained in:
commit
d3b2c905d9
81 changed files with 646 additions and 452 deletions
|
|
@ -1,6 +1,6 @@
|
|||
from importlib import metadata
|
||||
from langflow.cache import cache_manager
|
||||
from langflow.processing.process import load_flow_from_json
|
||||
from langflow.cache import cache_manager # noqa: E402
|
||||
from langflow.processing.process import load_flow_from_json # noqa: E402
|
||||
|
||||
try:
|
||||
__version__ = metadata.version(__package__)
|
||||
|
|
@ -9,4 +9,5 @@ except metadata.PackageNotFoundError:
|
|||
__version__ = ""
|
||||
del metadata # optional, avoids polluting the results of dir(__package__)
|
||||
|
||||
|
||||
__all__ = ["load_flow_from_json", "cache_manager"]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import os
|
||||
import sys
|
||||
import time
|
||||
import httpx
|
||||
|
|
@ -33,6 +34,10 @@ def update_settings(
|
|||
remove_api_keys: bool = False,
|
||||
):
|
||||
"""Update the settings from a config file."""
|
||||
|
||||
# Check for database_url in the environment variables
|
||||
database_url = database_url or os.getenv("langflow_database_url")
|
||||
|
||||
if config:
|
||||
settings.update_from_yaml(config, dev=dev)
|
||||
if database_url:
|
||||
|
|
@ -43,6 +48,26 @@ def update_settings(
|
|||
settings.update_settings(cache=cache)
|
||||
|
||||
|
||||
def load_params():
|
||||
"""
|
||||
Load the parameters from the environment variables.
|
||||
"""
|
||||
global_vars = globals()
|
||||
|
||||
for key, value in global_vars.items():
|
||||
env_key = f"LANGFLOW_{key.upper()}"
|
||||
if env_key in os.environ:
|
||||
if isinstance(value, bool):
|
||||
# Handle booleans
|
||||
global_vars[key] = os.getenv(env_key, str(value)).lower() == "true"
|
||||
elif isinstance(value, int):
|
||||
# Handle integers
|
||||
global_vars[key] = int(os.getenv(env_key, str(value)))
|
||||
elif isinstance(value, str) or value is None:
|
||||
# Handle strings and None values
|
||||
global_vars[key] = os.getenv(env_key, str(value))
|
||||
|
||||
|
||||
def serve_on_jcloud():
|
||||
"""
|
||||
Deploy Langflow server on Jina AI Cloud
|
||||
|
|
@ -91,19 +116,27 @@ def serve_on_jcloud():
|
|||
|
||||
@app.command()
|
||||
def serve(
|
||||
host: str = typer.Option("127.0.0.1", help="Host to bind the server to."),
|
||||
workers: int = typer.Option(1, help="Number of worker processes."),
|
||||
host: str = typer.Option(
|
||||
"127.0.0.1", help="Host to bind the server to.", envvar="LANGFLOW_HOST"
|
||||
),
|
||||
workers: int = typer.Option(
|
||||
1, help="Number of worker processes.", envvar="LANGFLOW_WORKERS"
|
||||
),
|
||||
timeout: int = typer.Option(60, help="Worker timeout in seconds."),
|
||||
port: int = typer.Option(7860, help="Port to listen on."),
|
||||
port: int = typer.Option(7860, help="Port to listen on.", envvar="LANGFLOW_PORT"),
|
||||
config: str = typer.Option("config.yaml", help="Path to the configuration file."),
|
||||
# .env file param
|
||||
env_file: Path = typer.Option(
|
||||
".env", help="Path to the .env file containing environment variables."
|
||||
),
|
||||
log_level: str = typer.Option("critical", help="Logging level."),
|
||||
log_file: Path = typer.Option("logs/langflow.log", help="Path to the log file."),
|
||||
cache: str = typer.Argument(
|
||||
envvar="LANGCHAIN_CACHE",
|
||||
log_level: str = typer.Option(
|
||||
"critical", help="Logging level.", envvar="LANGFLOW_LOG_LEVEL"
|
||||
),
|
||||
log_file: Path = typer.Option(
|
||||
"logs/langflow.log", help="Path to the log file.", envvar="LANGFLOW_LOG_FILE"
|
||||
),
|
||||
cache: str = typer.Option(
|
||||
envvar="LANGFLOW_LANGCHAIN_CACHE",
|
||||
help="Type of cache to use. (InMemoryCache, SQLiteCache)",
|
||||
default="SQLiteCache",
|
||||
),
|
||||
|
|
@ -112,27 +145,35 @@ def serve(
|
|||
database_url: str = typer.Option(
|
||||
None,
|
||||
help="Database URL to connect to. If not provided, a local SQLite database will be used.",
|
||||
envvar="LANGFLOW_DATABASE_URL",
|
||||
),
|
||||
path: str = typer.Option(
|
||||
None,
|
||||
help="Path to the frontend directory containing build files. This is for development purposes only.",
|
||||
envvar="LANGFLOW_FRONTEND_PATH",
|
||||
),
|
||||
open_browser: bool = typer.Option(
|
||||
True, help="Open the browser after starting the server."
|
||||
True,
|
||||
help="Open the browser after starting the server.",
|
||||
envvar="LANGFLOW_OPEN_BROWSER",
|
||||
),
|
||||
remove_api_keys: bool = typer.Option(
|
||||
False, help="Remove API keys from the projects saved in the database."
|
||||
False,
|
||||
help="Remove API keys from the projects saved in the database.",
|
||||
envvar="LANGFLOW_REMOVE_API_KEYS",
|
||||
),
|
||||
):
|
||||
"""
|
||||
Run the Langflow server.
|
||||
"""
|
||||
# override env variables with .env file
|
||||
if env_file:
|
||||
load_dotenv(env_file, override=True)
|
||||
load_params()
|
||||
|
||||
if jcloud:
|
||||
return serve_on_jcloud()
|
||||
|
||||
load_dotenv(env_file)
|
||||
|
||||
configure(log_level=log_level, log_file=log_file)
|
||||
update_settings(
|
||||
config,
|
||||
|
|
@ -224,7 +265,7 @@ def get_free_port(port):
|
|||
def print_banner(host, port):
|
||||
# console = Console()
|
||||
|
||||
word = "LangFlow"
|
||||
word = "Langflow"
|
||||
colors = ["#3300cc"]
|
||||
|
||||
styled_word = ""
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class GraphData(BaseModel):
|
|||
|
||||
|
||||
class ExportedFlow(BaseModel):
|
||||
"""Exported flow from LangFlow."""
|
||||
"""Exported flow from Langflow."""
|
||||
|
||||
description: str
|
||||
name: str
|
||||
|
|
|
|||
|
|
@ -2,17 +2,34 @@ from langflow.settings import settings
|
|||
from sqlmodel import SQLModel, Session, create_engine
|
||||
from langflow.utils.logger import logger
|
||||
|
||||
if settings.database_url.startswith("sqlite"):
|
||||
if settings.database_url and settings.database_url.startswith("sqlite"):
|
||||
connect_args = {"check_same_thread": False}
|
||||
else:
|
||||
connect_args = {}
|
||||
if not settings.database_url:
|
||||
raise RuntimeError("No database_url provided")
|
||||
engine = create_engine(settings.database_url, connect_args=connect_args)
|
||||
|
||||
|
||||
def create_db_and_tables():
|
||||
logger.debug("Creating database and tables")
|
||||
SQLModel.metadata.create_all(engine)
|
||||
logger.debug("Database and tables created")
|
||||
try:
|
||||
SQLModel.metadata.create_all(engine)
|
||||
except Exception as exc:
|
||||
logger.error(f"Error creating database and tables: {exc}")
|
||||
raise RuntimeError("Error creating database and tables") from exc
|
||||
# Now check if the table Flow exists, if not, something went wrong
|
||||
# and we need to create the tables again.
|
||||
from sqlalchemy import inspect
|
||||
|
||||
inspector = inspect(engine)
|
||||
if "flow" not in inspector.get_table_names():
|
||||
logger.error("Something went wrong creating the database and tables.")
|
||||
logger.error("Please check your database settings.")
|
||||
|
||||
raise RuntimeError("Something went wrong creating the database and tables.")
|
||||
else:
|
||||
logger.debug("Database and tables created successfully")
|
||||
|
||||
|
||||
def get_session():
|
||||
|
|
|
|||
|
|
@ -66,17 +66,24 @@ def extract_input_variables_from_prompt(prompt: str) -> list[str]:
|
|||
def setup_llm_caching():
|
||||
"""Setup LLM caching."""
|
||||
|
||||
from langflow.settings import settings
|
||||
|
||||
try:
|
||||
import langchain
|
||||
from langflow.settings import settings
|
||||
from langflow.interface.importing.utils import import_class
|
||||
|
||||
cache_class = import_class(f"langchain.cache.{settings.cache}")
|
||||
|
||||
logger.debug(f"Setting up LLM caching with {cache_class.__name__}")
|
||||
langchain.llm_cache = cache_class()
|
||||
logger.info(f"LLM caching setup with {cache_class.__name__}")
|
||||
set_langchain_cache(settings)
|
||||
except ImportError:
|
||||
logger.warning(f"Could not import {settings.cache}. ")
|
||||
except Exception as exc:
|
||||
logger.warning(f"Could not setup LLM caching. Error: {exc}")
|
||||
|
||||
|
||||
# TODO Rename this here and in `setup_llm_caching`
|
||||
def set_langchain_cache(settings):
|
||||
import langchain
|
||||
from langflow.interface.importing.utils import import_class
|
||||
|
||||
cache_type = os.getenv("LANGFLOW_LANGCHAIN_CACHE")
|
||||
cache_class = import_class(f"langchain.cache.{cache_type or settings.cache}")
|
||||
|
||||
logger.debug(f"Setting up LLM caching with {cache_class.__name__}")
|
||||
langchain.llm_cache = cache_class()
|
||||
logger.info(f"LLM caching setup with {cache_class.__name__}")
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
# This file is used by lc-serve to load the mounted app and serve it.
|
||||
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
# Use the JCLOUD_WORKSPACE for db URL if it's provided by JCloud.
|
||||
if 'JCLOUD_WORKSPACE' in os.environ:
|
||||
os.environ[
|
||||
'LANGFLOW_DATABASE_URL'
|
||||
] = f"sqlite:///{os.environ['JCLOUD_WORKSPACE']}/langflow.db"
|
||||
|
||||
from langflow.main import create_app
|
||||
from langflow.main import setup_app
|
||||
from langflow.utils.logger import configure
|
||||
|
||||
app = create_app()
|
||||
path = Path(__file__).parent
|
||||
static_files_dir = path / "frontend"
|
||||
app.mount(
|
||||
"/",
|
||||
StaticFiles(directory=static_files_dir, html=True),
|
||||
name="static",
|
||||
)
|
||||
configure(log_level="DEBUG")
|
||||
app = setup_app()
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ def setup_static_files(app: FastAPI, static_files_dir: Path):
|
|||
|
||||
# app = create_app()
|
||||
# setup_static_files(app, static_files_dir)
|
||||
def setup_app(static_files_dir: Optional[Path]) -> FastAPI:
|
||||
def setup_app(static_files_dir: Optional[Path] = None) -> FastAPI:
|
||||
"""Setup the FastAPI app."""
|
||||
# get the directory of the current file
|
||||
if not static_files_dir:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
from typing import Optional
|
||||
|
||||
import yaml
|
||||
from pydantic import BaseSettings, root_validator
|
||||
|
|
@ -21,16 +22,18 @@ class Settings(BaseSettings):
|
|||
textsplitters: dict = {}
|
||||
utilities: dict = {}
|
||||
dev: bool = False
|
||||
database_url: str
|
||||
database_url: Optional[str] = None
|
||||
cache: str = "InMemoryCache"
|
||||
remove_api_keys: bool = False
|
||||
|
||||
@root_validator(pre=True)
|
||||
def set_database_url(cls, values):
|
||||
if "database_url" not in values:
|
||||
logger.debug("No database_url provided, trying DATABASE_URL env variable")
|
||||
if database_url := os.getenv("DATABASE_URL"):
|
||||
values["database_url"] = database_url
|
||||
logger.debug(
|
||||
"No database_url provided, trying LANGFLOW_DATABASE_URL env variable"
|
||||
)
|
||||
if langflow_database_url := os.getenv("LANGFLOW_DATABASE_URL"):
|
||||
values["database_url"] = langflow_database_url
|
||||
else:
|
||||
logger.debug("No DATABASE_URL env variable, using sqlite database")
|
||||
values["database_url"] = "sqlite:///./langflow.db"
|
||||
|
|
@ -39,7 +42,6 @@ class Settings(BaseSettings):
|
|||
class Config:
|
||||
validate_assignment = True
|
||||
extra = "ignore"
|
||||
env_prefix = "LANGFLOW_"
|
||||
|
||||
@root_validator(allow_reuse=True)
|
||||
def validate_lists(cls, values):
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<title>LangFlow</title>
|
||||
<title>Langflow</title>
|
||||
</head>
|
||||
<body id='body' style="width: 100%; height:100%">
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ export default function App() {
|
|||
|
||||
const removeAlert = (id: string) => {
|
||||
setAlertsList((prevAlertsList) =>
|
||||
prevAlertsList.filter((alert) => alert.id !== id)
|
||||
prevAlertsList.filter((alert) => alert.id !== id),
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export default function AccordionComponent({
|
|||
open = [],
|
||||
}: AccordionComponentType) {
|
||||
const [value, setValue] = useState(
|
||||
open.length == 0 ? "" : getOpenAccordion()
|
||||
open.length == 0 ? "" : getOpenAccordion(),
|
||||
);
|
||||
|
||||
function getOpenAccordion() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Disclosure } from "@headlessui/react";
|
||||
import { useContext, useState } from "react";
|
||||
import { useContext } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { classNames } from "../../utils";
|
||||
import { locationContext } from "../../contexts/locationContext";
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ export default function BuildTrigger({
|
|||
|
||||
async function enforceMinimumLoadingTime(
|
||||
startTime: number,
|
||||
minimumLoadingTime: number
|
||||
minimumLoadingTime: number,
|
||||
) {
|
||||
const elapsedTime = Date.now() - startTime;
|
||||
const remainingTime = minimumLoadingTime - elapsedTime;
|
||||
|
|
@ -156,7 +156,11 @@ export default function BuildTrigger({
|
|||
leaveFrom="translate-y-0"
|
||||
leaveTo="translate-y-96"
|
||||
>
|
||||
<div className={'round-buttons-position' + (isBuilt ? " bottom-20" : " bottom-4")}>
|
||||
<div
|
||||
className={
|
||||
"round-buttons-position" + (isBuilt ? " bottom-20" : " bottom-4")
|
||||
}
|
||||
>
|
||||
<div
|
||||
className={`${eventClick} round-button-form`}
|
||||
onClick={() => {
|
||||
|
|
@ -175,7 +179,10 @@ export default function BuildTrigger({
|
|||
value={progress}
|
||||
></RadialProgressComponent>
|
||||
) : isBuilding ? (
|
||||
<Loading strokeWidth={1.5} className="build-trigger-loading-icon" />
|
||||
<Loading
|
||||
strokeWidth={1.5}
|
||||
className="build-trigger-loading-icon"
|
||||
/>
|
||||
) : (
|
||||
<Zap strokeWidth={1.5} className="build-trigger-icon" />
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -31,10 +31,7 @@ export default function ChatTrigger({ open, setOpen, isBuilt }) {
|
|||
leaveTo="translate-y-96"
|
||||
>
|
||||
<div className="message-button-position">
|
||||
<div
|
||||
className="round-button-form"
|
||||
onClick={handleClick}
|
||||
>
|
||||
<div className="round-button-form" onClick={handleClick}>
|
||||
<button>
|
||||
<div className="round-button-div">
|
||||
<MessagesSquare
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ export default function Chat({ flow }: ChatType) {
|
|||
useEffect(() => {
|
||||
const prevNodes = prevNodesRef.current;
|
||||
const currentNodes = nodes.map(
|
||||
(node: NodeType) => node.data.node.template.value
|
||||
(node: NodeType) => node.data.node.template.value,
|
||||
);
|
||||
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export default function CodeAreaComponent({
|
|||
editNode = false,
|
||||
}: TextAreaComponentType) {
|
||||
const [myValue, setMyValue] = useState(
|
||||
typeof value == "string" ? value : JSON.stringify(value)
|
||||
typeof value == "string" ? value : JSON.stringify(value),
|
||||
);
|
||||
const { openPopUp } = useContext(PopUpContext);
|
||||
useEffect(() => {
|
||||
|
|
@ -43,13 +43,14 @@ export default function CodeAreaComponent({
|
|||
setMyValue(t);
|
||||
onChange(t);
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}}
|
||||
className={
|
||||
editNode
|
||||
? "input-edit-node input-dialog"
|
||||
: "input-primary input-dialog " + (disabled ? "input-disable" : "")
|
||||
: "input-dialog input-primary " +
|
||||
(disabled ? "input-disable" : "")
|
||||
}
|
||||
>
|
||||
{myValue !== "" ? myValue : "Type something..."}
|
||||
|
|
@ -63,7 +64,7 @@ export default function CodeAreaComponent({
|
|||
setMyValue(t);
|
||||
onChange(t);
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import { DropDownComponentType } from "../../types/components";
|
|||
import { classNames } from "../../utils";
|
||||
import { ChevronsUpDown, Check } from "lucide-react";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
|
||||
export default function Dropdown({
|
||||
value,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { BellIcon, Home, MoonIcon, SunIcon, Users2 } from "lucide-react";
|
||||
import { Home, MoonIcon, SunIcon, Users2 } from "lucide-react";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa";
|
||||
import { Button } from "../ui/button";
|
||||
|
|
|
|||
|
|
@ -110,7 +110,10 @@ export default function InputFileComponent({
|
|||
</span>
|
||||
<button onClick={handleButtonClick}>
|
||||
{!editNode && !loading && (
|
||||
<FileSearch2 strokeWidth={1.5} className="w-6 h-6 hover:text-accent-foreground" />
|
||||
<FileSearch2
|
||||
strokeWidth={1.5}
|
||||
className="h-6 w-6 hover:text-accent-foreground"
|
||||
/>
|
||||
)}
|
||||
{!editNode && loading && (
|
||||
<span className="loading loading-spinner loading-sm pointer-events-none h-8 pl-3"></span>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export default function PromptAreaComponent({
|
|||
disabled ? "pointer-events-none w-full cursor-not-allowed" : " w-full"
|
||||
}
|
||||
>
|
||||
<div className="w-full flex items-center">
|
||||
<div className="flex w-full items-center">
|
||||
<span
|
||||
onClick={() => {
|
||||
openPopUp(
|
||||
|
|
@ -44,13 +44,15 @@ export default function PromptAreaComponent({
|
|||
setMyValue(t);
|
||||
onChange(t);
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}}
|
||||
className={
|
||||
editNode
|
||||
? " input-edit-node " + " input-dialog "
|
||||
: (disabled ? " input-disable " : "") + " input-primary " + " input-dialog "
|
||||
: (disabled ? " input-disable " : "") +
|
||||
" input-primary " +
|
||||
" input-dialog "
|
||||
}
|
||||
>
|
||||
{myValue !== "" ? myValue : "Type your prompt here"}
|
||||
|
|
@ -67,11 +69,16 @@ export default function PromptAreaComponent({
|
|||
setMyValue(t);
|
||||
onChange(t);
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}}
|
||||
>
|
||||
{!editNode && <ExternalLink strokeWidth={1.5} className="w-6 h-6 hover:text-accent-foreground ml-3" />}
|
||||
{!editNode && (
|
||||
<ExternalLink
|
||||
strokeWidth={1.5}
|
||||
className="ml-3 h-6 w-6 hover:text-accent-foreground"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@ export default function TextAreaComponent({
|
|||
<div className={disabled ? "pointer-events-none cursor-not-allowed" : ""}>
|
||||
<div
|
||||
className={
|
||||
editNode
|
||||
? "w-full items-center"
|
||||
: "w-full flex items-center gap-3"
|
||||
editNode ? "w-full items-center" : "flex w-full items-center gap-3"
|
||||
}
|
||||
>
|
||||
<span
|
||||
|
|
@ -47,13 +45,15 @@ export default function TextAreaComponent({
|
|||
setMyValue(t);
|
||||
onChange(t);
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}}
|
||||
className={
|
||||
editNode
|
||||
? "input-edit-node " + " input-dialog "
|
||||
: " input_dialog " + "px-3 py-2" + (disabled ? " input-disable " : "")
|
||||
: " input_dialog " +
|
||||
"px-3 py-2" +
|
||||
(disabled ? " input-disable " : "")
|
||||
}
|
||||
>
|
||||
{myValue !== "" ? myValue : "Type something..."}
|
||||
|
|
@ -70,11 +70,16 @@ export default function TextAreaComponent({
|
|||
setMyValue(t);
|
||||
onChange(t);
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}}
|
||||
>
|
||||
{!editNode && <ExternalLink strokeWidth={1.5} className="w-6 h-6 hover:text-accent-foreground ml-3" />}
|
||||
{!editNode && (
|
||||
<ExternalLink
|
||||
strokeWidth={1.5}
|
||||
className="ml-3 h-6 w-6 hover:text-accent-foreground"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ const AccordionTrigger = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
|
|
@ -47,7 +47,7 @@ const AccordionContent = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ const badgeVariants = cva(
|
|||
defaultVariants: {
|
||||
variant: "default",
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export interface BadgeProps
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ const buttonVariants = cva(
|
|||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export interface ButtonProps
|
||||
|
|
@ -49,7 +49,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
Button.displayName = "Button";
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ const Checkbox = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const DialogContent = React.forwardRef<
|
|||
<DialogPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"fixed gap-3 z-50 grid w-full rounded-b-lg border bg-background p-6 shadow-lg animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:max-w-lg sm:rounded-lg sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0",
|
||||
"fixed z-50 grid w-full gap-3 rounded-b-lg border bg-background p-6 shadow-lg animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:max-w-lg sm:rounded-lg sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
|||
className={cn(
|
||||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
|
||||
inset && "pl-8",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
|
|
@ -47,7 +47,7 @@ const DropdownMenuSubContent = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
@ -65,7 +65,7 @@ const DropdownMenuContent = React.forwardRef<
|
|||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
@ -84,7 +84,7 @@ const DropdownMenuItem = React.forwardRef<
|
|||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
inset && "pl-8",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
@ -99,7 +99,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
checked={checked}
|
||||
{...props}
|
||||
|
|
@ -123,7 +123,7 @@ const DropdownMenuRadioItem = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
|
|
@ -148,7 +148,7 @@ const DropdownMenuLabel = React.forwardRef<
|
|||
className={cn(
|
||||
"px-2 py-1.5 pl-2 text-sm font-semibold",
|
||||
inset && "pl-8",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|||
type={type}
|
||||
className={cn(
|
||||
"flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
Input.displayName = "Input";
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { cva, type VariantProps } from "class-variance-authority";
|
|||
import { cn } from "../../utils";
|
||||
|
||||
const labelVariants = cva(
|
||||
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
);
|
||||
|
||||
const Label = React.forwardRef<
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const Menubar = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"flex h-10 items-center space-x-1 rounded-md border bg-background p-1",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
@ -39,7 +39,7 @@ const MenubarTrigger = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
@ -57,7 +57,7 @@ const MenubarSubTrigger = React.forwardRef<
|
|||
className={cn(
|
||||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
||||
inset && "pl-8",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
|
|
@ -75,7 +75,7 @@ const MenubarSubContent = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
@ -88,7 +88,7 @@ const MenubarContent = React.forwardRef<
|
|||
>(
|
||||
(
|
||||
{ className, align = "start", alignOffset = -4, sideOffset = 8, ...props },
|
||||
ref
|
||||
ref,
|
||||
) => (
|
||||
<MenubarPrimitive.Portal>
|
||||
<MenubarPrimitive.Content
|
||||
|
|
@ -98,12 +98,12 @@ const MenubarContent = React.forwardRef<
|
|||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in slide-in-from-top-1",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</MenubarPrimitive.Portal>
|
||||
)
|
||||
),
|
||||
);
|
||||
MenubarContent.displayName = MenubarPrimitive.Content.displayName;
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ const MenubarItem = React.forwardRef<
|
|||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
inset && "pl-8",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
@ -133,7 +133,7 @@ const MenubarCheckboxItem = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
checked={checked}
|
||||
{...props}
|
||||
|
|
@ -156,7 +156,7 @@ const MenubarRadioItem = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
|
|
@ -181,7 +181,7 @@ const MenubarLabel = React.forwardRef<
|
|||
className={cn(
|
||||
"px-2 py-1.5 text-sm font-semibold",
|
||||
inset && "pl-8",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
@ -208,7 +208,7 @@ const MenubarShortcut = ({
|
|||
<span
|
||||
className={cn(
|
||||
"ml-auto text-xs tracking-widest text-muted-foreground",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const Progress = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"relative h-4 w-full overflow-hidden rounded-full bg-secondary",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ const Separator = React.forwardRef<
|
|||
>(
|
||||
(
|
||||
{ className, orientation = "horizontal", decorative = true, ...props },
|
||||
ref
|
||||
ref,
|
||||
) => (
|
||||
<SeparatorPrimitive.Root
|
||||
ref={ref}
|
||||
|
|
@ -19,11 +19,11 @@ const Separator = React.forwardRef<
|
|||
className={cn(
|
||||
"shrink-0 bg-border",
|
||||
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
),
|
||||
);
|
||||
Separator.displayName = SeparatorPrimitive.Root.displayName;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ const TableRow = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
@ -70,7 +70,7 @@ const TableHead = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|||
<textarea
|
||||
className={cn(
|
||||
"flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
Textarea.displayName = "Textarea";
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ const TooltipContent = React.forwardRef<
|
|||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ TWEAKS = ${
|
|||
}
|
||||
flow = load_flow_from_json("${flowName}.json", tweaks=TWEAKS)
|
||||
# Now you can use it like any chain
|
||||
flow("Hey, have you heard of LangFlow?")`;
|
||||
flow("Hey, have you heard of Langflow?")`;
|
||||
};
|
||||
|
||||
function buildTweakObject(tweak) {
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ export function AlertProvider({ children }: { children: ReactNode }) {
|
|||
function removeFromNotificationList(index: string) {
|
||||
// set the notification list to a new array that filters out the alert with the matching id
|
||||
setNotificationList((prevAlertsList) =>
|
||||
prevAlertsList.filter((alert) => alert.id !== index)
|
||||
prevAlertsList.filter((alert) => alert.id !== index),
|
||||
);
|
||||
}
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export const darkContext = createContext<darkContextType>(initialValue);
|
|||
|
||||
export function DarkProvider({ children }) {
|
||||
const [dark, setDark] = useState(
|
||||
JSON.parse(window.localStorage.getItem("isDark")) ?? false
|
||||
JSON.parse(window.localStorage.getItem("isDark")) ?? false,
|
||||
);
|
||||
useEffect(() => {
|
||||
if (dark) {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export const locationContext = createContext<locationContextType>(initialValue);
|
|||
export function LocationProvider({ children }: { children: ReactNode }) {
|
||||
const [current, setCurrent] = useState(initialValue.current);
|
||||
const [isStackedOpen, setIsStackedOpen] = useState(
|
||||
initialValue.isStackedOpen
|
||||
initialValue.isStackedOpen,
|
||||
);
|
||||
const [showSideBar, setShowSideBar] = useState(initialValue.showSideBar);
|
||||
const [extraNavigation, setExtraNavigation] = useState({ title: "" });
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
|||
|
||||
// function loadCookie(cookie: string) {
|
||||
// if (cookie && Object.keys(templates).length > 0) {
|
||||
// let cookieObject: LangFlowState = JSON.parse(cookie);
|
||||
// let cookieObject: LangflowState = JSON.parse(cookie);
|
||||
// try {
|
||||
// cookieObject.flows.forEach((flow) => {
|
||||
// if (!flow.data) {
|
||||
|
|
@ -288,7 +288,11 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
|||
// create a link element and set its properties
|
||||
const link = document.createElement("a");
|
||||
link.href = jsonString;
|
||||
link.download = `${flowName && flowName != "" ? flowName : flows.find((f) => f.id === tabId).name}.json`;
|
||||
link.download = `${
|
||||
flowName && flowName != ""
|
||||
? flowName
|
||||
: flows.find((f) => f.id === tabId).name
|
||||
}.json`;
|
||||
|
||||
// simulate a click on the link element to trigger the download
|
||||
link.click();
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ export function TypesProvider({ children }: { children: ReactNode }) {
|
|||
acc[c] = result.data[curr][c];
|
||||
});
|
||||
return acc;
|
||||
}, {})
|
||||
}, {}),
|
||||
);
|
||||
// Set the types by reducing over the keys of the result data and updating the accumulator.
|
||||
setTypes(
|
||||
|
|
@ -62,10 +62,10 @@ export function TypesProvider({ children }: { children: ReactNode }) {
|
|||
result.data[curr][c].base_classes?.forEach((b) => {
|
||||
acc[b] = curr;
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
return acc;
|
||||
}, {})
|
||||
}, {}),
|
||||
);
|
||||
}
|
||||
// Clear the interval if successful.
|
||||
|
|
@ -99,12 +99,12 @@ export function TypesProvider({ children }: { children: ReactNode }) {
|
|||
|
||||
function deleteNode(idx: string) {
|
||||
reactFlowInstance.setNodes(
|
||||
reactFlowInstance.getNodes().filter((n: Node) => n.id !== idx)
|
||||
reactFlowInstance.getNodes().filter((n: Node) => n.id !== idx),
|
||||
);
|
||||
reactFlowInstance.setEdges(
|
||||
reactFlowInstance
|
||||
.getEdges()
|
||||
.filter((ns) => ns.source !== idx && ns.target !== idx)
|
||||
.filter((ns) => ns.source !== idx && ns.target !== idx),
|
||||
);
|
||||
}
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ export function UndoRedoProvider({ children }) {
|
|||
const [past, setPast] = useState<HistoryItem[][]>(flows.map(() => []));
|
||||
const [future, setFuture] = useState<HistoryItem[][]>(flows.map(() => []));
|
||||
const [tabIndex, setTabIndex] = useState(
|
||||
flows.findIndex((f) => f.id === tabId)
|
||||
flows.findIndex((f) => f.id === tabId),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -70,7 +70,7 @@ export function UndoRedoProvider({ children }) {
|
|||
let newPast = cloneDeep(old);
|
||||
newPast[tabIndex] = old[tabIndex].slice(
|
||||
old[tabIndex].length - defaultOptions.maxHistorySize + 1,
|
||||
old[tabIndex].length
|
||||
old[tabIndex].length,
|
||||
);
|
||||
newPast[tabIndex].push({ nodes: getNodes(), edges: getEdges() });
|
||||
return newPast;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const GITHUB_API_URL = "https://api.github.com";
|
|||
export async function getRepoStars(owner, repo) {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`${GITHUB_API_URL}/repos/${owner}/${repo}`
|
||||
`${GITHUB_API_URL}/repos/${owner}/${repo}`,
|
||||
);
|
||||
return response.data.stargazers_count;
|
||||
} catch (error) {
|
||||
|
|
@ -44,7 +44,7 @@ export async function sendAll(data: sendAllProps) {
|
|||
}
|
||||
|
||||
export async function postValidateCode(
|
||||
code: string
|
||||
code: string,
|
||||
): Promise<AxiosResponse<errorsTypeAPI>> {
|
||||
return await axios.post("/api/v1/validate/code", { code });
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ export async function postValidateCode(
|
|||
* @returns {Promise<AxiosResponse<PromptTypeAPI>>} A promise that resolves to an AxiosResponse containing the validation results.
|
||||
*/
|
||||
export async function checkPrompt(
|
||||
template: string
|
||||
template: string,
|
||||
): Promise<AxiosResponse<PromptTypeAPI>> {
|
||||
return await axios.post("/api/v1/validate/prompt", { template });
|
||||
}
|
||||
|
|
@ -120,7 +120,7 @@ export async function saveFlowToDatabase(newFlow: {
|
|||
* @throws Will throw an error if the update fails.
|
||||
*/
|
||||
export async function updateFlowInDatabase(
|
||||
updatedFlow: FlowType
|
||||
updatedFlow: FlowType,
|
||||
): Promise<FlowType> {
|
||||
try {
|
||||
const response = await axios.patch(`/api/v1/flows/${updatedFlow.id}`, {
|
||||
|
|
@ -296,7 +296,7 @@ export async function getHealth() {
|
|||
*
|
||||
*/
|
||||
export async function getBuildStatus(
|
||||
flowId: string
|
||||
flowId: string,
|
||||
): Promise<BuildStatusTypeAPI> {
|
||||
return await axios.get(`/api/v1/build/${flowId}/status`);
|
||||
}
|
||||
|
|
@ -309,7 +309,7 @@ export async function getBuildStatus(
|
|||
*
|
||||
*/
|
||||
export async function postBuildInit(
|
||||
flow: FlowType
|
||||
flow: FlowType,
|
||||
): Promise<AxiosResponse<InitTypeAPI>> {
|
||||
return await axios.post(`/api/v1/build/init/${flow.id}`, flow);
|
||||
}
|
||||
|
|
@ -325,7 +325,7 @@ export async function postBuildInit(
|
|||
*/
|
||||
export async function uploadFile(
|
||||
file: File,
|
||||
id: string
|
||||
id: string,
|
||||
): Promise<AxiosResponse<UploadFileTypeAPI>> {
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export const DESCRIPTIONS: string[] = [
|
|||
"Generate, Innovate, Communicate.",
|
||||
"Conversation Catalyst Engine.",
|
||||
"Language Chainlink Master.",
|
||||
"Design Dialogues with LangFlow.",
|
||||
"Design Dialogues with Langflow.",
|
||||
"Nurture NLP Nodes Here.",
|
||||
"Conversational Cartography Unlocked.",
|
||||
"Design, Develop, Dialogize.",
|
||||
|
|
@ -31,7 +31,7 @@ export const DESCRIPTIONS: string[] = [
|
|||
"Where Language Meets Logic.",
|
||||
"Building Intelligent Interactions.",
|
||||
"Your Passport to Linguistic Landscapes.",
|
||||
"Create, Curate, Communicate with LangFlow.",
|
||||
"Create, Curate, Communicate with Langflow.",
|
||||
"Flow into the Future of Language.",
|
||||
"Mapping Meaningful Conversations.",
|
||||
"Unravel the Art of Articulation.",
|
||||
|
|
@ -41,7 +41,7 @@ export const DESCRIPTIONS: string[] = [
|
|||
"The Pinnacle of Prompt Generation.",
|
||||
"Language Models, Mapped and Mastered.",
|
||||
"Powerful Prompts, Perfectly Positioned.",
|
||||
"Innovation in Interaction with LangFlow.",
|
||||
"Innovation in Interaction with Langflow.",
|
||||
"Your Toolkit for Text Generation.",
|
||||
"Unfolding Linguistic Possibilities.",
|
||||
"Building Powerful Solutions with Language Models.",
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ import { ReactComponent as AzSVG } from "./az_logo.svg";
|
|||
export const AzIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
||||
(props, ref) => {
|
||||
return <AzSVG ref={ref} {...props} />;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ import { ReactComponent as BingSVG } from "./bing.svg";
|
|||
export const BingIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
||||
(props, ref) => {
|
||||
return <BingSVG ref={ref} {...props} />;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ import { ReactComponent as FacebookMessengerSVG } from "./Facebook_Messenger_log
|
|||
export const FBIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
||||
(props, ref) => {
|
||||
return <FacebookMessengerSVG ref={ref} {...props} />;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ import { ReactComponent as IFixItSVG } from "./ifixit-seeklogo.com.svg";
|
|||
export const IFixIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
||||
(props, ref) => {
|
||||
return <IFixItSVG ref={ref} {...props} />;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ import { ReactComponent as MetaSVG } from "./meta-icon.svg";
|
|||
export const MetaIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
||||
(props, ref) => {
|
||||
return <MetaSVG ref={ref} {...props} />;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ import { ReactComponent as SearxSVG } from "./Searx_logo.svg";
|
|||
export const SearxIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
||||
(props, ref) => {
|
||||
return <SearxSVG ref={ref} {...props} />;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ import { ReactComponent as SlackSVG } from "./slack-icon.svg";
|
|||
export const SlackIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
||||
(props, ref) => {
|
||||
return <SlackSVG ref={ref} {...props} />;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ import { ReactComponent as WordSVG } from "./word.svg";
|
|||
export const WordIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
||||
(props, ref) => {
|
||||
return <WordSVG ref={ref} {...props} />;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -482,10 +482,10 @@ The cursor: default; property value restores the browser's default cursor style
|
|||
}
|
||||
|
||||
.dropdown-component-outline {
|
||||
@apply relative pr-8 input-edit-node
|
||||
@apply border-1 input-edit-node relative pr-8
|
||||
}
|
||||
.dropdown-component-false-outline {
|
||||
@apply py-2 pl-3 pr-10 text-left input-primary
|
||||
@apply input-primary py-2 pl-3 pr-10 text-left
|
||||
}
|
||||
.dropdown-component-display {
|
||||
@apply block w-full truncate bg-background
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ import ContextWrapper from "./contexts";
|
|||
import "./index.css";
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById("root") as HTMLElement
|
||||
document.getElementById("root") as HTMLElement,
|
||||
);
|
||||
root.render(
|
||||
<ContextWrapper>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</ContextWrapper>
|
||||
</ContextWrapper>,
|
||||
);
|
||||
reportWebVitals();
|
||||
|
|
|
|||
|
|
@ -104,11 +104,10 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
useEffect(() => {
|
||||
if (closeEdit !== "") {
|
||||
tweak.current = getTweak;
|
||||
if(tweak.current.length > 0){
|
||||
if (tweak.current.length > 0) {
|
||||
setActiveTab("3");
|
||||
openAccordions();
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
startTweaks();
|
||||
}
|
||||
} else {
|
||||
|
|
@ -157,7 +156,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
t.data.node.template[n].type === "code" ||
|
||||
t.data.node.template[n].type === "prompt" ||
|
||||
t.data.node.template[n].type === "file" ||
|
||||
t.data.node.template[n].type === "int")
|
||||
t.data.node.template[n].type === "int"),
|
||||
)
|
||||
.map((n, i) => {
|
||||
arrNodesWithValues.push(t["id"]);
|
||||
|
|
@ -181,7 +180,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
}
|
||||
|
||||
const existingTweak = tweak.current.find((element) =>
|
||||
element.hasOwnProperty(tw)
|
||||
element.hasOwnProperty(tw),
|
||||
);
|
||||
|
||||
if (existingTweak) {
|
||||
|
|
@ -250,25 +249,25 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
|
||||
function openAccordions() {
|
||||
let accordionsToOpen = [];
|
||||
tweak.current.forEach((el) => {
|
||||
Object.keys(el).forEach((key) => {
|
||||
if (Object.keys(el[key]).length > 0) {
|
||||
accordionsToOpen.push(key);
|
||||
setOpenAccordion(accordionsToOpen);
|
||||
}
|
||||
});
|
||||
tweak.current.forEach((el) => {
|
||||
Object.keys(el).forEach((key) => {
|
||||
if (Object.keys(el[key]).length > 0) {
|
||||
accordionsToOpen.push(key);
|
||||
setOpenAccordion(accordionsToOpen);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog open={true} onOpenChange={setModalOpen}>
|
||||
<DialogTrigger></DialogTrigger>
|
||||
<DialogContent className="lg:max-w-[80vw] h-[80vh]">
|
||||
<DialogContent className="h-[80vh] lg:max-w-[80vw]">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="flex items-center">
|
||||
<span className="pr-2">Code</span>
|
||||
<Code2
|
||||
className="h-6 w-6 text-gray-800 pl-1 dark:text-white"
|
||||
className="h-6 w-6 pl-1 text-gray-800 dark:text-white"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</DialogTitle>
|
||||
|
|
@ -296,7 +295,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
{Number(activeTab) < 3 && (
|
||||
<div className="float-right">
|
||||
<button
|
||||
className="flex gap-1.5 items-center rounded bg-none p-1 text-xs text-gray-500 dark:text-gray-300"
|
||||
className="flex items-center gap-1.5 rounded bg-none p-1 text-xs text-gray-500 dark:text-gray-300"
|
||||
onClick={copyToClipboard}
|
||||
>
|
||||
{isCopied ? <Check size={18} /> : <Clipboard size={15} />}
|
||||
|
|
@ -314,7 +313,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
>
|
||||
{index < 3 ? (
|
||||
<SyntaxHighlighter
|
||||
className="w-full overflow-auto h-[60vh]"
|
||||
className="h-[60vh] w-full overflow-auto"
|
||||
language={tab.mode}
|
||||
style={oneDark}
|
||||
>
|
||||
|
|
@ -325,10 +324,10 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
<div className="api-modal-according-display">
|
||||
<div
|
||||
className={classNames(
|
||||
"w-full rounded-lg bg-muted h-[60vh]",
|
||||
"h-[60vh] w-full rounded-lg bg-muted",
|
||||
1 == 1
|
||||
? "overflow-scroll overflow-x-hidden custom-scroll"
|
||||
: "overflow-hidden"
|
||||
: "overflow-hidden",
|
||||
)}
|
||||
>
|
||||
{flow["data"]["nodes"].map((t: any, index) => (
|
||||
|
|
@ -340,12 +339,12 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
>
|
||||
<div className="api-modal-table-arrangement">
|
||||
<Table className="table-fixed bg-muted outline-1">
|
||||
<TableHeader className="border-input text-xs font-medium text-ring h-10">
|
||||
<TableHeader className="h-10 border-input text-xs font-medium text-ring">
|
||||
<TableRow className="dark:border-b-muted">
|
||||
<TableHead className="h-7 text-center">
|
||||
PARAM
|
||||
</TableHead>
|
||||
<TableHead className="p-0 h-7 text-center">
|
||||
<TableHead className="h-7 p-0 text-center">
|
||||
VALUE
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
|
|
@ -369,7 +368,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
t.data.node.template[n].type ===
|
||||
"file" ||
|
||||
t.data.node.template[n].type ===
|
||||
"int")
|
||||
"int"),
|
||||
)
|
||||
.map((n, i) => {
|
||||
//console.log(t.data.node.template[n]);
|
||||
|
|
@ -379,11 +378,11 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
key={i}
|
||||
className="h-10 dark:border-b-muted"
|
||||
>
|
||||
<TableCell className="p-0 text-center text-gray-900 text-sm">
|
||||
<TableCell className="p-0 text-center text-sm text-gray-900">
|
||||
{n}
|
||||
</TableCell>
|
||||
<TableCell className="p-0 text-center text-gray-900 text-xs dark:text-gray-300">
|
||||
<div className="w-[250px] m-auto">
|
||||
<TableCell className="p-0 text-center text-xs text-gray-900 dark:text-gray-300">
|
||||
<div className="m-auto w-[250px]">
|
||||
{t.data.node.template[n]
|
||||
.type === "str" &&
|
||||
!t.data.node.template[n]
|
||||
|
|
@ -412,7 +411,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
t["data"]["id"],
|
||||
k,
|
||||
t.data.node
|
||||
.template[n]
|
||||
.template[n],
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
|
@ -423,7 +422,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
content={buildContent(
|
||||
t.data.node.template[
|
||||
n
|
||||
].value
|
||||
].value,
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
|
|
@ -436,14 +435,14 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
.value,
|
||||
t.data,
|
||||
t.data.node
|
||||
.template[n]
|
||||
.template[n],
|
||||
)}
|
||||
onChange={(k) => {
|
||||
buildTweakObject(
|
||||
t["data"]["id"],
|
||||
k,
|
||||
t.data.node
|
||||
.template[n]
|
||||
.template[n],
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
|
@ -465,14 +464,14 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
t.data,
|
||||
t.data.node.template[
|
||||
n
|
||||
]
|
||||
],
|
||||
)}
|
||||
onChange={(k) => {
|
||||
buildTweakObject(
|
||||
t["data"]["id"],
|
||||
k,
|
||||
t.data.node
|
||||
.template[n]
|
||||
.template[n],
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
|
@ -497,7 +496,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
e,
|
||||
t.data.node.template[
|
||||
n
|
||||
]
|
||||
],
|
||||
);
|
||||
}}
|
||||
size="small"
|
||||
|
|
@ -513,8 +512,8 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
t.data.node.template[n]
|
||||
.value,
|
||||
t.data,
|
||||
t.data.node.template[n]
|
||||
)
|
||||
t.data.node.template[n],
|
||||
),
|
||||
)}
|
||||
>
|
||||
<div className="mx-auto">
|
||||
|
|
@ -527,7 +526,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
].value ?? ""
|
||||
}
|
||||
onChange={(
|
||||
k: any
|
||||
k: any,
|
||||
) => {}}
|
||||
fileTypes={
|
||||
t.data.node.template[
|
||||
|
|
@ -540,7 +539,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
].suffixes
|
||||
}
|
||||
onFileChange={(
|
||||
k: any
|
||||
k: any,
|
||||
) => {}}
|
||||
></InputFileComponent>
|
||||
</div>
|
||||
|
|
@ -555,7 +554,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
t.data.node.template[n]
|
||||
.value,
|
||||
t.data,
|
||||
t.data.node.template[n]
|
||||
t.data.node.template[n],
|
||||
)}
|
||||
onChange={(k) => {
|
||||
buildTweakObject(
|
||||
|
|
@ -563,7 +562,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
k,
|
||||
t.data.node.template[
|
||||
n
|
||||
]
|
||||
],
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
|
@ -586,14 +585,14 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
k,
|
||||
t.data.node.template[
|
||||
n
|
||||
]
|
||||
],
|
||||
);
|
||||
}}
|
||||
value={getValue(
|
||||
t.data.node.template[n]
|
||||
.value,
|
||||
t.data,
|
||||
t.data.node.template[n]
|
||||
t.data.node.template[n],
|
||||
)}
|
||||
></Dropdown>
|
||||
</div>
|
||||
|
|
@ -607,7 +606,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
t.data.node.template[n]
|
||||
.value,
|
||||
t.data,
|
||||
t.data.node.template[n]
|
||||
t.data.node.template[n],
|
||||
)}
|
||||
onChange={(k) => {
|
||||
buildTweakObject(
|
||||
|
|
@ -615,7 +614,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
k,
|
||||
t.data.node.template[
|
||||
n
|
||||
]
|
||||
],
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
|
@ -629,8 +628,8 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
t.data.node.template[n]
|
||||
.value,
|
||||
t.data,
|
||||
t.data.node.template[n]
|
||||
)
|
||||
t.data.node.template[n],
|
||||
),
|
||||
)}
|
||||
>
|
||||
<div className="mx-auto">
|
||||
|
|
@ -644,14 +643,14 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
t.data,
|
||||
t.data.node.template[
|
||||
n
|
||||
]
|
||||
],
|
||||
)}
|
||||
onChange={(k) => {
|
||||
buildTweakObject(
|
||||
t["data"]["id"],
|
||||
k,
|
||||
t.data.node
|
||||
.template[n]
|
||||
.template[n],
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
|
@ -666,8 +665,8 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
t.data.node.template[n]
|
||||
.value,
|
||||
t.data,
|
||||
t.data.node.template[n]
|
||||
)
|
||||
t.data.node.template[n],
|
||||
),
|
||||
)}
|
||||
>
|
||||
<div className="mx-auto">
|
||||
|
|
@ -681,14 +680,14 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
|
|||
t.data,
|
||||
t.data.node.template[
|
||||
n
|
||||
]
|
||||
],
|
||||
)}
|
||||
onChange={(k) => {
|
||||
buildTweakObject(
|
||||
t["data"]["id"],
|
||||
k,
|
||||
t.data.node
|
||||
.template[n]
|
||||
.template[n],
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
|
|||
data.node.template[t].type === "code" ||
|
||||
data.node.template[t].type === "prompt" ||
|
||||
data.node.template[t].type === "file" ||
|
||||
data.node.template[t].type === "int")
|
||||
).length
|
||||
data.node.template[t].type === "int"),
|
||||
).length,
|
||||
);
|
||||
const [nodeValue, setNodeValue] = useState(null);
|
||||
const { closePopUp } = useContext(PopUpContext);
|
||||
|
|
@ -81,7 +81,7 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
|
|||
return (
|
||||
<Dialog open={true} onOpenChange={setModalOpen}>
|
||||
<DialogTrigger asChild></DialogTrigger>
|
||||
<DialogContent className="lg:max-w-[700px] sm:max-w-[600px]">
|
||||
<DialogContent className="sm:max-w-[600px] lg:max-w-[700px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="flex items-center">
|
||||
<span className="pr-2">{data.type}</span>
|
||||
|
|
@ -104,7 +104,7 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
|
|||
"edit-node-modal-box",
|
||||
nodeLength > limitScrollFieldsModal
|
||||
? "overflow-scroll overflow-x-hidden custom-scroll"
|
||||
: "overflow-hidden"
|
||||
: "overflow-hidden",
|
||||
)}
|
||||
>
|
||||
{nodeLength > 0 && (
|
||||
|
|
@ -131,11 +131,11 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
|
|||
data.node.template[t].type === "code" ||
|
||||
data.node.template[t].type === "prompt" ||
|
||||
data.node.template[t].type === "file" ||
|
||||
data.node.template[t].type === "int")
|
||||
data.node.template[t].type === "int"),
|
||||
)
|
||||
.map((n, i) => (
|
||||
<TableRow key={i} className="h-10">
|
||||
<TableCell className="p-0 text-center text-sm text-foreground truncate sm:px-3">
|
||||
<TableCell className="truncate p-0 text-center text-sm text-foreground sm:px-3">
|
||||
{data.node.template[n].name
|
||||
? data.node.template[n].name
|
||||
: data.node.template[n].display_name}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export default function ModalField({
|
|||
index,
|
||||
}) {
|
||||
const [enabled, setEnabled] = useState(
|
||||
data.node.template[name]?.value ?? false
|
||||
data.node.template[name]?.value ?? false,
|
||||
);
|
||||
const display =
|
||||
type === "str" ||
|
||||
|
|
@ -42,12 +42,12 @@ export default function ModalField({
|
|||
(t) =>
|
||||
t.charAt(0) !== "_" &&
|
||||
data.node.template[t].advanced &&
|
||||
data.node.template[t].show
|
||||
data.node.template[t].show,
|
||||
).length -
|
||||
1 ===
|
||||
index
|
||||
? "pb-4"
|
||||
: ""
|
||||
: "",
|
||||
)}
|
||||
>
|
||||
{display && (
|
||||
|
|
|
|||
|
|
@ -100,10 +100,10 @@ export default function NodeModal({ data }: { data: NodeDataType }) {
|
|||
(t) =>
|
||||
t.charAt(0) !== "_" &&
|
||||
data.node.template[t].advanced &&
|
||||
data.node.template[t].show
|
||||
data.node.template[t].show,
|
||||
).length > limitScrollFieldsModal
|
||||
? "overflow-scroll overflow-x-hidden custom-scroll"
|
||||
: "overflow-hidden"
|
||||
: "overflow-hidden",
|
||||
)}
|
||||
>
|
||||
<div className="node-modal-template-column">
|
||||
|
|
@ -112,7 +112,7 @@ export default function NodeModal({ data }: { data: NodeDataType }) {
|
|||
(t) =>
|
||||
t.charAt(0) !== "_" &&
|
||||
data.node.template[t].advanced &&
|
||||
data.node.template[t].show
|
||||
data.node.template[t].show,
|
||||
)
|
||||
.map((t: string, idx) => {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { classNames } from "../../../utils";
|
||||
import { useContext, useEffect, useRef, useState } from "react";
|
||||
import { TabsContext } from "../../../contexts/tabsContext";
|
||||
import { useEffect } from "react";
|
||||
import { Lock, Send } from "lucide-react";
|
||||
|
||||
export default function ChatInput({
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ export default function ChatModal({
|
|||
<span>
|
||||
👋{" "}
|
||||
<span className="text-lg text-muted-foreground">
|
||||
LangFlow Chat
|
||||
Langflow Chat
|
||||
</span>
|
||||
</span>
|
||||
<br />
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ export default function CodeAreaModal({
|
|||
<DialogTitle className="flex items-center">
|
||||
<span className="pr-2">Edit Code</span>
|
||||
<TerminalSquare
|
||||
strokeWidth={1.5}
|
||||
className="h-6 w-6 text-primary pl-1 "
|
||||
strokeWidth={1.5}
|
||||
className="h-6 w-6 pl-1 text-primary "
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</DialogTitle>
|
||||
|
|
@ -118,7 +118,7 @@ export default function CodeAreaModal({
|
|||
setErrorData({
|
||||
title:
|
||||
"There is something wrong with this code, please review it",
|
||||
})
|
||||
}),
|
||||
);
|
||||
}}
|
||||
type="submit"
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export default function ExportModal() {
|
|||
const [checked, setChecked] = useState(false);
|
||||
const [name, setName] = useState(flows.find((f) => f.id === tabId).name);
|
||||
const [description, setDescription] = useState(
|
||||
flows.find((f) => f.id === tabId).description
|
||||
flows.find((f) => f.id === tabId).description,
|
||||
);
|
||||
return (
|
||||
<Dialog open={true} onOpenChange={setModalOpen}>
|
||||
|
|
@ -47,8 +47,8 @@ export default function ExportModal() {
|
|||
<DialogTitle className="flex items-center">
|
||||
<span className="pr-2">Export</span>
|
||||
<Download
|
||||
strokeWidth={1.5}
|
||||
className="h-6 w-6 text-foreground pl-1"
|
||||
strokeWidth={1.5}
|
||||
className="h-6 w-6 pl-1 text-foreground"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</DialogTitle>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export default function FlowSettingsModal() {
|
|||
const maxLength = 50;
|
||||
const [name, setName] = useState(flows.find((f) => f.id === tabId).name);
|
||||
const [description, setDescription] = useState(
|
||||
flows.find((f) => f.id === tabId).description
|
||||
flows.find((f) => f.id === tabId).description,
|
||||
);
|
||||
function setModalOpen(x: boolean) {
|
||||
setOpen(x);
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@ export default function GenericModal({
|
|||
<DialogTitle className="flex items-center">
|
||||
<span className="pr-2">{myModalTitle}</span>
|
||||
<FileText
|
||||
strokeWidth={1.5}
|
||||
className="h-6 w-6 text-primary pl-1 "
|
||||
strokeWidth={1.5}
|
||||
className="h-6 w-6 pl-1 text-primary "
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</DialogTitle>
|
||||
|
|
@ -80,7 +80,7 @@ export default function GenericModal({
|
|||
<div className="mt-2 flex h-full w-full">
|
||||
<Textarea
|
||||
ref={ref}
|
||||
className=" h-[300px] w-full form-primary "
|
||||
className=" form-primary h-[300px] w-full "
|
||||
value={myValue}
|
||||
onChange={(e) => {
|
||||
setMyValue(e.target.value);
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ export default function ButtonBox({
|
|||
bgColor,
|
||||
height,
|
||||
width,
|
||||
padding
|
||||
padding,
|
||||
)}
|
||||
>
|
||||
<div
|
||||
|
|
@ -98,7 +98,7 @@ export default function ButtonBox({
|
|||
className={classNames(
|
||||
"w-full break-words font-semibold text-background truncate-multiline",
|
||||
titleFontSize,
|
||||
marginTop
|
||||
marginTop,
|
||||
)}
|
||||
>
|
||||
{title}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,18 @@
|
|||
import {
|
||||
XMarkIcon,
|
||||
ArrowDownTrayIcon,
|
||||
DocumentDuplicateIcon,
|
||||
ComputerDesktopIcon,
|
||||
ArrowUpTrayIcon,
|
||||
ArrowLeftIcon,
|
||||
CommandLineIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { Fragment, useContext, useRef, useState } from "react";
|
||||
import { useContext, useRef, useState } from "react";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import ButtonBox from "./buttonBox";
|
||||
import { getExamples } from "../../controllers/API";
|
||||
import { error } from "console";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import LoadingComponent from "../../components/loadingComponent";
|
||||
import { FlowType } from "../../types/flow";
|
||||
import { classNames, snakeToSpaces, toNormalCase } from "../../utils";
|
||||
import { classNames } from "../../utils";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
|
|
@ -26,7 +22,6 @@ import {
|
|||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "../../components/ui/dialog";
|
||||
import { Button } from "../../components/ui/button";
|
||||
import { IMPORT_DIALOG_SUBTITLE } from "../../constants";
|
||||
|
||||
export default function ImportModal() {
|
||||
|
|
@ -160,7 +155,10 @@ export default function ImportModal() {
|
|||
bgColor="bg-medium-emerald "
|
||||
description={example.description ?? "Prebuilt Examples"}
|
||||
icon={
|
||||
<DocumentDuplicateIcon strokeWidth={1.5} className="h-6 w-6 flex-shrink-0" />
|
||||
<DocumentDuplicateIcon
|
||||
strokeWidth={1.5}
|
||||
className="h-6 w-6 flex-shrink-0"
|
||||
/>
|
||||
}
|
||||
onClick={() => {
|
||||
addFlow(example, false);
|
||||
|
|
@ -194,7 +192,7 @@ export default function ImportModal() {
|
|||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<span className="ml-2 ">LangFlow Examples</span>
|
||||
<span className="ml-2 ">Langflow Examples</span>
|
||||
</a>
|
||||
</div>
|
||||
</DialogFooter>
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ export default function CommunityPage() {
|
|||
</div>
|
||||
</div>
|
||||
<span className="community-page-description-text">
|
||||
Discover and learn from shared examples by the LangFlow community. We
|
||||
Discover and learn from shared examples by the Langflow community. We
|
||||
welcome new example contributions that can help our community explore
|
||||
new and powerful features.
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -15,9 +15,7 @@ export default function DisclosureComponent({
|
|||
<Disclosure.Button className="components-disclosure-arrangement">
|
||||
<div className="flex gap-4">
|
||||
<Icon strokeWidth={1.5} size={22} className="text-primary" />
|
||||
<span className="components-disclosure-title">
|
||||
{title}
|
||||
</span>
|
||||
<span className="components-disclosure-title">{title}</span>
|
||||
</div>
|
||||
<div className="components-disclosure-div">
|
||||
{buttons.map((x, index) => (
|
||||
|
|
|
|||
|
|
@ -111,10 +111,10 @@ export default function Page({ flow }: { flow: FlowType }) {
|
|||
const { setExtraComponent, setExtraNavigation } = useContext(locationContext);
|
||||
const { setErrorData } = useContext(alertContext);
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(
|
||||
flow.data?.nodes ?? []
|
||||
flow.data?.nodes ?? [],
|
||||
);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(
|
||||
flow.data?.edges ?? []
|
||||
flow.data?.edges ?? [],
|
||||
);
|
||||
const { setViewport } = useReactFlow();
|
||||
const edgeUpdateSuccessful = useRef(true);
|
||||
|
|
@ -156,7 +156,7 @@ export default function Page({ flow }: { flow: FlowType }) {
|
|||
};
|
||||
});
|
||||
},
|
||||
[onEdgesChange, setNodes, setTabsState, tabId]
|
||||
[onEdgesChange, setNodes, setTabsState, tabId],
|
||||
);
|
||||
|
||||
const onNodesChangeMod = useCallback(
|
||||
|
|
@ -171,7 +171,7 @@ export default function Page({ flow }: { flow: FlowType }) {
|
|||
};
|
||||
});
|
||||
},
|
||||
[onNodesChange, setTabsState, tabId]
|
||||
[onNodesChange, setTabsState, tabId],
|
||||
);
|
||||
|
||||
const onConnect = useCallback(
|
||||
|
|
@ -188,15 +188,15 @@ export default function Page({ flow }: { flow: FlowType }) {
|
|||
: "stroke-foreground ",
|
||||
animated: params.targetHandle.split("|")[0] === "Text",
|
||||
},
|
||||
eds
|
||||
)
|
||||
eds,
|
||||
),
|
||||
);
|
||||
setNodes((x) => {
|
||||
let newX = _.cloneDeep(x);
|
||||
return newX;
|
||||
});
|
||||
},
|
||||
[setEdges, setNodes, takeSnapshot]
|
||||
[setEdges, setNodes, takeSnapshot],
|
||||
);
|
||||
|
||||
const onNodeDragStart: NodeDragHandler = useCallback(() => {
|
||||
|
|
@ -230,7 +230,7 @@ export default function Page({ flow }: { flow: FlowType }) {
|
|||
|
||||
// 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")
|
||||
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
|
||||
|
|
@ -275,7 +275,7 @@ export default function Page({ flow }: { flow: FlowType }) {
|
|||
setNodes((nds) => nds.concat(newNode));
|
||||
},
|
||||
// Specify dependencies for useCallback
|
||||
[getNodeId, reactFlowInstance, setErrorData, setNodes, takeSnapshot]
|
||||
[getNodeId, reactFlowInstance, setErrorData, setNodes, takeSnapshot],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -291,11 +291,12 @@ export default function Page({ flow }: { flow: FlowType }) {
|
|||
takeSnapshot();
|
||||
setEdges(
|
||||
edges.filter(
|
||||
(ns) => !mynodes.some((n) => ns.source === n.id || ns.target === n.id)
|
||||
)
|
||||
(ns) =>
|
||||
!mynodes.some((n) => ns.source === n.id || ns.target === n.id),
|
||||
),
|
||||
);
|
||||
},
|
||||
[takeSnapshot, edges, setEdges]
|
||||
[takeSnapshot, edges, setEdges],
|
||||
);
|
||||
|
||||
const onEdgeUpdateStart = useCallback(() => {
|
||||
|
|
@ -309,7 +310,7 @@ export default function Page({ flow }: { flow: FlowType }) {
|
|||
setEdges((els) => updateEdge(oldEdge, newConnection, els));
|
||||
}
|
||||
},
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
const onEdgeUpdateEnd = useCallback((_, edge) => {
|
||||
|
|
|
|||
|
|
@ -69,27 +69,29 @@ export default function ExtraSidebar() {
|
|||
uploadFlow();
|
||||
}}
|
||||
>
|
||||
<FileUp strokeWidth={1.5} className="side-bar-button-size "></FileUp>
|
||||
<FileUp
|
||||
strokeWidth={1.5}
|
||||
className="side-bar-button-size "
|
||||
></FileUp>
|
||||
</button>
|
||||
</ShadTooltip>
|
||||
|
||||
<ShadTooltip content="Export" side="top">
|
||||
<button
|
||||
className={classNames(
|
||||
"extra-side-bar-buttons"
|
||||
)}
|
||||
className={classNames("extra-side-bar-buttons")}
|
||||
onClick={(event) => {
|
||||
openPopUp(<ExportModal />);
|
||||
}}
|
||||
>
|
||||
<FileDown strokeWidth={1.5} className="side-bar-button-size"></FileDown>
|
||||
<FileDown
|
||||
strokeWidth={1.5}
|
||||
className="side-bar-button-size"
|
||||
></FileDown>
|
||||
</button>
|
||||
</ShadTooltip>
|
||||
<ShadTooltip content="Code" side="top">
|
||||
<button
|
||||
className={classNames(
|
||||
"extra-side-bar-buttons"
|
||||
)}
|
||||
className={classNames("extra-side-bar-buttons")}
|
||||
onClick={(event) => {
|
||||
openPopUp(<ApiModal flow={flows.find((f) => f.id === tabId)} />);
|
||||
}}
|
||||
|
|
@ -110,7 +112,8 @@ export default function ExtraSidebar() {
|
|||
<Save
|
||||
strokeWidth={1.5}
|
||||
className={
|
||||
"side-bar-button-size" + (isPending ? " " : " extra-side-bar-save-disable")
|
||||
"side-bar-button-size" +
|
||||
(isPending ? " " : " extra-side-bar-save-disable")
|
||||
}
|
||||
></Save>
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import { TabsContext } from "../../../../contexts/tabsContext";
|
|||
import { useReactFlow } from "reactflow";
|
||||
import EditNodeModal from "../../../../modals/EditNodeModal";
|
||||
import ShadTooltip from "../../../../components/ShadTooltipComponent";
|
||||
import { EllipsisVerticalIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
const NodeToolbarComponent = (props) => {
|
||||
const [nodeLength, setNodeLength] = useState(
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export default function FlowPage() {
|
|||
href="https://logspace.ai/"
|
||||
className="logspace-page-icon"
|
||||
>
|
||||
{version && <div className="mt-1">⛓️ LangFlow v{version}</div>}
|
||||
{version && <div className="mt-1">⛓️ Langflow v{version}</div>}
|
||||
<div className={version ? "mt-2" : "mt-1"}>Created by Logspace</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export type TabsContextType = {
|
|||
setTabsState: Dispatch<SetStateAction<TabsState>>;
|
||||
paste: (
|
||||
selection: { nodes: any; edges: any },
|
||||
position: { x: number; y: number; paneX?: number; paneY?: number }
|
||||
position: { x: number; y: number; paneX?: number; paneY?: number },
|
||||
) => void;
|
||||
lastCopiedSelection: { nodes: any; edges: any };
|
||||
setLastCopiedSelection: (selection: { nodes: any; edges: any }) => void;
|
||||
|
|
|
|||
|
|
@ -484,7 +484,7 @@ export function cn(...inputs: ClassValue[]) {
|
|||
export function measureTextHeight(
|
||||
text: string,
|
||||
width: number,
|
||||
fontSize: number
|
||||
fontSize: number,
|
||||
) {
|
||||
const charHeight = fontSize;
|
||||
const lineHeight = charHeight * 1.5;
|
||||
|
|
@ -511,7 +511,7 @@ export function toCamelCase(str: string) {
|
|||
.map((word, index) =>
|
||||
index === 0
|
||||
? word.toLowerCase()
|
||||
: word[0].toUpperCase() + word.slice(1).toLowerCase()
|
||||
: word[0].toUpperCase() + word.slice(1).toLowerCase(),
|
||||
)
|
||||
.join("");
|
||||
}
|
||||
|
|
@ -572,7 +572,7 @@ export function getConnectedNodes(edge: Edge, nodes: Array<Node>): Array<Node> {
|
|||
|
||||
export function isValidConnection(
|
||||
{ source, target, sourceHandle, targetHandle }: Connection,
|
||||
reactFlowInstance: ReactFlowInstance
|
||||
reactFlowInstance: ReactFlowInstance,
|
||||
) {
|
||||
if (
|
||||
sourceHandle.split("|")[0] === targetHandle.split("|")[0] ||
|
||||
|
|
@ -619,7 +619,7 @@ export function removeApiKeys(flow: FlowType): FlowType {
|
|||
|
||||
export function updateObject<T extends Record<string, any>>(
|
||||
reference: T,
|
||||
objectToUpdate: T
|
||||
objectToUpdate: T,
|
||||
): T {
|
||||
let clonedObject = _.cloneDeep(objectToUpdate);
|
||||
// Loop through each key in the object to update
|
||||
|
|
@ -650,7 +650,7 @@ export function debounce(func, wait) {
|
|||
|
||||
export function updateTemplate(
|
||||
reference: APITemplateType,
|
||||
objectToUpdate: APITemplateType
|
||||
objectToUpdate: APITemplateType,
|
||||
): APITemplateType {
|
||||
let clonedObject: APITemplateType = _.cloneDeep(reference);
|
||||
|
||||
|
|
@ -708,7 +708,7 @@ export function toTitleCase(str: string) {
|
|||
.map((word, index) => {
|
||||
if (index === 0) {
|
||||
return checkUpperWords(
|
||||
word[0].toUpperCase() + word.slice(1).toLowerCase()
|
||||
word[0].toUpperCase() + word.slice(1).toLowerCase(),
|
||||
);
|
||||
}
|
||||
return checkUpperWords(word.toLowerCase());
|
||||
|
|
@ -720,7 +720,7 @@ export function toTitleCase(str: string) {
|
|||
.map((word, index) => {
|
||||
if (index === 0) {
|
||||
return checkUpperWords(
|
||||
word[0].toUpperCase() + word.slice(1).toLowerCase()
|
||||
word[0].toUpperCase() + word.slice(1).toLowerCase(),
|
||||
);
|
||||
}
|
||||
return checkUpperWords(word.toLowerCase());
|
||||
|
|
@ -789,7 +789,7 @@ export function groupByFamily(data, baseClasses) {
|
|||
});
|
||||
|
||||
let uniq = arrOfParent.filter(
|
||||
(item, index) => arrOfParent.indexOf(item) === index
|
||||
(item, index) => arrOfParent.indexOf(item) === index,
|
||||
);
|
||||
|
||||
Object.keys(data).map((d) => {
|
||||
|
|
@ -809,7 +809,7 @@ export function groupByFamily(data, baseClasses) {
|
|||
|
||||
let groupedBy = arrOfType.filter((object, index, self) => {
|
||||
const foundIndex = self.findIndex(
|
||||
(o) => o.family === object.family && o.type === object.type
|
||||
(o) => o.family === object.family && o.type === object.type,
|
||||
);
|
||||
return foundIndex === index;
|
||||
});
|
||||
|
|
@ -835,7 +835,7 @@ export function buildTweaks(flow) {
|
|||
}
|
||||
export function validateNode(
|
||||
n: NodeType,
|
||||
reactFlowInstance: ReactFlowInstance
|
||||
reactFlowInstance: ReactFlowInstance,
|
||||
): Array<string> {
|
||||
if (!n.data?.node?.template || !Object.keys(n.data.node.template)) {
|
||||
return [
|
||||
|
|
@ -861,16 +861,16 @@ export function validateNode(
|
|||
.some(
|
||||
(e) =>
|
||||
e.targetHandle.split("|")[1] === t &&
|
||||
e.targetHandle.split("|")[2] === n.id
|
||||
e.targetHandle.split("|")[2] === n.id,
|
||||
)
|
||||
? [
|
||||
`${type} is missing ${
|
||||
template.display_name || toNormalCase(template[t].name)
|
||||
}.`,
|
||||
]
|
||||
: []
|
||||
: [],
|
||||
),
|
||||
[] as string[]
|
||||
[] as string[],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -895,7 +895,7 @@ export function getRandomDescription(): string {
|
|||
export function getRandomName(
|
||||
retry: number = 0,
|
||||
noSpace: boolean = false,
|
||||
maxRetries: number = 3
|
||||
maxRetries: number = 3,
|
||||
): string {
|
||||
const left: string[] = ADJECTIVES;
|
||||
const right: string[] = NOUNS;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue