Merge branch 'dev' into vecstores
This commit is contained in:
commit
616dfd0370
22 changed files with 1890 additions and 128 deletions
|
|
@ -1,5 +1,7 @@
|
|||
from pydantic import BaseModel, validator
|
||||
|
||||
from langflow.graph.utils import extract_input_variables_from_prompt
|
||||
|
||||
|
||||
class Code(BaseModel):
|
||||
code: str
|
||||
|
|
@ -25,3 +27,54 @@ class CodeValidationResponse(BaseModel):
|
|||
|
||||
class PromptValidationResponse(BaseModel):
|
||||
input_variables: list
|
||||
|
||||
|
||||
INVALID_CHARACTERS = {
|
||||
" ",
|
||||
",",
|
||||
".",
|
||||
":",
|
||||
";",
|
||||
"!",
|
||||
"?",
|
||||
"/",
|
||||
"\\",
|
||||
"(",
|
||||
")",
|
||||
"[",
|
||||
"]",
|
||||
"{",
|
||||
"}",
|
||||
}
|
||||
|
||||
|
||||
def validate_prompt(template: str):
|
||||
input_variables = extract_input_variables_from_prompt(template)
|
||||
|
||||
# Check if there are invalid characters in the input_variables
|
||||
input_variables = check_input_variables(input_variables)
|
||||
|
||||
return PromptValidationResponse(input_variables=input_variables)
|
||||
|
||||
|
||||
def check_input_variables(input_variables: list):
|
||||
invalid_chars = []
|
||||
fixed_variables = []
|
||||
for variable in input_variables:
|
||||
new_var = variable
|
||||
for char in INVALID_CHARACTERS:
|
||||
if char in variable:
|
||||
invalid_chars.append(char)
|
||||
new_var = new_var.replace(char, "")
|
||||
fixed_variables.append(new_var)
|
||||
if new_var != variable:
|
||||
input_variables.remove(variable)
|
||||
input_variables.append(new_var)
|
||||
# If any of the input_variables is not in the fixed_variables, then it means that
|
||||
# there are invalid characters in the input_variables
|
||||
if any(var not in fixed_variables for var in input_variables):
|
||||
raise ValueError(
|
||||
f"Invalid input variables: {input_variables}. Please, use something like {fixed_variables} instead."
|
||||
)
|
||||
|
||||
return input_variables
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ from langflow.api.base import (
|
|||
CodeValidationResponse,
|
||||
Prompt,
|
||||
PromptValidationResponse,
|
||||
validate_prompt,
|
||||
)
|
||||
from langflow.graph.utils import extract_input_variables_from_prompt
|
||||
from langflow.utils.logger import logger
|
||||
from langflow.utils.validate import validate_code
|
||||
|
||||
|
|
@ -29,8 +29,7 @@ def post_validate_code(code: Code):
|
|||
@router.post("/prompt", status_code=200, response_model=PromptValidationResponse)
|
||||
def post_validate_prompt(prompt: Prompt):
|
||||
try:
|
||||
input_variables = extract_input_variables_from_prompt(prompt.template)
|
||||
return PromptValidationResponse(input_variables=input_variables)
|
||||
return validate_prompt(prompt.template)
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
return HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
|
|
|||
|
|
@ -26,8 +26,9 @@ prompts:
|
|||
|
||||
llms:
|
||||
- OpenAI
|
||||
- AzureOpenAI
|
||||
# - AzureOpenAI
|
||||
- ChatOpenAI
|
||||
- HuggingFaceHub
|
||||
|
||||
tools:
|
||||
- Search
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Dict, List, Union
|
||||
from typing import Dict, List, Type, Union
|
||||
|
||||
from langflow.graph.base import Edge, Node
|
||||
from langflow.graph.nodes import (
|
||||
|
|
@ -25,7 +25,6 @@ from langflow.interface.prompts.base import prompt_creator
|
|||
from langflow.interface.toolkits.base import toolkits_creator
|
||||
from langflow.interface.tools.base import tool_creator
|
||||
from langflow.interface.tools.constants import FILE_TOOLS
|
||||
from langflow.interface.tools.util import get_tools_dict
|
||||
from langflow.interface.vectorStore.base import vectorstore_creator
|
||||
from langflow.interface.wrappers.base import wrapper_creator
|
||||
from langflow.utils import payload
|
||||
|
|
@ -114,6 +113,29 @@ class Graph:
|
|||
edges.append(Edge(source, target))
|
||||
return edges
|
||||
|
||||
def _get_node_class(self, node_type: str, node_lc_type: str) -> Type[Node]:
|
||||
node_type_map: Dict[str, Type[Node]] = {
|
||||
**{t: PromptNode for t in prompt_creator.to_list()},
|
||||
**{t: AgentNode for t in agent_creator.to_list()},
|
||||
**{t: ChainNode for t in chain_creator.to_list()},
|
||||
**{t: ToolNode for t in tool_creator.to_list()},
|
||||
**{t: ToolkitNode for t in toolkits_creator.to_list()},
|
||||
**{t: WrapperNode for t in wrapper_creator.to_list()},
|
||||
**{t: LLMNode for t in llm_creator.to_list()},
|
||||
**{t: MemoryNode for t in memory_creator.to_list()},
|
||||
**{t: EmbeddingNode for t in embedding_creator.to_list()},
|
||||
**{t: VectorStoreNode for t in vectorstore_creator.to_list()},
|
||||
**{t: DocumentLoaderNode for t in documentloader_creator.to_list()},
|
||||
}
|
||||
|
||||
if node_type in FILE_TOOLS:
|
||||
return FileToolNode
|
||||
if node_type in node_type_map:
|
||||
return node_type_map[node_type]
|
||||
if node_lc_type in node_type_map:
|
||||
return node_type_map[node_lc_type]
|
||||
return Node
|
||||
|
||||
def _build_nodes(self) -> List[Node]:
|
||||
nodes: List[Node] = []
|
||||
for node in self._nodes:
|
||||
|
|
@ -121,44 +143,9 @@ class Graph:
|
|||
node_type: str = node_data["type"] # type: ignore
|
||||
node_lc_type: str = node_data["node"]["template"]["_type"] # type: ignore
|
||||
|
||||
if node_type in prompt_creator.to_list():
|
||||
nodes.append(PromptNode(node))
|
||||
elif (
|
||||
node_type in agent_creator.to_list()
|
||||
or node_lc_type in agent_creator.to_list()
|
||||
):
|
||||
nodes.append(AgentNode(node))
|
||||
elif node_type in chain_creator.to_list():
|
||||
nodes.append(ChainNode(node))
|
||||
elif (
|
||||
node_type in tool_creator.to_list()
|
||||
or node_lc_type in get_tools_dict().keys()
|
||||
):
|
||||
if node_type in FILE_TOOLS:
|
||||
nodes.append(FileToolNode(node))
|
||||
nodes.append(ToolNode(node))
|
||||
elif node_type in toolkits_creator.to_list():
|
||||
nodes.append(ToolkitNode(node))
|
||||
elif node_type in wrapper_creator.to_list():
|
||||
nodes.append(WrapperNode(node))
|
||||
elif (
|
||||
node_type in llm_creator.to_list()
|
||||
or node_lc_type in llm_creator.to_list()
|
||||
):
|
||||
nodes.append(LLMNode(node))
|
||||
elif node_type in embedding_creator.to_list():
|
||||
nodes.append(EmbeddingNode(node))
|
||||
elif node_type in vectorstore_creator.to_list():
|
||||
nodes.append(VectorStoreNode(node))
|
||||
elif node_type in documentloader_creator.to_list():
|
||||
nodes.append(DocumentLoaderNode(node))
|
||||
elif (
|
||||
node_type in memory_creator.to_list()
|
||||
or node_lc_type in memory_creator.to_list()
|
||||
):
|
||||
nodes.append(MemoryNode(node))
|
||||
else:
|
||||
nodes.append(Node(node))
|
||||
NodeClass = self._get_node_class(node_type, node_lc_type)
|
||||
nodes.append(NodeClass(node))
|
||||
|
||||
return nodes
|
||||
|
||||
def get_children_by_node_type(self, node: Node, node_type: str) -> List[Node]:
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class BaseCustomChain(ConversationChain):
|
|||
|
||||
template: Optional[str]
|
||||
|
||||
ai_prefix_key: Optional[str]
|
||||
ai_prefix_value: Optional[str]
|
||||
"""Field to use as the ai_prefix. It needs to be set and has to be in the template"""
|
||||
|
||||
@root_validator(pre=False)
|
||||
|
|
@ -27,13 +27,13 @@ class BaseCustomChain(ConversationChain):
|
|||
format_dict = {}
|
||||
input_variables = extract_input_variables_from_prompt(values["template"])
|
||||
|
||||
if values.get("ai_prefix_key", None) is None:
|
||||
values["ai_prefix_key"] = values["memory"].ai_prefix
|
||||
if values.get("ai_prefix_value", None) is None:
|
||||
values["ai_prefix_value"] = values["memory"].ai_prefix
|
||||
|
||||
for key in input_variables:
|
||||
new_value = values.get(key, f"{{{key}}}")
|
||||
format_dict[key] = new_value
|
||||
if key == values.get("ai_prefix_key", None):
|
||||
if key == values.get("ai_prefix_value", None):
|
||||
values["memory"].ai_prefix = new_value
|
||||
|
||||
values["template"] = values["template"].format(**format_dict)
|
||||
|
|
@ -62,7 +62,7 @@ Current conversation:
|
|||
Human: {input}
|
||||
{character}:"""
|
||||
memory: BaseMemory = Field(default_factory=ConversationBufferMemory)
|
||||
ai_prefix_key: Optional[str] = "character"
|
||||
ai_prefix_value: Optional[str] = "character"
|
||||
"""Default memory store."""
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -178,12 +178,14 @@ class FrontendNode(BaseModel):
|
|||
field.show = bool(
|
||||
(field.required and key not in ["input_variables"])
|
||||
or key in FORCE_SHOW_FIELDS
|
||||
or "api_key" in key
|
||||
or "api" in key
|
||||
or ("key" in key and "input" not in key and "output" not in key)
|
||||
)
|
||||
|
||||
# Add password field
|
||||
field.password = any(
|
||||
text in key.lower() for text in {"password", "token", "api", "key"}
|
||||
field.password = (
|
||||
any(text in key.lower() for text in {"password", "token", "api", "key"})
|
||||
and field.show
|
||||
)
|
||||
|
||||
# Add multline
|
||||
|
|
|
|||
|
|
@ -309,13 +309,22 @@ class PromptFrontendNode(FrontendNode):
|
|||
def format_field(field: TemplateField, name: Optional[str] = None) -> None:
|
||||
# if field.field_type == "StringPromptTemplate"
|
||||
# change it to str
|
||||
PROMPT_FIELDS = [
|
||||
"template",
|
||||
"suffix",
|
||||
"prefix",
|
||||
"examples",
|
||||
]
|
||||
if field.field_type == "StringPromptTemplate" and "Message" in str(name):
|
||||
field.field_type = "str"
|
||||
field.field_type = "prompt"
|
||||
field.multiline = True
|
||||
field.value = HUMAN_PROMPT if "Human" in field.name else SYSTEM_PROMPT
|
||||
if field.name == "template" and field.value == "":
|
||||
field.value = DEFAULT_PROMPT
|
||||
|
||||
if field.name in PROMPT_FIELDS:
|
||||
field.field_type = "prompt"
|
||||
|
||||
if (
|
||||
"Union" in field.field_type
|
||||
and "BaseMessagePromptTemplate" in field.field_type
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import CodeAreaComponent from "../../../../components/codeAreaComponent";
|
|||
import InputFileComponent from "../../../../components/inputFileComponent";
|
||||
import { TabsContext } from "../../../../contexts/tabsContext";
|
||||
import IntComponent from "../../../../components/intComponent";
|
||||
import PromptAreaComponent from "../../../../components/promptComponent";
|
||||
|
||||
export default function ParameterComponent({
|
||||
left,
|
||||
|
|
@ -63,6 +64,7 @@ export default function ParameterComponent({
|
|||
type === "bool" ||
|
||||
type === "float" ||
|
||||
type === "code" ||
|
||||
type === "prompt" ||
|
||||
type === "file" ||
|
||||
type === "int") ? (
|
||||
<></>
|
||||
|
|
@ -187,9 +189,16 @@ export default function ParameterComponent({
|
|||
save();
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
) : left === true && type === "prompt" ? (
|
||||
<PromptAreaComponent
|
||||
disabled={disabled}
|
||||
value={data.node.template[name].value ?? ""}
|
||||
onChange={(t: string) => {
|
||||
data.node.template[name].value = t;
|
||||
save();
|
||||
}}
|
||||
/>
|
||||
):(<></>)}
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@ import {
|
|||
} from "react";
|
||||
import { sendAll } from "../../controllers/API";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { classNames, nodeColors } from "../../utils";
|
||||
import { classNames, nodeColors, snakeToNormalCase } from "../../utils";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { ChatType } from "../../types/chat";
|
||||
import ChatMessage from "./chatMessage";
|
||||
import { NodeType } from "../../types/flow";
|
||||
|
||||
const _ = require("lodash");
|
||||
|
||||
|
|
@ -28,7 +29,7 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) {
|
|||
const [open, setOpen] = useState(true);
|
||||
const [chatValue, setChatValue] = useState("");
|
||||
const [chatHistory, setChatHistory] = useState(flow.chat);
|
||||
const { setErrorData } = useContext(alertContext);
|
||||
const { setErrorData, setNoticeData } = useContext(alertContext);
|
||||
const addChatHistory = (
|
||||
message: string,
|
||||
isSend: boolean,
|
||||
|
|
@ -73,36 +74,58 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) {
|
|||
useEffect(() => {
|
||||
if (ref.current) ref.current.scrollIntoView({ behavior: "smooth" });
|
||||
}, [chatHistory]);
|
||||
function validateNodes() {
|
||||
if (
|
||||
reactFlowInstance.getNodes().some(
|
||||
(n) =>
|
||||
n.data.node &&
|
||||
Object.keys(n.data.node.template).some((t: any) => {
|
||||
return (
|
||||
n.data.node.template[t].required &&
|
||||
(!n.data.node.template[t].value ||
|
||||
n.data.node.template[t].value === "") &&
|
||||
!reactFlowInstance
|
||||
.getEdges()
|
||||
.some(
|
||||
(e) =>
|
||||
e.targetHandle.split("|")[1] === t &&
|
||||
e.targetHandle.split("|")[2] === n.id
|
||||
)
|
||||
);
|
||||
})
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
|
||||
function validateNode(n: NodeType): Array<string> {
|
||||
if (!n.data?.node?.template || !Object.keys(n.data.node.template)) {
|
||||
setNoticeData({
|
||||
title:
|
||||
"We've noticed a potential issue with a node in the flow. Please review it and, if necessary, submit a bug report with your exported flow file. Thank you for your help!",
|
||||
});
|
||||
return [];
|
||||
}
|
||||
return true;
|
||||
|
||||
const {
|
||||
type,
|
||||
node: { template },
|
||||
} = n.data;
|
||||
|
||||
return Object.keys(template).reduce(
|
||||
(errors: Array<string>, t) =>
|
||||
errors.concat(
|
||||
(template[t].required && template[t].show) &&
|
||||
(!template[t].value || template[t].value === "") &&
|
||||
!reactFlowInstance
|
||||
.getEdges()
|
||||
.some(
|
||||
(e) =>
|
||||
e.targetHandle.split("|")[1] === t &&
|
||||
e.targetHandle.split("|")[2] === n.id
|
||||
)
|
||||
? [
|
||||
`${type} is missing ${
|
||||
template.display_name
|
||||
? template.display_name
|
||||
: snakeToNormalCase(template[t].name)
|
||||
}.`,
|
||||
]
|
||||
: []
|
||||
),
|
||||
[] as string[]
|
||||
);
|
||||
}
|
||||
|
||||
function validateNodes() {
|
||||
return reactFlowInstance
|
||||
.getNodes()
|
||||
.flatMap((n: NodeType) => validateNode(n));
|
||||
}
|
||||
|
||||
const ref = useRef(null);
|
||||
|
||||
function sendMessage() {
|
||||
if (chatValue !== "") {
|
||||
if (validateNodes()) {
|
||||
let nodeValidationErrors = validateNodes();
|
||||
if (nodeValidationErrors.length === 0) {
|
||||
setLockChat(true);
|
||||
let message = chatValue;
|
||||
setChatValue("");
|
||||
|
|
@ -136,10 +159,8 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) {
|
|||
});
|
||||
} else {
|
||||
setErrorData({
|
||||
title: "Error sending message",
|
||||
list: [
|
||||
"Oops! Looks like you missed some required information. Please fill in all the required fields before continuing.",
|
||||
],
|
||||
title: "Oops! Looks like you missed some required information:",
|
||||
list: nodeValidationErrors,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
35
src/frontend/src/components/promptComponent/index.tsx
Normal file
35
src/frontend/src/components/promptComponent/index.tsx
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import { ArrowTopRightOnSquareIcon } from "@heroicons/react/24/outline";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import CodeAreaModal from "../../modals/codeAreaModal";
|
||||
import TextAreaModal from "../../modals/textAreaModal";
|
||||
import { TextAreaComponentType } from "../../types/components";
|
||||
import PromptAreaModal from "../../modals/promptModal";
|
||||
|
||||
export default function PromptAreaComponent({ value, onChange, disabled }:TextAreaComponentType) {
|
||||
const [myValue, setMyValue] = useState(value);
|
||||
const { openPopUp } = useContext(PopUpContext);
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setMyValue("");
|
||||
onChange("");
|
||||
}
|
||||
}, [disabled, onChange]);
|
||||
return (
|
||||
<div className={disabled ? "pointer-events-none cursor-not-allowed w-full" : " w-full"}>
|
||||
<div className="w-full flex items-center gap-3">
|
||||
<span
|
||||
className={
|
||||
"truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" +
|
||||
(disabled ? " bg-gray-200" : "")
|
||||
}
|
||||
>
|
||||
{myValue !== "" ? myValue : 'Text empty'}
|
||||
</span>
|
||||
<button onClick={()=>{openPopUp(<PromptAreaModal value={myValue} setValue={(t:string) => {setMyValue(t); onChange(t);}}/>)}}>
|
||||
<ArrowTopRightOnSquareIcon className="w-6 h-6 hover:text-blue-600" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { errorsTypeAPI } from './../../types/api/index';
|
||||
import { PromptTypeAPI, errorsTypeAPI } from './../../types/api/index';
|
||||
import { APIObjectType, sendAllProps } from '../../types/api/index';
|
||||
import axios, { AxiosResponse } from "axios";
|
||||
|
||||
|
|
@ -13,4 +13,9 @@ export async function sendAll(data:sendAllProps) {
|
|||
export async function checkCode(code:string):Promise<AxiosResponse<errorsTypeAPI>>{
|
||||
|
||||
return await axios.post('/validate/code',{code})
|
||||
}
|
||||
|
||||
export async function checkPrompt(template:string):Promise<AxiosResponse<PromptTypeAPI>>{
|
||||
|
||||
return await axios.post('/validate/prompt',{template})
|
||||
}
|
||||
|
|
@ -96,7 +96,6 @@ export default function CodeAreaModal({
|
|||
<div className="h-full w-full bg-gray-200 overflow-auto dark:bg-gray-900 p-4 gap-4 flex flex-row justify-center items-center">
|
||||
<div className="flex h-full w-full">
|
||||
<div className="overflow-hidden px-4 py-5 sm:p-6 w-full h-full rounded-lg bg-white dark:bg-gray-800 shadow">
|
||||
{/* need to insert code editor */}
|
||||
<AceEditor
|
||||
value={code}
|
||||
mode="python"
|
||||
|
|
|
|||
153
src/frontend/src/modals/promptModal/index.tsx
Normal file
153
src/frontend/src/modals/promptModal/index.tsx
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { XMarkIcon, DocumentTextIcon } from "@heroicons/react/24/outline";
|
||||
import { Fragment, useContext, useRef, useState } from "react";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { darkContext } from "../../contexts/darkContext";
|
||||
import { checkPrompt } from "../../controllers/API";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
export default function PromptAreaModal({
|
||||
value,
|
||||
setValue,
|
||||
}: {
|
||||
setValue: (value: string) => void;
|
||||
value: string;
|
||||
}) {
|
||||
const [open, setOpen] = useState(true);
|
||||
const [myValue, setMyValue] = useState(value);
|
||||
const { dark } = useContext(darkContext);
|
||||
const { setErrorData, setSuccessData } = useContext(alertContext);
|
||||
const { closePopUp } = useContext(PopUpContext);
|
||||
const ref = useRef();
|
||||
function setModalOpen(x: boolean) {
|
||||
setOpen(x);
|
||||
if (x === false) {
|
||||
setTimeout(() => {
|
||||
closePopUp();
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Transition.Root show={open} appear={true} as={Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-10"
|
||||
onClose={setModalOpen}
|
||||
initialFocus={ref}
|
||||
>
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed inset-0 bg-gray-500 dark:bg-gray-600 dark:bg-opacity-75 bg-opacity-75 transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-10 overflow-y-auto">
|
||||
<div className="flex h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative flex flex-col justify-between transform h-[600px] overflow-hidden rounded-lg bg-white dark:bg-gray-800 text-left shadow-xl transition-all sm:my-8 w-[700px]">
|
||||
<div className=" z-50 absolute top-0 right-0 hidden pt-4 pr-4 sm:block">
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||
onClick={() => {
|
||||
setModalOpen(false);
|
||||
}}
|
||||
>
|
||||
<span className="sr-only">Close</span>
|
||||
<XMarkIcon className="h-6 w-6" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="h-full w-full flex flex-col justify-center items-center">
|
||||
<div className="flex w-full pb-4 z-10 justify-center shadow-sm">
|
||||
<div className="mx-auto mt-4 flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-blue-100 dark:bg-gray-900 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<DocumentTextIcon
|
||||
className="h-6 w-6 text-blue-600"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-4 text-center sm:ml-4 sm:text-left">
|
||||
<Dialog.Title
|
||||
as="h3"
|
||||
className="text-lg font-medium dark:text-white leading-10 text-gray-900"
|
||||
>
|
||||
Edit Prompt
|
||||
</Dialog.Title>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-full w-full bg-gray-200 overflow-auto dark:bg-gray-900 p-4 gap-4 flex flex-row justify-center items-center">
|
||||
<div className="flex h-full w-full">
|
||||
<div className="overflow-hidden px-4 py-5 sm:p-6 w-full h-full rounded-lg bg-white dark:bg-gray-800 shadow">
|
||||
<textarea
|
||||
ref={ref}
|
||||
className="form-input h-full w-full rounded-lg border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-white"
|
||||
value={myValue}
|
||||
onChange={(e) => {
|
||||
setMyValue(e.target.value);
|
||||
setValue(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-gray-200 dark:bg-gray-900 w-full pb-3 flex flex-row-reverse px-4">
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex w-full justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 sm:ml-3 sm:w-auto sm:text-sm"
|
||||
onClick={() => {
|
||||
checkPrompt(myValue)
|
||||
.then((apiReturn) => {
|
||||
console.log(apiReturn);
|
||||
if (apiReturn.data) {
|
||||
let inputVariables =
|
||||
apiReturn.data.input_variables;
|
||||
if (inputVariables.length === 0) {
|
||||
setErrorData({
|
||||
title:
|
||||
"The template you are attempting to use does not contain any variables for data entry.",
|
||||
});
|
||||
} else {
|
||||
setSuccessData({
|
||||
title: "Prompt is ready",
|
||||
});
|
||||
setModalOpen(false);
|
||||
setValue(myValue);
|
||||
}
|
||||
} else {
|
||||
setErrorData({
|
||||
title: "Something went wrong, please try again",
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
return setErrorData({
|
||||
title:
|
||||
"There is something wrong with this prompt, please review it",
|
||||
list:[error.response.data.detail]});
|
||||
});
|
||||
}}
|
||||
>
|
||||
Check & Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
);
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ export default function TabComponent({ selected, flow, onClick }:{flow:FlowType,
|
|||
) : (
|
||||
<div className="flex items-center gap-2">
|
||||
<span
|
||||
className="text-left truncate"
|
||||
className="text-left w-32 truncate"
|
||||
onDoubleClick={() => {
|
||||
setIsRename(true);
|
||||
setValue(flow.name);
|
||||
|
|
|
|||
|
|
@ -16,4 +16,5 @@ export type sendAllProps={
|
|||
|
||||
chatHistory:{message:string,isSend:boolean}[],
|
||||
};
|
||||
export type errorsTypeAPI={function:{errors:Array<string>},imports:{errors:Array<string>}}
|
||||
export type errorsTypeAPI={function:{errors:Array<string>},imports:{errors:Array<string>}}
|
||||
export type PromptTypeAPI = {input_variables:Array<string>}
|
||||
|
|
@ -79,6 +79,8 @@ export const nodeColors: {[char: string]: string} = {
|
|||
embeddings:"#FF9135",
|
||||
documentloaders:"#FF9135",
|
||||
vectorstores: "#FF9135",
|
||||
toolkits:"#DB2C2C",
|
||||
wrappers:"#E6277A",
|
||||
unknown:"#9CA3AF"
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue