Merge dev into types_refactor
This commit is contained in:
commit
33ea356eba
31 changed files with 326 additions and 590 deletions
529
poetry.lock
generated
529
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -12,7 +12,7 @@ import IntComponent from "../../../../components/intComponent";
|
|||
import PromptAreaComponent from "../../../../components/promptComponent";
|
||||
import TextAreaComponent from "../../../../components/textAreaComponent";
|
||||
import ToggleShadComponent from "../../../../components/toggleShadComponent";
|
||||
import { MAX_LENGTH_TO_SCROLL_TOOLTIP } from "../../../../constants";
|
||||
import { MAX_LENGTH_TO_SCROLL_TOOLTIP } from "../../../../constants/constants";
|
||||
import { PopUpContext } from "../../../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../../../contexts/tabsContext";
|
||||
import { typesContext } from "../../../../contexts/typesContext";
|
||||
|
|
@ -54,6 +54,7 @@ export default function ParameterComponent({
|
|||
const { closePopUp } = useContext(PopUpContext);
|
||||
const { setTabsState, tabId, save } = useContext(TabsContext);
|
||||
|
||||
// Update component position
|
||||
useEffect(() => {
|
||||
if (ref.current && ref.current.offsetTop && ref.current.clientHeight) {
|
||||
setPosition(ref.current.offsetTop + ref.current.clientHeight / 2);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
CHAT_CANNOT_OPEN_TITLE,
|
||||
FLOW_NOT_BUILT_DESCRIPTION,
|
||||
FLOW_NOT_BUILT_TITLE,
|
||||
} from "../../../constants";
|
||||
} from "../../../constants/constants";
|
||||
import { alertContext } from "../../../contexts/alertContext";
|
||||
import IconComponent from "../../genericIconComponent";
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ export default function FloatComponent({
|
|||
const min = 0;
|
||||
const max = 1;
|
||||
|
||||
// Clear component state
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setMyValue("");
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { useContext, useEffect, useState } from "react";
|
|||
import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa";
|
||||
import { Link, useLocation, useParams } from "react-router-dom";
|
||||
import AlertDropdown from "../../alerts/alertDropDown";
|
||||
import { USER_PROJECTS_HEADER } from "../../constants";
|
||||
import { USER_PROJECTS_HEADER } from "../../constants/constants";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { darkContext } from "../../contexts/darkContext";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
|
|
@ -27,6 +27,7 @@ export default function Header() {
|
|||
|
||||
const [stars, setStars] = useState(null);
|
||||
|
||||
// Get and set numbers of stars on header
|
||||
useEffect(() => {
|
||||
async function fetchStars() {
|
||||
const starsCount = await getRepoStars("logspace-ai", "langflow");
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export default function InputComponent({
|
|||
const { setDisableCopyPaste } = useContext(TabsContext);
|
||||
const { closePopUp } = useContext(PopUpContext);
|
||||
|
||||
// Clear component state
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setMyValue("");
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ export default function InputFileComponent({
|
|||
const [loading, setLoading] = useState(false);
|
||||
const { setErrorData } = useContext(alertContext);
|
||||
const { tabId } = useContext(TabsContext);
|
||||
|
||||
// Clear component state
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setMyValue("");
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ export default function IntComponent({
|
|||
const min = 0;
|
||||
const { closePopUp } = useContext(PopUpContext);
|
||||
|
||||
// Clear component state
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setMyValue("");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useContext, useEffect, useState } from "react";
|
||||
|
||||
import { TypeModal } from "../../constants";
|
||||
import { TypeModal } from "../../constants/enums";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import { postValidatePrompt } from "../../controllers/API";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useContext, useEffect, useState } from "react";
|
||||
import { TypeModal } from "../../constants";
|
||||
import { TypeModal } from "../../constants/enums";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import GenericModal from "../../modals/genericModal";
|
||||
|
|
@ -16,6 +16,7 @@ export default function TextAreaComponent({
|
|||
const { openPopUp, closePopUp } = useContext(PopUpContext);
|
||||
const { setDisableCopyPaste } = useContext(TabsContext);
|
||||
|
||||
// Clear text area
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setMyValue("");
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ export default function ToggleComponent({
|
|||
setEnabled,
|
||||
disabled,
|
||||
}: ToggleComponentType) {
|
||||
|
||||
// set component state as disabled
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setEnabled(false);
|
||||
|
|
|
|||
|
|
@ -1,19 +1,7 @@
|
|||
// src/constants.tsx
|
||||
// src/constants/constants.ts
|
||||
|
||||
import { MessageSquare } from "lucide-react";
|
||||
import { IVarHighlightType } from "./types/components";
|
||||
import { FlowType } from "./types/flow";
|
||||
import { TabsState } from "./types/tabs";
|
||||
import { buildTweaks } from "./utils/reactflowUtils";
|
||||
import { buildInputs } from "./utils/utils";
|
||||
import { languageMap } from "../types/components";
|
||||
|
||||
/**
|
||||
* constants fpr programming languages box on chat form
|
||||
* @constant
|
||||
*/
|
||||
interface languageMap {
|
||||
[key: string]: string | undefined;
|
||||
}
|
||||
/**
|
||||
* invalid characters for flow name
|
||||
* @constant
|
||||
|
|
@ -42,11 +30,6 @@ export const INVALID_CHARACTERS = [
|
|||
|
||||
export const regexHighlight = /\{([^}]+)\}/g;
|
||||
|
||||
export const varHighlightHTML = ({ name }: IVarHighlightType) => {
|
||||
const html = `<span class="font-semibold chat-message-highlight">{${name}}</span>`;
|
||||
return html;
|
||||
};
|
||||
|
||||
export const programmingLanguages: languageMap = {
|
||||
javascript: ".js",
|
||||
python: ".py",
|
||||
|
|
@ -73,15 +56,6 @@ export const programmingLanguages: languageMap = {
|
|||
css: ".css",
|
||||
// add more file extensions here, make sure the key is same as language prop in CodeBlock.tsx component
|
||||
};
|
||||
|
||||
/**
|
||||
* enum for the different types of nodes
|
||||
* @enum
|
||||
*/
|
||||
export enum TypeModal {
|
||||
TEXT = 1,
|
||||
PROMPT = 2,
|
||||
}
|
||||
/**
|
||||
* Number maximum of components to scroll on tooltips
|
||||
* @constant
|
||||
|
|
@ -153,8 +127,6 @@ export const CHAT_CANNOT_OPEN_DESCRIPTION = "This is not a chat flow.";
|
|||
|
||||
export const FLOW_NOT_BUILT_TITLE = "Flow not built";
|
||||
|
||||
export const THOUGHTS_ICON = MessageSquare;
|
||||
|
||||
export const FLOW_NOT_BUILT_DESCRIPTION =
|
||||
"Please build the flow before chatting.";
|
||||
|
||||
|
|
@ -164,127 +136,6 @@ export const FLOW_NOT_BUILT_DESCRIPTION =
|
|||
*/
|
||||
export const TEXT_DIALOG_SUBTITLE = "Edit your text.";
|
||||
|
||||
/**
|
||||
* Function to get the python code for the API
|
||||
* @param {string} flowId - The id of the flow
|
||||
* @returns {string} - The python code
|
||||
*/
|
||||
export const getPythonApiCode = (
|
||||
flow: FlowType,
|
||||
tweak?: any[],
|
||||
tabsState?: TabsState
|
||||
): string => {
|
||||
const flowId = flow.id;
|
||||
|
||||
// create a dictionary of node ids and the values is an empty dictionary
|
||||
// flow.data.nodes.forEach((node) => {
|
||||
// node.data.id
|
||||
// }
|
||||
const tweaks = buildTweaks(flow);
|
||||
const inputs = buildInputs(tabsState, flow.id);
|
||||
return `import requests
|
||||
from typing import Optional
|
||||
|
||||
BASE_API_URL = "${window.location.protocol}//${
|
||||
window.location.host
|
||||
}/api/v1/process"
|
||||
FLOW_ID = "${flowId}"
|
||||
# You can tweak the flow by adding a tweaks dictionary
|
||||
# e.g {"OpenAI-XXXXX": {"model_name": "gpt-4"}}
|
||||
TWEAKS = ${
|
||||
tweak && tweak.length > 0
|
||||
? buildTweakObject(tweak)
|
||||
: JSON.stringify(tweaks, null, 2)
|
||||
}
|
||||
|
||||
def run_flow(inputs: dict, flow_id: str, tweaks: Optional[dict] = None) -> dict:
|
||||
"""
|
||||
Run a flow with a given message and optional tweaks.
|
||||
|
||||
:param message: The message to send to the flow
|
||||
:param flow_id: The ID of the flow to run
|
||||
:param tweaks: Optional tweaks to customize the flow
|
||||
:return: The JSON response from the flow
|
||||
"""
|
||||
api_url = f"{BASE_API_URL}/{flow_id}"
|
||||
|
||||
payload = {"inputs": inputs}
|
||||
|
||||
if tweaks:
|
||||
payload["tweaks"] = tweaks
|
||||
|
||||
response = requests.post(api_url, json=payload)
|
||||
return response.json()
|
||||
|
||||
# Setup any tweaks you want to apply to the flow
|
||||
inputs = ${inputs}
|
||||
print(run_flow(inputs, flow_id=FLOW_ID, tweaks=TWEAKS))`;
|
||||
};
|
||||
/**
|
||||
* Function to get the curl code for the API
|
||||
* @param {string} flowId - The id of the flow
|
||||
* @returns {string} - The curl code
|
||||
*/
|
||||
export const getCurlCode = (
|
||||
flow: FlowType,
|
||||
tweak?: any[],
|
||||
tabsState?: TabsState
|
||||
): string => {
|
||||
const flowId = flow.id;
|
||||
const tweaks = buildTweaks(flow);
|
||||
const inputs = buildInputs(tabsState, flow.id);
|
||||
|
||||
return `curl -X POST \\
|
||||
${window.location.protocol}//${
|
||||
window.location.host
|
||||
}/api/v1/process/${flowId} \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '{"inputs": ${inputs}, "tweaks": ${
|
||||
tweak && tweak.length > 0
|
||||
? buildTweakObject(tweak)
|
||||
: JSON.stringify(tweaks, null, 2)
|
||||
}}'`;
|
||||
};
|
||||
/**
|
||||
* Function to get the python code for the API
|
||||
* @param {string} flowName - The name of the flow
|
||||
* @returns {string} - The python code
|
||||
*/
|
||||
export const getPythonCode = (
|
||||
flow: FlowType,
|
||||
tweak?: any[],
|
||||
tabsState?: TabsState
|
||||
): string => {
|
||||
const flowName = flow.name;
|
||||
const tweaks = buildTweaks(flow);
|
||||
const inputs = buildInputs(tabsState, flow.id);
|
||||
return `from langflow import load_flow_from_json
|
||||
TWEAKS = ${
|
||||
tweak && tweak.length > 0
|
||||
? buildTweakObject(tweak)
|
||||
: JSON.stringify(tweaks, null, 2)
|
||||
}
|
||||
flow = load_flow_from_json("${flowName}.json", tweaks=TWEAKS)
|
||||
# Now you can use it like any chain
|
||||
inputs = ${inputs}
|
||||
flow(inputs)`;
|
||||
};
|
||||
|
||||
function buildTweakObject(tweak) {
|
||||
tweak.forEach((el) => {
|
||||
Object.keys(el).forEach((key) => {
|
||||
for (let kp in el[key]) {
|
||||
try {
|
||||
el[key][kp] = JSON.parse(el[key][kp]);
|
||||
} catch {}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const tweakString = JSON.stringify(tweak, null, 2);
|
||||
return tweakString;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base text for subtitle of Import Dialog
|
||||
* @constant
|
||||
8
src/frontend/src/constants/enums.ts
Normal file
8
src/frontend/src/constants/enums.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* enum for the different types of nodes
|
||||
* @enum
|
||||
*/
|
||||
export enum TypeModal {
|
||||
TEXT = 1,
|
||||
PROMPT = 2,
|
||||
}
|
||||
|
|
@ -41,18 +41,18 @@ import {
|
|||
TabsList,
|
||||
TabsTrigger,
|
||||
} from "../../components/ui/tabs";
|
||||
import {
|
||||
EXPORT_CODE_DIALOG,
|
||||
getCurlCode,
|
||||
getPythonApiCode,
|
||||
getPythonCode,
|
||||
} from "../../constants";
|
||||
import { EXPORT_CODE_DIALOG } from "../../constants/constants";
|
||||
import { darkContext } from "../../contexts/darkContext";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { FlowType } from "../../types/flow/index";
|
||||
import { buildTweaks } from "../../utils/reactflowUtils";
|
||||
import { classNames } from "../../utils/utils";
|
||||
import {
|
||||
classNames,
|
||||
getCurlCode,
|
||||
getPythonApiCode,
|
||||
getPythonCode,
|
||||
} from "../../utils/utils";
|
||||
export default function ApiModal({ flow }: { flow: FlowType }) {
|
||||
const [open, setOpen] = useState(true);
|
||||
const { dark } = useContext(darkContext);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import {
|
|||
TableHeader,
|
||||
TableRow,
|
||||
} from "../../components/ui/table";
|
||||
import { limitScrollFieldsModal } from "../../constants";
|
||||
import { limitScrollFieldsModal } from "../../constants/constants";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { Fragment, useContext, useRef, useState } from "react";
|
||||
import IconComponent from "../../components/genericIconComponent";
|
||||
import { limitScrollFieldsModal } from "../../constants";
|
||||
import { limitScrollFieldsModal } from "../../constants/constants";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import { NodeDataType } from "../../types/flow";
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { useContext, useState } from "react";
|
|||
import AceEditor from "react-ace";
|
||||
import IconComponent from "../../components/genericIconComponent";
|
||||
import { Button } from "../../components/ui/button";
|
||||
import { CODE_PROMPT_DIALOG_SUBTITLE } from "../../constants";
|
||||
import { CODE_PROMPT_DIALOG_SUBTITLE } from "../../constants/constants";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { darkContext } from "../../contexts/darkContext";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
|
|
@ -39,6 +39,7 @@ export default function CodeAreaModal({
|
|||
}
|
||||
}
|
||||
|
||||
// Check for custom code errors
|
||||
function handleClick() {
|
||||
postValidateCode(code)
|
||||
.then((apiReturn) => {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import {
|
|||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "../../components/ui/dialog";
|
||||
import { EXPORT_DIALOG_SUBTITLE } from "../../constants";
|
||||
import { EXPORT_DIALOG_SUBTITLE } from "../../constants/constants";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "../../components/ui/dialog";
|
||||
import { SETTINGS_DIALOG_SUBTITLE } from "../../constants";
|
||||
import { SETTINGS_DIALOG_SUBTITLE } from "../../constants/constants";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { IconCheck, IconClipboard, IconDownload } from "@tabler/icons-react";
|
|||
import { useState } from "react";
|
||||
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||
import { oneDark } from "react-syntax-highlighter/dist/cjs/styles/prism";
|
||||
import { programmingLanguages } from "../../../../constants";
|
||||
import { programmingLanguages } from "../../../../constants/constants";
|
||||
|
||||
interface Props {
|
||||
language: string;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import MaleTechnology from "../../../assets/male-technologist.png";
|
|||
import Robot from "../../../assets/robot.png";
|
||||
import SanitizedHTMLWrapper from "../../../components/SanitizedHTMLWrapper";
|
||||
import IconComponent from "../../../components/genericIconComponent";
|
||||
import { THOUGHTS_ICON } from "../../../constants";
|
||||
import { ChatMessageType } from "../../../types/chat";
|
||||
import { classNames } from "../../../utils/utils";
|
||||
import FileCard from "../fileComponent";
|
||||
|
|
@ -61,7 +60,10 @@ export default function ChatMessage({
|
|||
onClick={() => setHidden((prev) => !prev)}
|
||||
className="form-modal-chat-icon-div"
|
||||
>
|
||||
<THOUGHTS_ICON className="form-modal-chat-icon" />
|
||||
<IconComponent
|
||||
name="MessageSquare"
|
||||
className="form-modal-chat-icon"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{chat.thought && chat.thought !== "" && !hidden && (
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import {
|
|||
DialogTrigger,
|
||||
} from "../../components/ui/dialog";
|
||||
import { Textarea } from "../../components/ui/textarea";
|
||||
import { CHAT_FORM_DIALOG_SUBTITLE, THOUGHTS_ICON } from "../../constants";
|
||||
import { CHAT_FORM_DIALOG_SUBTITLE } from "../../constants/constants";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { validateNodes } from "../../utils/reactflowUtils";
|
||||
|
||||
|
|
@ -586,7 +586,10 @@ export default function FormModal({
|
|||
<span className="langflow-chat-desc-span">
|
||||
Start a conversation and click the agent's thoughts{" "}
|
||||
<span>
|
||||
<THOUGHTS_ICON className="mx-1 inline h-5 w-5 animate-bounce " />
|
||||
<IconComponent
|
||||
name="MessageSquare"
|
||||
className="mx-1 inline h-5 w-5 animate-bounce "
|
||||
/>
|
||||
</span>{" "}
|
||||
to inspect the chaining process.
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -11,16 +11,19 @@ import {
|
|||
MAX_WORDS_HIGHLIGHT,
|
||||
PROMPT_DIALOG_SUBTITLE,
|
||||
TEXT_DIALOG_SUBTITLE,
|
||||
TypeModal,
|
||||
regexHighlight,
|
||||
varHighlightHTML,
|
||||
} from "../../constants";
|
||||
} from "../../constants/constants";
|
||||
import { TypeModal } from "../../constants/enums";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { darkContext } from "../../contexts/darkContext";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { postValidatePrompt } from "../../controllers/API";
|
||||
import { APIClassType } from "../../types/api";
|
||||
import { classNames, getRandomKeyByssmm } from "../../utils/utils";
|
||||
import {
|
||||
classNames,
|
||||
getRandomKeyByssmm,
|
||||
varHighlightHTML,
|
||||
} from "../../utils/utils";
|
||||
import BaseModal from "../baseModal";
|
||||
|
||||
export default function GenericModal({
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import {
|
|||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "../../components/ui/dialog";
|
||||
import { IMPORT_DIALOG_SUBTITLE } from "../../constants";
|
||||
import { IMPORT_DIALOG_SUBTITLE } from "../../constants/constants";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
|
|
|
|||
|
|
@ -11,12 +11,16 @@ import { FlowType } from "../../types/flow";
|
|||
export default function CommunityPage() {
|
||||
const { flows, setTabId, downloadFlows, uploadFlows, addFlow } =
|
||||
useContext(TabsContext);
|
||||
|
||||
// set null id
|
||||
useEffect(() => {
|
||||
setTabId("");
|
||||
}, []);
|
||||
const { setErrorData } = useContext(alertContext);
|
||||
const [loadingExamples, setLoadingExamples] = useState(false);
|
||||
const [examples, setExamples] = useState<FlowType[]>([]);
|
||||
|
||||
// Show community examples on screen
|
||||
function handleExamples() {
|
||||
setLoadingExamples(true);
|
||||
getExamples()
|
||||
|
|
@ -33,6 +37,7 @@ export default function CommunityPage() {
|
|||
}
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Show community examples on page start
|
||||
useEffect(() => {
|
||||
handleExamples();
|
||||
}, []);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ export default function ExtraSidebar() {
|
|||
event.dataTransfer.setData("nodedata", JSON.stringify(data));
|
||||
}
|
||||
|
||||
// Handle showing components after use search input
|
||||
function handleSearchInput(e: string) {
|
||||
setFilterData((_) => {
|
||||
let ret = {};
|
||||
|
|
@ -122,6 +123,7 @@ export default function ExtraSidebar() {
|
|||
className="input-search"
|
||||
onChange={(e) => {
|
||||
handleSearchInput(e.target.value);
|
||||
// Set search input state
|
||||
setSearch(e.target.value);
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import Page from "./components/PageComponent";
|
|||
export default function FlowPage() {
|
||||
const { flows, tabId, setTabId } = useContext(TabsContext);
|
||||
const { id } = useParams();
|
||||
|
||||
// Set flow tab id
|
||||
useEffect(() => {
|
||||
setTabId(id);
|
||||
}, [id]);
|
||||
|
|
|
|||
|
|
@ -3,15 +3,19 @@ import { Link, useNavigate } from "react-router-dom";
|
|||
import { CardComponent } from "../../components/cardComponent";
|
||||
import IconComponent from "../../components/genericIconComponent";
|
||||
import { Button } from "../../components/ui/button";
|
||||
import { USER_PROJECTS_HEADER } from "../../constants";
|
||||
import { USER_PROJECTS_HEADER } from "../../constants/constants";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
export default function HomePage() {
|
||||
const { flows, setTabId, downloadFlows, uploadFlows, addFlow, removeFlow } =
|
||||
useContext(TabsContext);
|
||||
|
||||
// Set a null id
|
||||
useEffect(() => {
|
||||
setTabId("");
|
||||
}, []);
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Personal flows display
|
||||
return (
|
||||
<div className="main-page-panel">
|
||||
<div className="main-page-nav-arrangement">
|
||||
|
|
|
|||
|
|
@ -199,3 +199,7 @@ export type LoadingComponentProps = {
|
|||
|
||||
export type ContentProps = { children: ReactNode };
|
||||
export type HeaderProps = { children: ReactNode; description: string };
|
||||
|
||||
export interface languageMap {
|
||||
[key: string]: string | undefined;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import {
|
|||
LucideSend,
|
||||
Menu,
|
||||
MessageCircle,
|
||||
MessageSquare,
|
||||
MessagesSquare,
|
||||
MoonIcon,
|
||||
Paperclip,
|
||||
|
|
@ -266,6 +267,7 @@ export const nodeIconsLucide = {
|
|||
Search,
|
||||
Copy,
|
||||
Upload,
|
||||
MessageSquare,
|
||||
};
|
||||
export function getConnectedNodes(edge: Edge, nodes: Array<Node>): Array<Node> {
|
||||
const sourceId = edge.source;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import clsx, { ClassValue } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { ADJECTIVES, DESCRIPTIONS, NOUNS } from "../flow_constants";
|
||||
import { IVarHighlightType } from "../types/components";
|
||||
import { FlowType } from "../types/flow";
|
||||
import { TabsState } from "../types/tabs";
|
||||
import { buildTweaks } from "./reactflowUtils";
|
||||
|
||||
export function classNames(...classes: Array<string>) {
|
||||
return classes.filter(Boolean).join(" ");
|
||||
|
|
@ -251,3 +255,131 @@ export function getRandomKeyByssmm(): string {
|
|||
const milliseconds = String(now.getMilliseconds()).padStart(3, "0");
|
||||
return seconds + milliseconds + Math.abs(Math.floor(Math.random() * 10001));
|
||||
}
|
||||
|
||||
export function varHighlightHTML({ name }: IVarHighlightType): string {
|
||||
const html = `<span class="font-semibold chat-message-highlight">{${name}}</span>`;
|
||||
return html;
|
||||
};
|
||||
|
||||
export function buildTweakObject(tweak) {
|
||||
tweak.forEach((el) => {
|
||||
Object.keys(el).forEach((key) => {
|
||||
for (let kp in el[key]) {
|
||||
try {
|
||||
el[key][kp] = JSON.parse(el[key][kp]);
|
||||
} catch {}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const tweakString = JSON.stringify(tweak, null, 2);
|
||||
return tweakString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get the python code for the API
|
||||
* @param {string} flowId - The id of the flow
|
||||
* @returns {string} - The python code
|
||||
*/
|
||||
export function getPythonApiCode(
|
||||
flow: FlowType,
|
||||
tweak?: any[],
|
||||
tabsState?: TabsState
|
||||
): string {
|
||||
const flowId = flow.id;
|
||||
|
||||
// create a dictionary of node ids and the values is an empty dictionary
|
||||
// flow.data.nodes.forEach((node) => {
|
||||
// node.data.id
|
||||
// }
|
||||
const tweaks = buildTweaks(flow);
|
||||
const inputs = buildInputs(tabsState, flow.id);
|
||||
return `import requests
|
||||
from typing import Optional
|
||||
|
||||
BASE_API_URL = "${window.location.protocol}//${
|
||||
window.location.host
|
||||
}/api/v1/process"
|
||||
FLOW_ID = "${flowId}"
|
||||
# You can tweak the flow by adding a tweaks dictionary
|
||||
# e.g {"OpenAI-XXXXX": {"model_name": "gpt-4"}}
|
||||
TWEAKS = ${
|
||||
tweak && tweak.length > 0
|
||||
? buildTweakObject(tweak)
|
||||
: JSON.stringify(tweaks, null, 2)
|
||||
}
|
||||
|
||||
def run_flow(inputs: dict, flow_id: str, tweaks: Optional[dict] = None) -> dict:
|
||||
"""
|
||||
Run a flow with a given message and optional tweaks.
|
||||
|
||||
:param message: The message to send to the flow
|
||||
:param flow_id: The ID of the flow to run
|
||||
:param tweaks: Optional tweaks to customize the flow
|
||||
:return: The JSON response from the flow
|
||||
"""
|
||||
api_url = f"{BASE_API_URL}/{flow_id}"
|
||||
|
||||
payload = {"inputs": inputs}
|
||||
|
||||
if tweaks:
|
||||
payload["tweaks"] = tweaks
|
||||
|
||||
response = requests.post(api_url, json=payload)
|
||||
return response.json()
|
||||
|
||||
# Setup any tweaks you want to apply to the flow
|
||||
inputs = ${inputs}
|
||||
print(run_flow(inputs, flow_id=FLOW_ID, tweaks=TWEAKS))`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to get the curl code for the API
|
||||
* @param {string} flowId - The id of the flow
|
||||
* @returns {string} - The curl code
|
||||
*/
|
||||
export function getCurlCode(
|
||||
flow: FlowType,
|
||||
tweak?: any[],
|
||||
tabsState?: TabsState
|
||||
): string {
|
||||
const flowId = flow.id;
|
||||
const tweaks = buildTweaks(flow);
|
||||
const inputs = buildInputs(tabsState, flow.id);
|
||||
|
||||
return `curl -X POST \\
|
||||
${window.location.protocol}//${
|
||||
window.location.host
|
||||
}/api/v1/process/${flowId} \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '{"inputs": ${inputs}, "tweaks": ${
|
||||
tweak && tweak.length > 0
|
||||
? buildTweakObject(tweak)
|
||||
: JSON.stringify(tweaks, null, 2)
|
||||
}}'`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to get the python code for the API
|
||||
* @param {string} flowName - The name of the flow
|
||||
* @returns {string} - The python code
|
||||
*/
|
||||
export function getPythonCode(
|
||||
flow: FlowType,
|
||||
tweak?: any[],
|
||||
tabsState?: TabsState
|
||||
): string {
|
||||
const flowName = flow.name;
|
||||
const tweaks = buildTweaks(flow);
|
||||
const inputs = buildInputs(tabsState, flow.id);
|
||||
return `from langflow import load_flow_from_json
|
||||
TWEAKS = ${
|
||||
tweak && tweak.length > 0
|
||||
? buildTweakObject(tweak)
|
||||
: JSON.stringify(tweaks, null, 2)
|
||||
}
|
||||
flow = load_flow_from_json("${flowName}.json", tweaks=TWEAKS)
|
||||
# Now you can use it like any chain
|
||||
inputs = ${inputs}
|
||||
flow(inputs)`;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue