diff --git a/.gitattributes b/.gitattributes index d6e351bc3..379b21be8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11,12 +11,12 @@ *.ts text *.tsx text *.md text -*.mdx text working-tree-encoding = UTF-8 +*.mdx text *.yml text *.yaml text *.xml text *.csv text -*.json text working-tree-encoding = UTF-8 +*.json text *.sh text *.Dockerfile text Dockerfile text diff --git a/src/backend/base/langflow/api/utils.py b/src/backend/base/langflow/api/utils.py index 1dbd68d8f..82bd32165 100644 --- a/src/backend/base/langflow/api/utils.py +++ b/src/backend/base/langflow/api/utils.py @@ -219,7 +219,7 @@ async def build_and_cache_graph_from_db(flow_id: str, session: Session, chat_ser if vertex is None: raise ValueError(f"Vertex {vertex_id} not found") if not vertex._raw_params.get("session_id"): - vertex.update_raw_params({"session_id": flow_id}) + vertex.update_raw_params({"session_id": flow_id}, overwrite=True) await chat_service.set_cache(flow_id, graph) return graph diff --git a/src/backend/base/langflow/api/v1/files.py b/src/backend/base/langflow/api/v1/files.py index f6293686f..a72ee7711 100644 --- a/src/backend/base/langflow/api/v1/files.py +++ b/src/backend/base/langflow/api/v1/files.py @@ -110,7 +110,7 @@ async def download_profile_picture( extension = file_name.split(".")[-1] config_dir = get_storage_service().settings_service.settings.config_dir config_path = Path(config_dir) - folder_path = config_path / 'profile_pictures' / folder_name + folder_path = config_path / "profile_pictures" / folder_name content_type = build_content_type_from_extension(extension) file_content = await storage_service.get_file(flow_id=folder_path, file_name=file_name) return StreamingResponse(BytesIO(file_content), media_type=content_type) @@ -140,7 +140,6 @@ async def list_profile_pictures(storage_service: StorageService = Depends(get_st raise HTTPException(status_code=500, detail=str(e)) - @router.get("/list/{flow_id}") async def list_files( flow_id: UUID = Depends(get_flow_id), storage_service: StorageService = Depends(get_storage_service) diff --git a/src/backend/base/langflow/base/vectorstores/utils.py b/src/backend/base/langflow/base/vectorstores/utils.py index e8d93ff37..739181600 100644 --- a/src/backend/base/langflow/base/vectorstores/utils.py +++ b/src/backend/base/langflow/base/vectorstores/utils.py @@ -15,7 +15,7 @@ def chroma_collection_to_records(collection_dict: dict): for i, doc in enumerate(collection_dict["documents"]): record_dict = { "id": collection_dict["ids"][i], - "document": doc, + "text": doc, } if "metadatas" in collection_dict: for key, value in collection_dict["metadatas"][i].items(): diff --git a/src/backend/base/langflow/components/outputs/RecordsOutput.py b/src/backend/base/langflow/components/outputs/RecordsOutput.py index c750e675b..cbd268ea6 100644 --- a/src/backend/base/langflow/components/outputs/RecordsOutput.py +++ b/src/backend/base/langflow/components/outputs/RecordsOutput.py @@ -16,4 +16,5 @@ class RecordOutput(CustomComponent): } def build(self, input_value: Record) -> Record: + self.status = input_value return input_value diff --git a/src/backend/base/langflow/components/retrievers/SelfQueryRetriever.py b/src/backend/base/langflow/components/retrievers/SelfQueryRetriever.py new file mode 100644 index 000000000..3e6d6f696 --- /dev/null +++ b/src/backend/base/langflow/components/retrievers/SelfQueryRetriever.py @@ -0,0 +1,68 @@ +# from langflow.field_typing import Data +from langchain.chains.query_constructor.base import AttributeInfo +from langchain.retrievers.self_query.base import SelfQueryRetriever +from langchain_core.vectorstores import VectorStore + +from langflow.custom import CustomComponent +from langflow.field_typing import BaseLanguageModel, Text +from langflow.schema import Record +from langflow.schema.message import Message + + +class SelfQueryRetrieverComponent(CustomComponent): + display_name: str = "Self Query Retriever" + description: str = "Retriever that uses a vector store and an LLM to generate the vector store queries." + icon = "LangChain" + + def build_config(self): + return { + "query": { + "display_name": "Query", + "input_types": ["Message", "Text"], + "info": "Query to be passed as input.", + }, + "vectorstore": { + "display_name": "Vector Store", + "info": "Vector Store to be passed as input.", + }, + "attribute_infos": { + "display_name": "Metadata Field Info", + "info": "Metadata Field Info to be passed as input.", + }, + "document_content_description": { + "display_name": "Document Content Description", + "info": "Document Content Description to be passed as input.", + }, + "llm": { + "display_name": "LLM", + "info": "LLM to be passed as input.", + }, + } + + def build( + self, + query: Message, + vectorstore: VectorStore, + attribute_infos: list[Record], + document_content_description: Text, + llm: BaseLanguageModel, + ) -> Record: + metadata_field_infos = [AttributeInfo(**record.data) for record in attribute_infos] + self_query_retriever = SelfQueryRetriever.from_llm( + llm=llm, + vectorstore=vectorstore, + document_contents=document_content_description, + metadata_field_info=metadata_field_infos, + enable_limit=True, + ) + + if isinstance(query, Message): + input_text = query.text + elif isinstance(query, str): + input_text = query + else: + raise ValueError(f"Query type {type(query)} not supported.") + documents = self_query_retriever.invoke(input=input_text) + records = [Record.from_document(document) for document in documents] + self.status = records + return records diff --git a/src/backend/base/langflow/components/vectorstores/Chroma.py b/src/backend/base/langflow/components/vectorstores/Chroma.py index b7cfad7d4..6001b119c 100644 --- a/src/backend/base/langflow/components/vectorstores/Chroma.py +++ b/src/backend/base/langflow/components/vectorstores/Chroma.py @@ -1,3 +1,4 @@ +from copy import deepcopy from typing import List, Optional, Union import chromadb @@ -6,6 +7,7 @@ from langchain_chroma import Chroma from langchain_core.embeddings import Embeddings from langchain_core.retrievers import BaseRetriever from langchain_core.vectorstores import VectorStore + from langflow.base.vectorstores.utils import chroma_collection_to_records from langflow.custom import CustomComponent from langflow.schema import Record @@ -48,6 +50,11 @@ class ChromaComponent(CustomComponent): "display_name": "Server SSL Enabled", "advanced": True, }, + "allow_duplicates": { + "display_name": "Allow Duplicates", + "advanced": True, + "info": "If false, will not add documents that are already in the Vector Store.", + }, } def build( @@ -61,6 +68,7 @@ class ChromaComponent(CustomComponent): chroma_server_host: Optional[str] = None, chroma_server_http_port: Optional[int] = None, chroma_server_grpc_port: Optional[int] = None, + allow_duplicates: bool = False, ) -> Union[VectorStore, BaseRetriever]: """ Builds the Vector Store or BaseRetriever object. @@ -75,6 +83,7 @@ class ChromaComponent(CustomComponent): - chroma_server_host (Optional[str]): The host for the Chroma server. - chroma_server_http_port (Optional[int]): The HTTP port for the Chroma server. - chroma_server_grpc_port (Optional[int]): The gRPC port for the Chroma server. + - allow_duplicates (bool): Whether to allow duplicates in the Vector Store. Returns: - Union[VectorStore, BaseRetriever]: The Vector Store or BaseRetriever object. @@ -93,35 +102,34 @@ class ChromaComponent(CustomComponent): ) client = chromadb.HttpClient(settings=chroma_settings) - # If documents, then we need to create a Chroma instance using .from_documents - # Check index_directory and expand it if it is a relative path if index_directory is not None: index_directory = self.resolve_path(index_directory) + chroma = Chroma( + persist_directory=index_directory, + client=client, + embedding_function=embedding, + collection_name=collection_name, + ) + if allow_duplicates: + stored_records = [] + else: + stored_records = chroma_collection_to_records(chroma.get()) + _stored_documents_without_id = [] + for record in deepcopy(stored_records): + del record.id + _stored_documents_without_id.append(record) documents = [] for _input in inputs or []: if isinstance(_input, Record): - documents.append(_input.to_lc_document()) + if _input not in _stored_documents_without_id: + documents.append(_input.to_lc_document()) else: - documents.append(_input) - if documents is not None and embedding is not None: - if len(documents) == 0: - raise ValueError("If documents are provided, there must be at least one document.") - chroma = Chroma.from_documents( - documents=documents, # type: ignore - persist_directory=index_directory, - collection_name=collection_name, - embedding=embedding, - client=client, - ) - else: - chroma = Chroma( - persist_directory=index_directory, - client=client, - embedding_function=embedding, - ) + raise ValueError("Inputs must be a Record objects.") - store = chroma.get() - self.status = chroma_collection_to_records(store) + if documents and embedding is not None: + chroma.add_documents(documents) + + self.status = stored_records return chroma diff --git a/src/backend/base/langflow/custom/custom_component/custom_component.py b/src/backend/base/langflow/custom/custom_component/custom_component.py index 896b07337..5c1da081b 100644 --- a/src/backend/base/langflow/custom/custom_component/custom_component.py +++ b/src/backend/base/langflow/custom/custom_component/custom_component.py @@ -126,8 +126,11 @@ class CustomComponent(Component): @staticmethod def resolve_path(path: str) -> str: """Resolves the path to an absolute path.""" + if not path: + return path path_object = Path(path) - if path_object.parts[0] == "~": + + if path_object.parts and path_object.parts[0] == "~": path_object = path_object.expanduser() elif path_object.is_relative_to("."): path_object = path_object.resolve() diff --git a/src/backend/base/langflow/field_typing/prompt.py b/src/backend/base/langflow/field_typing/prompt.py index ef6c7ce9a..029261ac7 100644 --- a/src/backend/base/langflow/field_typing/prompt.py +++ b/src/backend/base/langflow/field_typing/prompt.py @@ -25,6 +25,7 @@ class Prompt(Record): prompt_template = PromptTemplate.from_template(self.template) variables_with_str_values = dict_values_to_string(self.variables) formatted_prompt = prompt_template.format(**variables_with_str_values) + self.text = formatted_prompt return formatted_prompt @classmethod diff --git a/src/backend/base/langflow/helpers/folders.py b/src/backend/base/langflow/helpers/folders.py index fa6f27fcc..c3d7567b5 100644 --- a/src/backend/base/langflow/helpers/folders.py +++ b/src/backend/base/langflow/helpers/folders.py @@ -20,4 +20,4 @@ def generate_unique_folder_name(folder_name, user_id, session): # If a folder with the name already exists, append (n) to the name and increment n folder_name = f"{original_name} ({n})" - n += 1 \ No newline at end of file + n += 1 diff --git a/src/backend/base/langflow/schema/record.py b/src/backend/base/langflow/schema/record.py index 830f576ba..67d9b5da8 100644 --- a/src/backend/base/langflow/schema/record.py +++ b/src/backend/base/langflow/schema/record.py @@ -1,12 +1,12 @@ import copy import json -from typing import cast, Optional +from typing import Optional, cast from langchain_core.documents import Document from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, SystemMessage +from langchain_core.prompt_values import ImagePromptValue from langchain_core.prompts.image import ImagePromptTemplate from pydantic import BaseModel, model_serializer, model_validator -from langchain_core.prompt_values import ImagePromptValue class Record(BaseModel): @@ -200,3 +200,6 @@ class Record(BaseModel): def __contains__(self, key): return key in self.data + + def __eq__(self, other): + return isinstance(other, Record) and self.data == other.data diff --git a/src/frontend/.prettierignore b/src/frontend/.prettierignore index 07ed7069a..a007feab0 100644 --- a/src/frontend/.prettierignore +++ b/src/frontend/.prettierignore @@ -1 +1 @@ -build/* \ No newline at end of file +build/* diff --git a/src/frontend/package.json b/src/frontend/package.json index 63cbf6503..ab53c6e0b 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -82,7 +82,7 @@ "start": "vite", "build": "vite build", "serve": "vite preview", - "format": "npx prettier --write \"{docs,src}/**/*.{js,jsx,ts,tsx,json,md}\" --ignore-path .prettierignore", + "format": "npx prettier --write \"{tests,src}/**/*.{js,jsx,ts,tsx,json,md}\" --ignore-path .prettierignore", "type-check": "tsc --noEmit --pretty --project tsconfig.json && vite" }, "simple-git-hooks": { diff --git a/src/frontend/src/CustomNodes/GenericNode/components/outputModal/components/switchOutputView/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/outputModal/components/switchOutputView/index.tsx index 307c77c1a..437adb511 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/outputModal/components/switchOutputView/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/outputModal/components/switchOutputView/index.tsx @@ -28,7 +28,7 @@ export default function SwitchOutputView(nodeId): JSX.Element { if (resultMessage.raw) { resultMessage = resultMessage.raw; } - console.log("resultType", results); + return ( <> diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index 418d03b88..73fdd6ff8 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -82,7 +82,9 @@ export default function ParameterComponent({ const [openOutputModal, setOpenOutputModal] = useState(false); const flowPool = useFlowStore((state) => state.flowPool); - const displayOutputPreview = !!flowPool[data.id]; + const displayOutputPreview = + !!flowPool[data.id] && + flowPool[data.id][flowPool[data.id].length - 1]?.valid; const unknownOutput = !!( flowPool[data.id] && diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx index 018e99a7c..b9e939c5d 100644 --- a/src/frontend/src/CustomNodes/GenericNode/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx @@ -13,7 +13,7 @@ import { TOOLTIP_OUTDATED_NODE, } from "../../constants/constants"; import { BuildStatus } from "../../constants/enums"; -import { getSpecificClassFromBuildStatus } from "../helpers/get-class-from-build-status"; +import { postCustomComponent } from "../../controllers/API"; import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent"; import useAlertStore from "../../stores/alertStore"; import { useDarkStore } from "../../stores/darkStore"; @@ -25,6 +25,8 @@ import { NodeDataType } from "../../types/flow"; import { handleKeyDown, scapedJSONStringfy } from "../../utils/reactflowUtils"; import { nodeColors, nodeIconsLucide } from "../../utils/styleUtils"; import { classNames, cn } from "../../utils/utils"; +import { countHandlesFn } from "../helpers/count-handles"; +import { getSpecificClassFromBuildStatus } from "../helpers/get-class-from-build-status"; import useCheckCodeValidity from "../hooks/use-check-code-validity"; import useIconNodeRender from "../hooks/use-icon-render"; import useIconStatus from "../hooks/use-icons-status"; @@ -34,9 +36,7 @@ import useValidationStatusString from "../hooks/use-validation-status-string"; import getFieldTitle from "../utils/get-field-title"; import sortFields from "../utils/sort-fields"; import ParameterComponent from "./components/parameterComponent"; -import { postCustomComponent } from "../../controllers/API"; import { useShortcutsStore } from "../../stores/shortcuts"; -import { countHandlesFn } from "../helpers/count-handles"; export default function GenericNode({ data, @@ -260,6 +260,7 @@ export default function GenericNode({ openAdvancedModal={false} onCloseAdvancedModal={() => {}} selected={selected} + updateNode={handleUpdateCode} /> ); diff --git a/src/frontend/src/CustomNodes/hooks/use-icons-status.tsx b/src/frontend/src/CustomNodes/hooks/use-icons-status.tsx index ec378fac2..55936c6c9 100644 --- a/src/frontend/src/CustomNodes/hooks/use-icons-status.tsx +++ b/src/frontend/src/CustomNodes/hooks/use-icons-status.tsx @@ -4,11 +4,21 @@ import Loading from "../../components/ui/loading"; import Xmark from "../../components/ui/xmark"; import { BuildStatus } from "../../constants/enums"; import { VertexBuildTypeAPI } from "../../types/api"; +import { cn } from "../../utils/utils"; const useIconStatus = ( buildStatus: BuildStatus | undefined, validationStatus: VertexBuildTypeAPI | null, ) => { + const conditionSuccess = validationStatus && validationStatus.valid; + const conditionInactive = + validationStatus && + !validationStatus.valid && + buildStatus === BuildStatus.INACTIVE; + const conditionError = + buildStatus === BuildStatus.ERROR || + (validationStatus && !validationStatus.valid); + const renderIconStatus = () => { if (buildStatus === BuildStatus.BUILDING) { return ; @@ -17,31 +27,30 @@ const useIconStatus = ( <> - {validationStatus && validationStatus.valid ? ( + {conditionSuccess ? ( - ) : validationStatus && - !validationStatus.valid && - buildStatus === BuildStatus.INACTIVE ? ( + ) : conditionInactive ? ( - ) : buildStatus === BuildStatus.ERROR || - (validationStatus && !validationStatus.valid) ? ( + ) : conditionError ? ( ) : ( - + <> )} ); diff --git a/src/frontend/src/components/chatComponent/index.tsx b/src/frontend/src/components/chatComponent/index.tsx index 7fad5a882..5bcaade0a 100644 --- a/src/frontend/src/components/chatComponent/index.tsx +++ b/src/frontend/src/components/chatComponent/index.tsx @@ -1,6 +1,6 @@ import { Transition } from "@headlessui/react"; +import { useMemo, useRef, useState } from "react"; import { useHotkeys } from "react-hotkeys-hook"; -import { useEffect, useMemo, useRef, useState } from "react"; import IOModal from "../../modals/IOModal"; import ApiModal from "../../modals/apiModal/views"; import ShareModal from "../../modals/shareModal"; diff --git a/src/frontend/src/components/codeTabsComponent/index.tsx b/src/frontend/src/components/codeTabsComponent/index.tsx index 3b42608d1..0611de7cc 100644 --- a/src/frontend/src/components/codeTabsComponent/index.tsx +++ b/src/frontend/src/components/codeTabsComponent/index.tsx @@ -26,7 +26,6 @@ import { TabsTrigger, } from "../../components/ui/tabs"; import { LANGFLOW_SUPPORTED_TYPES } from "../../constants/constants"; -import ExportModal from "../../modals/exportModal"; import { Case } from "../../shared/components/caseComponent"; import { useDarkStore } from "../../stores/darkStore"; import useFlowStore from "../../stores/flowStore"; @@ -43,9 +42,9 @@ import IconComponent from "../genericIconComponent"; import InputComponent from "../inputComponent"; import KeypairListComponent from "../keypairListComponent"; import ShadTooltip from "../shadTooltipComponent"; +import { Button } from "../ui/button"; import { Label } from "../ui/label"; import { Switch } from "../ui/switch"; -import { Button } from "../ui/button"; export default function CodeTabsComponent({ flow, diff --git a/src/frontend/src/components/headerComponent/components/menuBar/index.tsx b/src/frontend/src/components/headerComponent/components/menuBar/index.tsx index 6405e258a..4965d37a6 100644 --- a/src/frontend/src/components/headerComponent/components/menuBar/index.tsx +++ b/src/frontend/src/components/headerComponent/components/menuBar/index.tsx @@ -16,11 +16,11 @@ import FlowSettingsModal from "../../../../modals/flowSettingsModal"; import useAlertStore from "../../../../stores/alertStore"; import useFlowStore from "../../../../stores/flowStore"; import useFlowsManagerStore from "../../../../stores/flowsManagerStore"; +import { useShortcutsStore } from "../../../../stores/shortcuts"; import { cn } from "../../../../utils/utils"; import IconComponent from "../../../genericIconComponent"; import ShadTooltip from "../../../shadTooltipComponent"; import { Button } from "../../../ui/button"; -import { useShortcutsStore } from "../../../../stores/shortcuts"; export const MenuBar = ({}: {}): JSX.Element => { const shortcuts = useShortcutsStore((state) => state.shortcuts); @@ -115,7 +115,7 @@ export const MenuBar = ({}: {}): JSX.Element => { title: UPLOAD_ERROR_ALERT, list: [error], }); - } + }, ); }} > @@ -201,7 +201,7 @@ export const MenuBar = ({}: {}): JSX.Element => { name={isBuilding || saveLoading ? "Loader2" : "CheckCircle2"} className={cn( "h-4 w-4", - isBuilding || saveLoading ? "animate-spin" : "animate-wiggle" + isBuilding || saveLoading ? "animate-spin" : "animate-wiggle", )} /> {printByBuildStatus()} diff --git a/src/frontend/src/components/headerComponent/index.tsx b/src/frontend/src/components/headerComponent/index.tsx index 979dcc88b..11a774b84 100644 --- a/src/frontend/src/components/headerComponent/index.tsx +++ b/src/frontend/src/components/headerComponent/index.tsx @@ -1,9 +1,9 @@ import { useContext } from "react"; -import profileCircle from "../../assets/profile-circle.png"; import { FaDiscord, FaGithub } from "react-icons/fa"; import { RiTwitterXFill } from "react-icons/ri"; import { Link, useLocation, useNavigate, useParams } from "react-router-dom"; import AlertDropdown from "../../alerts/alertDropDown"; +import profileCircle from "../../assets/profile-circle.png"; import { BACKEND_URL, BASE_URL_API, @@ -18,7 +18,6 @@ import useFlowStore from "../../stores/flowStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore"; import { useLocationStore } from "../../stores/locationStore"; import { useStoreStore } from "../../stores/storeStore"; -import { gradients } from "../../utils/styleUtils"; import IconComponent from "../genericIconComponent"; import { Button } from "../ui/button"; import { @@ -79,7 +78,7 @@ export default function Header(): JSX.Element { return (
-
+
⛓️ @@ -202,8 +201,9 @@ export default function Header(): JSX.Element { `${BACKEND_URL.slice( 0, BACKEND_URL.length - 1, - )}${BASE_URL_API}files/profile_pictures/${userData?.profile_image ?? "Space/046-rocket.png"}` ?? - profileCircle + )}${BASE_URL_API}files/profile_pictures/${ + userData?.profile_image ?? "Space/046-rocket.png" + }` ?? profileCircle } className="h-7 w-7 shrink-0 focus-visible:outline-0" /> @@ -219,8 +219,9 @@ export default function Header(): JSX.Element { `${BACKEND_URL.slice( 0, BACKEND_URL.length - 1, - )}${BASE_URL_API}files/profile_pictures/${userData?.profile_image}` ?? - profileCircle + )}${BASE_URL_API}files/profile_pictures/${ + userData?.profile_image + }` ?? profileCircle } className="h-5 w-5 focus-visible:outline-0 " /> diff --git a/src/frontend/src/components/inputFileComponent/index.tsx b/src/frontend/src/components/inputFileComponent/index.tsx index 1cd8b4a64..402bc8af7 100644 --- a/src/frontend/src/components/inputFileComponent/index.tsx +++ b/src/frontend/src/components/inputFileComponent/index.tsx @@ -48,12 +48,12 @@ export default function InputFileComponent({ const handleButtonClick = (): void => { // Create a file input element const input = document.createElement("input"); + document.body.appendChild(input); input.type = "file"; input.accept = fileTypes?.join(","); input.style.display = "none"; // Hidden from view input.multiple = false; // Allow only one file selection - - input.onchange = (event: Event): void => { + const onChangeFile = (event: Event): void => { setLoading(true); // Get the selected file @@ -90,6 +90,8 @@ export default function InputFileComponent({ } }; + input.addEventListener("change", onChangeFile); + // Trigger the file selection dialog input.click(); }; diff --git a/src/frontend/src/components/tableComponent/components/TableOptions/index.tsx b/src/frontend/src/components/tableComponent/components/TableOptions/index.tsx index 7ad2d11f3..dcf246fda 100644 --- a/src/frontend/src/components/tableComponent/components/TableOptions/index.tsx +++ b/src/frontend/src/components/tableComponent/components/TableOptions/index.tsx @@ -1,7 +1,7 @@ import { cn } from "../../../../utils/utils"; +import IconComponent from "../../../genericIconComponent"; import ShadTooltip from "../../../shadTooltipComponent"; import { Button } from "../../../ui/button"; -import IconComponent from "../../../genericIconComponent"; export default function TableOptions({ resetGrid, @@ -18,7 +18,7 @@ export default function TableOptions({ }): JSX.Element { return (
-
+
@@ -81,8 +84,8 @@ export default function TableOptions({ diff --git a/src/frontend/src/components/tableComponent/components/tableAutoCellRender/index.tsx b/src/frontend/src/components/tableComponent/components/tableAutoCellRender/index.tsx index 4a6020f78..903068c84 100644 --- a/src/frontend/src/components/tableComponent/components/tableAutoCellRender/index.tsx +++ b/src/frontend/src/components/tableComponent/components/tableAutoCellRender/index.tsx @@ -1,6 +1,5 @@ import { CustomCellRendererProps } from "ag-grid-react"; import { cn, isTimeStampString } from "../../../../utils/utils"; -import ArrayReader from "../../../arrayReaderComponent"; import DateReader from "../../../dateReaderComponent"; import NumberReader from "../../../numberReader"; import ObjectRender from "../../../objectRender"; diff --git a/src/frontend/src/components/tableComponent/index.tsx b/src/frontend/src/components/tableComponent/index.tsx index 84d4a6bba..917919f51 100644 --- a/src/frontend/src/components/tableComponent/index.tsx +++ b/src/frontend/src/components/tableComponent/index.tsx @@ -12,7 +12,6 @@ import { cn, toTitleCase } from "../../utils/utils"; import ForwardedIconComponent from "../genericIconComponent"; import { Alert, AlertDescription, AlertTitle } from "../ui/alert"; import TableOptions from "./components/TableOptions"; -import { useParams } from "react-router-dom"; import resetGrid from "./utils/reset-grid-columns"; interface TableComponentProps extends AgGridReactProps { @@ -21,6 +20,7 @@ interface TableComponentProps extends AgGridReactProps { alertTitle?: string; alertDescription?: string; editable?: boolean | string[]; + pagination?: boolean; onDelete?: () => void; onDuplicate?: () => void; } @@ -134,7 +134,6 @@ const TableComponent = forwardRef< }} columnDefs={colDef} ref={realRef} - pagination={true} onGridReady={onGridReady} onColumnMoved={onColumnMoved} onStateUpdated={(e) => { @@ -143,18 +142,20 @@ const TableComponent = forwardRef< } }} /> - 0} - duplicateRow={props.onDuplicate ? props.onDuplicate : undefined} - deleteRow={props.onDelete ? props.onDelete : undefined} - resetGrid={() => { - resetGrid(realRef, initialColumnDefs); - setTimeout(() => { - setColumnStateChange(false); - }, 100); - }} - /> + {props.pagination && ( + 0} + duplicateRow={props.onDuplicate ? props.onDuplicate : undefined} + deleteRow={props.onDelete ? props.onDelete : undefined} + resetGrid={() => { + resetGrid(realRef, initialColumnDefs); + setTimeout(() => { + setColumnStateChange(false); + }, 100); + }} + /> + )}
); }, diff --git a/src/frontend/src/components/ui/button.tsx b/src/frontend/src/components/ui/button.tsx index 92d6f41a9..e5dfeb1ab 100644 --- a/src/frontend/src/components/ui/button.tsx +++ b/src/frontend/src/components/ui/button.tsx @@ -5,7 +5,7 @@ import { cn } from "../../utils/utils"; import ForwardedIconComponent from "../genericIconComponent"; const buttonVariants = cva( - "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background", + "inline-flex items-center gap-2 justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background", { variants: { variant: { diff --git a/src/frontend/src/controllers/API/api.tsx b/src/frontend/src/controllers/API/api.tsx index 4070b784f..b8035e74e 100644 --- a/src/frontend/src/controllers/API/api.tsx +++ b/src/frontend/src/controllers/API/api.tsx @@ -1,4 +1,4 @@ -import axios, { Axios, AxiosError, AxiosInstance } from "axios"; +import axios, { AxiosError, AxiosInstance } from "axios"; import { useContext, useEffect } from "react"; import { Cookies } from "react-cookie"; import { renewAccessToken } from "."; diff --git a/src/frontend/src/icons/LangChain/LangChainIcon.jsx b/src/frontend/src/icons/LangChain/LangChainIcon.jsx new file mode 100644 index 000000000..aa5e98bec --- /dev/null +++ b/src/frontend/src/icons/LangChain/LangChainIcon.jsx @@ -0,0 +1,24 @@ +const SvgLangChainIcon = (props) => ( + + + + + +); +export default SvgLangChainIcon; diff --git a/src/frontend/src/icons/LangChain/index.tsx b/src/frontend/src/icons/LangChain/index.tsx new file mode 100644 index 000000000..48b8566e1 --- /dev/null +++ b/src/frontend/src/icons/LangChain/index.tsx @@ -0,0 +1,9 @@ +import React, { forwardRef } from "react"; +import SvgLangChainIcon from "./LangChainIcon"; + +export const LangChainIcon = forwardRef< + SVGSVGElement, + React.PropsWithChildren<{}> +>((props, ref) => { + return ; +}); diff --git a/src/frontend/src/icons/LangChain/langchain-icon.svg b/src/frontend/src/icons/LangChain/langchain-icon.svg new file mode 100644 index 000000000..e80068b50 --- /dev/null +++ b/src/frontend/src/icons/LangChain/langchain-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/frontend/src/index.tsx b/src/frontend/src/index.tsx index 9c828e086..006d93ff2 100644 --- a/src/frontend/src/index.tsx +++ b/src/frontend/src/index.tsx @@ -8,7 +8,6 @@ import "./style/index.css"; // @ts-ignore import "./style/applies.css"; // @ts-ignore -import { StrictMode } from "react"; import "./style/classes.css"; const root = ReactDOM.createRoot( diff --git a/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx b/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx index 7b1fba1ca..20bae05c6 100644 --- a/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx +++ b/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx @@ -254,7 +254,13 @@ export default function IOFieldView({
artifact.data, + ) ?? [] + : [flowPoolNode?.data?.artifacts] + } columnMode="union" />
diff --git a/src/frontend/src/modals/IOModal/components/SessionView/index.tsx b/src/frontend/src/modals/IOModal/components/SessionView/index.tsx index b20ed6c57..edabbe252 100644 --- a/src/frontend/src/modals/IOModal/components/SessionView/index.tsx +++ b/src/frontend/src/modals/IOModal/components/SessionView/index.tsx @@ -1,20 +1,10 @@ -import { - CellEditRequestEvent, - ColDef, - ColGroupDef, - SelectionChangedEvent, -} from "ag-grid-community"; +import { CellEditRequestEvent, SelectionChangedEvent } from "ag-grid-community"; import { useState } from "react"; import TableComponent from "../../../../components/tableComponent"; -import { Card, CardContent } from "../../../../components/ui/card"; +import useRemoveMessages from "../../../../pages/SettingsPage/pages/messagesPage/hooks/use-remove-messages"; +import useUpdateMessage from "../../../../pages/SettingsPage/pages/messagesPage/hooks/use-updateMessage"; import useAlertStore from "../../../../stores/alertStore"; import { useMessagesStore } from "../../../../stores/messagesStore"; -import useUpdateMessage from "../../../../pages/SettingsPage/pages/messagesPage/hooks/use-updateMessage"; -import useRemoveMessages from "../../../../pages/SettingsPage/pages/messagesPage/hooks/use-remove-messages"; -import HeaderMessagesComponent from "../../../../pages/SettingsPage/pages/messagesPage/components/headerMessages"; -import { Button } from "../../../../components/ui/button"; -import ForwardedIconComponent from "../../../../components/genericIconComponent"; -import { cn } from "../../../../utils/utils"; export default function SessionView({ rows }: { rows: Array }) { const columns = useMessagesStore((state) => state.columns); diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatInput/components/uploadFileButton/index.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatInput/components/uploadFileButton/index.tsx index e675794e0..17ca897ea 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/chatInput/components/uploadFileButton/index.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/chatInput/components/uploadFileButton/index.tsx @@ -18,7 +18,9 @@ const UploadFileButton = ({ /> diff --git a/src/frontend/src/pages/ProfileSettingsPage/index.tsx b/src/frontend/src/pages/ProfileSettingsPage/index.tsx index 78e328623..5cedc5841 100644 --- a/src/frontend/src/pages/ProfileSettingsPage/index.tsx +++ b/src/frontend/src/pages/ProfileSettingsPage/index.tsx @@ -2,7 +2,6 @@ import * as Form from "@radix-ui/react-form"; import { cloneDeep } from "lodash"; import { useContext, useEffect, useState } from "react"; import IconComponent from "../../components/genericIconComponent"; -import GradientChooserComponent from "../SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent"; import Header from "../../components/headerComponent"; import InputComponent from "../../components/inputComponent"; import { Button } from "../../components/ui/button"; @@ -22,6 +21,7 @@ import { patchUserInputStateType, } from "../../types/components"; import { gradients } from "../../utils/styleUtils"; +import GradientChooserComponent from "../SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent"; export default function ProfileSettingsPage(): JSX.Element { const setCurrentFlowId = useFlowsManagerStore( (state) => state.setCurrentFlowId, diff --git a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/components/ApiKeyHeader/index.tsx b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/components/ApiKeyHeader/index.tsx index 45a606af6..4138d621f 100644 --- a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/components/ApiKeyHeader/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/components/ApiKeyHeader/index.tsx @@ -2,7 +2,6 @@ import ForwardedIconComponent from "../../../../../../components/genericIconComp import { Button } from "../../../../../../components/ui/button"; import { API_PAGE_PARAGRAPH } from "../../../../../../constants/constants"; import SecretKeyModal from "../../../../../../modals/secretKeyModal"; -import { cn } from "../../../../../../utils/utils"; type ApiKeyHeaderComponentProps = { selectedRows: string[]; diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-get-profile-pictures.ts b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-get-profile-pictures.ts index 2997a4b2f..684fd5e38 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-get-profile-pictures.ts +++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-get-profile-pictures.ts @@ -1,7 +1,6 @@ -import { reject } from "lodash"; +import axios from "axios"; import { PROFILE_PICTURES_GET_ERROR_ALERT } from "../../../../../../../../../constants/alerts_constants"; import { getProfilePictures } from "../../../../../../../../../controllers/API"; -import axios from "axios"; const useGetProfilePictures = (setErrorData) => { const handleGetProfilePictures = async () => { diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/index.tsx index a841ecc5e..908cea255 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/index.tsx @@ -1,4 +1,5 @@ import * as Form from "@radix-ui/react-form"; +import { useEffect, useState } from "react"; import { Button } from "../../../../../../components/ui/button"; import { Card, @@ -10,8 +11,6 @@ import { } from "../../../../../../components/ui/card"; import { gradients } from "../../../../../../utils/styleUtils"; import ProfilePictureChooserComponent from "./components/profilePictureChooserComponent"; -import { useEffect, useState } from "react"; -import { GenericAbortSignal } from "axios"; type ProfilePictureFormComponentProps = { profilePicture: string; diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/index.tsx index 3c81bdb1c..239103777 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/index.tsx @@ -9,15 +9,15 @@ import { inputHandlerEventType, patchUserInputStateType, } from "../../../../types/components"; -import usePatchProfilePicture from "../hooks/use-patch-profile-picture"; import usePatchPassword from "../hooks/use-patch-password"; +import usePatchProfilePicture from "../hooks/use-patch-profile-picture"; import useSaveKey from "../hooks/use-save-key"; import useScrollToElement from "../hooks/use-scroll-to-element"; import GeneralPageHeaderComponent from "./components/GeneralPageHeader"; import PasswordFormComponent from "./components/PasswordForm"; import ProfilePictureFormComponent from "./components/ProfilePictureForm"; -import StoreApiKeyFormComponent from "./components/StoreApiKeyForm"; import useGetProfilePictures from "./components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-get-profile-pictures"; +import StoreApiKeyFormComponent from "./components/StoreApiKeyForm"; export default function GeneralPage() { const setCurrentFlowId = useFlowsManagerStore( diff --git a/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx index 990312739..131f7f46e 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx @@ -11,7 +11,6 @@ import { Badge } from "../../../../components/ui/badge"; import { deleteGlobalVariable } from "../../../../controllers/API"; import useAlertStore from "../../../../stores/alertStore"; import { useGlobalVariablesStore } from "../../../../stores/globalVariablesStore/globalVariables"; -import { cn } from "../../../../utils/utils"; export default function GlobalVariablesPage() { const globalVariablesEntries = useGlobalVariablesStore( diff --git a/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/EditShortcutButton/index.tsx b/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/EditShortcutButton/index.tsx index 652a3c8db..e2e49e815 100644 --- a/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/EditShortcutButton/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/EditShortcutButton/index.tsx @@ -107,7 +107,9 @@ export default function EditShortcutButton({ if (oldKey === null) { return `${key.length > 0 ? toTitleCase(key) : toTitleCase(key)}`; } - return `${oldKey.length > 0 ? toTitleCase(oldKey) : oldKey.toUpperCase()} + ${key.length > 0 ? toTitleCase(key) : key.toUpperCase()}`; + return `${ + oldKey.length > 0 ? toTitleCase(oldKey) : oldKey.toUpperCase() + } + ${key.length > 0 ? toTitleCase(key) : key.toUpperCase()}`; } function checkForKeys(keys: string, keyToCompare: string): boolean { diff --git a/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/index.tsx b/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/index.tsx index 9a6b4ea8f..5e1228c7d 100644 --- a/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/index.tsx @@ -1,4 +1,3 @@ -import { ColDef, ColGroupDef, SelectionChangedEvent } from "ag-grid-community"; import { useEffect, useState } from "react"; import ForwardedIconComponent from "../../../../components/genericIconComponent"; import TableComponent from "../../../../components/tableComponent"; diff --git a/src/frontend/src/pages/SettingsPage/pages/messagesPage/components/headerMessages/index.tsx b/src/frontend/src/pages/SettingsPage/pages/messagesPage/components/headerMessages/index.tsx index 20f44427a..505adc872 100644 --- a/src/frontend/src/pages/SettingsPage/pages/messagesPage/components/headerMessages/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/messagesPage/components/headerMessages/index.tsx @@ -1,6 +1,4 @@ import ForwardedIconComponent from "../../../../../../components/genericIconComponent"; -import { Button } from "../../../../../../components/ui/button"; -import { cn } from "../../../../../../utils/utils"; type HeaderMessagesComponentProps = { selectedRows: number[]; diff --git a/src/frontend/src/stores/foldersStore.tsx b/src/frontend/src/stores/foldersStore.tsx index 4d5f4a850..e72610987 100644 --- a/src/frontend/src/stores/foldersStore.tsx +++ b/src/frontend/src/stores/foldersStore.tsx @@ -7,7 +7,6 @@ import { } from "../pages/MainPage/services"; import { FoldersStoreType } from "../types/zustand/folders"; import useFlowsManagerStore from "./flowsManagerStore"; -import { uploadFlowsToDatabase } from "../controllers/API"; export const useFolderStore = create((set, get) => ({ folders: [], diff --git a/src/frontend/src/stores/shortcuts.ts b/src/frontend/src/stores/shortcuts.ts index c0b271849..d792a0d6c 100644 --- a/src/frontend/src/stores/shortcuts.ts +++ b/src/frontend/src/stores/shortcuts.ts @@ -23,7 +23,7 @@ export const useShortcutsStore = create((set, get) => ({ group: "mod+g", cut: "mod+x", paste: "mod+v", - api: "mod+r", + api: "mod+shift+r", update: "mod+u", download: "mod+j", freeze: "mod+f", diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index 8d1fef5d1..3cae3f838 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -491,7 +491,7 @@ export type ChatInputType = { isDragging: boolean; files: FilePreviewType[]; setFiles: ( - files: FilePreviewType[] | ((prev: FilePreviewType[]) => FilePreviewType[]) + files: FilePreviewType[] | ((prev: FilePreviewType[]) => FilePreviewType[]), ) => void; chatValue: string; inputRef: { @@ -547,6 +547,7 @@ export type nodeToolbarPropsType = { onCloseAdvancedModal?: (close: boolean) => void; selected: boolean; setShowState: (show: boolean | SetStateAction) => void; + updateNode: () => void; }; export type parsedDataType = { @@ -593,7 +594,7 @@ export type chatMessagePropsType = { updateChat: ( chat: ChatMessageType, message: string, - stream_url?: string + stream_url?: string, ) => void; }; @@ -685,12 +686,12 @@ export type codeTabsPropsType = { value: string, node: NodeType, template: TemplateVariableType, - tweak: tweakType + tweak: tweakType, ) => string; buildTweakObject?: ( tw: string, changes: string | string[] | boolean | number | Object[] | Object, - template: TemplateVariableType + template: TemplateVariableType, ) => Promise; }; activeTweaks?: boolean; diff --git a/src/frontend/src/utils/styleUtils.ts b/src/frontend/src/utils/styleUtils.ts index 123702b60..9a65e4f27 100644 --- a/src/frontend/src/utils/styleUtils.ts +++ b/src/frontend/src/utils/styleUtils.ts @@ -1,5 +1,6 @@ import { AlertCircle, + AlertTriangle, ArrowBigUp, ArrowLeft, ArrowUpToLine, @@ -116,7 +117,6 @@ import { Settings, Settings2, Share, - AlertTriangle, Share2, Shield, Sliders, @@ -146,11 +146,10 @@ import { Variable, Wand2, Workflow, + Wrench, X, XCircle, Zap, - PlaySquare, - Wrench, } from "lucide-react"; import { FaApple, FaDiscord, FaGithub } from "react-icons/fa"; import { AWSIcon } from "../icons/AWS"; @@ -177,6 +176,7 @@ import { import { GroqIcon } from "../icons/Groq"; import { HuggingFaceIcon } from "../icons/HuggingFace"; import { IFixIcon } from "../icons/IFixIt"; +import { LangChainIcon } from "../icons/LangChain"; import { MetaIcon } from "../icons/Meta"; import { MidjourneyIcon } from "../icons/Midjorney"; import { MongoDBIcon } from "../icons/MongoDB"; @@ -325,6 +325,7 @@ export const nodeIconsLucide: iconsType = { ChatOllamaModel: OllamaIcon, Faiss: MetaIcon, FaissSearch: MetaIcon, + LangChain: LangChainIcon, AzureOpenAiModel: AzureIcon, Redis: RedisIcon, RedisSearch: RedisIcon, diff --git a/src/frontend/src/utils/utils.ts b/src/frontend/src/utils/utils.ts index db1bdfdf1..5d99927a5 100644 --- a/src/frontend/src/utils/utils.ts +++ b/src/frontend/src/utils/utils.ts @@ -1,6 +1,8 @@ import { ColDef, ColGroupDef } from "ag-grid-community"; import clsx, { ClassValue } from "clsx"; import { twMerge } from "tailwind-merge"; +import TableAutoCellRender from "../components/tableComponent/components/tableAutoCellRender"; +import { MODAL_CLASSES } from "../constants/constants"; import { APIDataType, TemplateVariableType } from "../types/api"; import { groupedObjType, @@ -9,8 +11,6 @@ import { } from "../types/components"; import { NodeType } from "../types/flow"; import { FlowState } from "../types/tabs"; -import TableAutoCellRender from "../components/tableComponent/components/tableAutoCellRender"; -import { MODAL_CLASSES } from "../constants/constants"; export function classNames(...classes: Array): string { return classes.filter(Boolean).join(" "); diff --git a/src/frontend/tailwind.config.js b/src/frontend/tailwind.config.js index fd5acab36..a97e4cec0 100644 --- a/src/frontend/tailwind.config.js +++ b/src/frontend/tailwind.config.js @@ -236,6 +236,10 @@ module.exports = { ".text-align-last-right": { "text-align-last": "right", }, + ":focus-visible": { + outline: "none !important", + outlineOffset: "0px !important", + }, }); }), require("@tailwindcss/typography"), diff --git a/src/frontend/tests/end-to-end/assets/ChatTest.json b/src/frontend/tests/end-to-end/assets/ChatTest.json index cadb3fe12..045d0cddf 100644 --- a/src/frontend/tests/end-to-end/assets/ChatTest.json +++ b/src/frontend/tests/end-to-end/assets/ChatTest.json @@ -44,9 +44,7 @@ "name": "input_value", "display_name": "Message", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -70,9 +68,7 @@ "info": "In case of Message being a Record, this template will be used to convert it to text.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "return_record": { "type": "bool", @@ -104,10 +100,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -115,9 +108,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -137,9 +128,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -158,20 +147,13 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Display a chat message in the Playground.", "icon": "ChatOutput", - "base_classes": [ - "object", - "Record", - "str", - "Text" - ], + "base_classes": ["object", "Record", "str", "Text"], "display_name": "Chat Output", "documentation": "", "custom_fields": { @@ -182,10 +164,7 @@ "return_record": null, "record_template": null }, - "output_types": [ - "Text", - "Record" - ], + "output_types": ["Text", "Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -280,10 +259,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -291,9 +267,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -313,9 +287,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -334,20 +306,13 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Get chat inputs from the Playground.", "icon": "ChatInput", - "base_classes": [ - "object", - "Record", - "str", - "Text" - ], + "base_classes": ["object", "Record", "str", "Text"], "display_name": "Chat Input", "documentation": "", "custom_fields": { @@ -357,10 +322,7 @@ "session_id": null, "return_record": null }, - "output_types": [ - "Text", - "Record" - ], + "output_types": ["Text", "Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -383,18 +345,11 @@ "targetHandle": { "fieldName": "input_value", "id": "ChatOutput-xPeM1", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "Record", - "str", - "Text" - ], + "baseClasses": ["object", "Record", "str", "Text"], "dataType": "ChatInput", "id": "ChatInput-XYvUc" } @@ -416,4 +371,4 @@ "name": "ChatTest", "last_tested_version": "1.0.0a14", "is_component": false -} \ No newline at end of file +}