Skip to content

Commit

Permalink
Fixes Duplicated CustomComponents, CTRL+Backspace and other fixes (#767)
Browse files Browse the repository at this point in the history
  • Loading branch information
ogabrielluiz committed Aug 15, 2023
2 parents 823b140 + 5a49015 commit ea3aef3
Show file tree
Hide file tree
Showing 19 changed files with 256 additions and 168 deletions.
229 changes: 108 additions & 121 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "langflow"
version = "0.4.8"
version = "0.4.9"
description = "A Python package with a built-in web application"
authors = ["Logspace <[email protected]>"]
maintainers = [
Expand Down
16 changes: 12 additions & 4 deletions src/backend/langflow/api/v1/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,18 @@ def get_all():
custom_components_from_file = {}
if settings.COMPONENTS_PATH:
logger.info(f"Building custom components from {settings.COMPONENTS_PATH}")
custom_component_dicts = [
build_langchain_custom_component_list_from_path(str(path))
for path in settings.COMPONENTS_PATH
]

custom_component_dicts = []
processed_paths = []
for path in settings.COMPONENTS_PATH:
if str(path) in processed_paths:
continue
custom_component_dict = build_langchain_custom_component_list_from_path(
str(path)
)
custom_component_dicts.append(custom_component_dict)
processed_paths.append(str(path))

logger.info(f"Loading {len(custom_component_dicts)} category(ies)")
for custom_component_dict in custom_component_dicts:
# custom_component_dict is a dict of dicts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


class ConversationalAgent(CustomComponent):
display_name: str = "OpenaAI Conversational Agent"
display_name: str = "OpenAI Conversational Agent"
description: str = "Conversational Agent that can use OpenAI's function calling API"

def build_config(self):
Expand All @@ -41,12 +41,18 @@ def build_config(self):
def build(
self,
model_name: str,
openai_api_key: str,
openai_api_base: str,
tools: Tool,
memory: Optional[BaseMemory] = None,
system_message: Optional[SystemMessagePromptTemplate] = None,
max_token_limit: int = 2000,
) -> AgentExecutor:
llm = ChatOpenAI(model=model_name)
llm = ChatOpenAI(
model=model_name,
openai_api_key=openai_api_key,
openai_api_base=openai_api_base,
)
if not memory:
memory_key = "chat_history"
memory = ConversationTokenBufferMemory(
Expand Down
7 changes: 6 additions & 1 deletion src/backend/langflow/graph/vertex/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,12 @@ def _built_object_repr(self):
# so the prompt format doesn't break
artifacts.pop("handle_keys", None)
try:
template = self._built_object.template
if not hasattr(self._built_object, "template") and hasattr(
self._built_object, "prompt"
):
template = self._built_object.prompt.template
else:
template = self._built_object.template
for key, value in artifacts.items():
if value:
replace_key = "{" + key + "}"
Expand Down
4 changes: 3 additions & 1 deletion src/backend/langflow/interface/initialize/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ def handle_partial_variables(prompt, format_kwargs: Dict):
}
# Remove handle_keys otherwise LangChain raises an error
partial_variables.pop("handle_keys", None)
return prompt.partial(**partial_variables)
if partial_variables and hasattr(prompt, "partial"):
return prompt.partial(**partial_variables)
return prompt


def handle_variable(params: Dict, input_variable: str, format_kwargs: Dict):
Expand Down
9 changes: 7 additions & 2 deletions src/backend/langflow/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,17 @@ def update_settings(self, **kwargs):
value = json.loads(str(value))
if isinstance(value, list):
for item in value:
if isinstance(item, Path):
item = str(item)
if item not in getattr(self, key):
getattr(self, key).append(item)
logger.debug(f"Extended {key}")
else:
getattr(self, key).append(value)
logger.debug(f"Appended {key}")
if isinstance(value, Path):
value = str(value)
if value not in getattr(self, key):
getattr(self, key).append(value)
logger.debug(f"Appended {key}")

else:
setattr(self, key, value)
Expand Down
8 changes: 8 additions & 0 deletions src/frontend/src/components/AccordionComponent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,21 @@ export default function AccordionComponent({
value === "" ? setValue(keyValue) : setValue("");
}

const handleKeyDown = (event) => {
if (event.key === "Backspace") {
event.preventDefault();
event.stopPropagation();
}
};

return (
<>
<Accordion
type="single"
className="w-full"
value={value}
onValueChange={setValue}
onKeyDown={handleKeyDown}
>
<AccordionItem value={keyValue} className="border-b">
<AccordionTrigger
Expand Down
32 changes: 20 additions & 12 deletions src/frontend/src/components/EditFlowSettingsComponent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ type InputProps = {
maxLength?: number;
flows: Array<{ id: string; name: string; description: string }>;
tabId: string;
invalidName: boolean;
setInvalidName: (invalidName: boolean) => void;
invalidName?: boolean;
setInvalidName?: (invalidName: boolean) => void;
setName: (name: string) => void;
setDescription: (description: string) => void;
updateFlow: (flow: { id: string; name: string }) => void;
Expand Down Expand Up @@ -46,21 +46,29 @@ export const EditFlowSettings: React.FC<InputProps> = ({
} else {
setIsMaxLength(false);
}
if (!nameLists.current.includes(value)) {
setInvalidName(false);
} else {
setInvalidName(true);
if (invalidName !== undefined) {
if (!nameLists.current.includes(value)) {
setInvalidName(false);
} else {
setInvalidName(true);
}
}
setName(value);
setCurrentName(value);
};

const [desc, setDesc] = useState(
flows.find((f) => f.id === tabId).description
);
const [currentName, setCurrentName] = useState(name);

const [currentDescription, setCurrentDescription] = useState(description);

useEffect(() => {
setCurrentName(name);
setCurrentDescription(description);
}, [name, description]);

const handleDescriptionChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
flows.find((f) => f.id === tabId).description = event.target.value;
setDesc(flows.find((f) => f.id === tabId).description);
setCurrentDescription(flows.find((f) => f.id === tabId).description);
setDescription(event.target.value);
};

Expand All @@ -81,7 +89,7 @@ export const EditFlowSettings: React.FC<InputProps> = ({
onChange={handleNameChange}
type="text"
name="name"
value={name ?? ""}
value={currentName ?? ""}
placeholder="File name"
id="name"
maxLength={maxLength}
Expand All @@ -96,7 +104,7 @@ export const EditFlowSettings: React.FC<InputProps> = ({
name="description"
id="description"
onChange={handleDescriptionChange}
value={desc}
value={currentDescription}
placeholder="Flow description"
className="mt-2 max-h-[100px] font-normal"
rows={3}
Expand Down
4 changes: 4 additions & 0 deletions src/frontend/src/components/floatComponent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect } from "react";
import { FloatComponentType } from "../../types/components";
import { handleKeyDown } from "../../utils/reactflowUtils";
import { Input } from "../ui/input";

export default function FloatComponent({
Expand Down Expand Up @@ -43,6 +44,9 @@ export default function FloatComponent({
onChange={(e) => {
onChange(e.target.value);
}}
onKeyDown={(e) => {
handleKeyDown(e, value, "0");
}}
/>
</div>
);
Expand Down
4 changes: 4 additions & 0 deletions src/frontend/src/components/inputComponent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useState } from "react";
import { InputComponentType } from "../../types/components";
import { handleKeyDown } from "../../utils/reactflowUtils";
import { classNames } from "../../utils/utils";
import { Input } from "../ui/input";

Expand Down Expand Up @@ -34,6 +35,9 @@ export default function InputComponent({
onChange={(e) => {
onChange(e.target.value);
}}
onKeyDown={(e) => {
handleKeyDown(e, value, "");
}}
/>
{password && (
<button
Expand Down
6 changes: 6 additions & 0 deletions src/frontend/src/components/inputListComponent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ export default function InputListComponent({
newInputList[idx] = e.target.value;
onChange(newInputList);
}}
onKeyDown={(e) => {
if (e.ctrlKey && e.key === "Backspace") {
e.preventDefault();
e.stopPropagation();
}
}}
/>
{idx === value.length - 1 ? (
<button
Expand Down
2 changes: 2 additions & 0 deletions src/frontend/src/components/intComponent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect } from "react";
import { FloatComponentType } from "../../types/components";
import { handleKeyDown } from "../../utils/reactflowUtils";
import { Input } from "../ui/input";

export default function IntComponent({
Expand Down Expand Up @@ -37,6 +38,7 @@ export default function IntComponent({
) {
event.preventDefault();
}
handleKeyDown(event, value, "0");
}}
type="number"
step="1"
Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const INVALID_CHARACTERS = [
*/

export const regexHighlight = /\{([^}]+)\}/g;
export const specialCharsRegex = /[!@#$%^&*()\-_=+[\]{}|;:'",.<>/?\\`´]/;

export const programmingLanguages: languageMap = {
javascript: ".js",
Expand Down
17 changes: 10 additions & 7 deletions src/frontend/src/modals/exportModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode, forwardRef, useContext, useState } from "react";
import { ReactNode, forwardRef, useContext, useEffect, useState } from "react";
import EditFlowSettings from "../../components/EditFlowSettingsComponent";
import IconComponent from "../../components/genericIconComponent";
import { Button } from "../../components/ui/button";
Expand All @@ -9,14 +9,17 @@ import { removeApiKeys } from "../../utils/reactflowUtils";
import BaseModal from "../baseModal";

const ExportModal = forwardRef((props: { children: ReactNode }, ref) => {
const { flows, tabId, updateFlow, downloadFlow, saveFlow } =
useContext(TabsContext);
const { flows, tabId, updateFlow, downloadFlow } = useContext(TabsContext);
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
);
const flow = flows.find((f) => f.id === tabId);
useEffect(() => {
setName(flow.name);
setDescription(flow.description);
}, [flow.name, flow.description]);
const [name, setName] = useState(flow.name);
const [description, setDescription] = useState(flow.description);
const [open, setOpen] = useState(false);

return (
<BaseModal size="smaller" open={open} setOpen={setOpen}>
<BaseModal.Trigger>{props.children}</BaseModal.Trigger>
Expand Down
20 changes: 10 additions & 10 deletions src/frontend/src/modals/flowSettingsModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useContext, useRef, useState } from "react";
import { useContext, useEffect, useState } from "react";
import EditFlowSettings from "../../components/EditFlowSettingsComponent";
import IconComponent from "../../components/genericIconComponent";
import { Button } from "../../components/ui/button";
Expand All @@ -14,15 +14,15 @@ export default function FlowSettingsModal({
open: boolean;
setOpen: (open: boolean) => void;
}) {
const { setErrorData, setSuccessData } = useContext(alertContext);
const ref = useRef();
const { flows, tabId, updateFlow, setTabsState, saveFlow } =
useContext(TabsContext);
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
);
const { setSuccessData } = useContext(alertContext);
const { flows, tabId, updateFlow, saveFlow } = useContext(TabsContext);
const flow = flows.find((f) => f.id === tabId);
useEffect(() => {
setName(flow.name);
setDescription(flow.description);
}, [flow.name, flow.description]);
const [name, setName] = useState(flow.name);
const [description, setDescription] = useState(flow.description);
const [invalidName, setInvalidName] = useState(false);

function handleClick() {
Expand Down
7 changes: 7 additions & 0 deletions src/frontend/src/modals/genericModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { TypeModal } from "../../constants/enums";
import { alertContext } from "../../contexts/alertContext";
import { postValidatePrompt } from "../../controllers/API";
import { APIClassType } from "../../types/api";
import { handleKeyDown } from "../../utils/reactflowUtils";
import {
classNames,
getRandomKeyByssmm,
Expand Down Expand Up @@ -213,6 +214,9 @@ export default function GenericModal({
checkVariables(e.target.value);
}}
placeholder="Type message here."
onKeyDown={(e) => {
handleKeyDown(e, inputValue, "");
}}
/>
) : type === TypeModal.PROMPT && !isEdit ? (
<TextAreaContentView />
Expand All @@ -225,6 +229,9 @@ export default function GenericModal({
setInputValue(e.target.value);
}}
placeholder="Type message here."
onKeyDown={(e) => {
handleKeyDown(e, value, "");
}}
/>
) : (
<></>
Expand Down
Loading

0 comments on commit ea3aef3

Please sign in to comment.