Merge branch 'zustand/io/migration' of github.com:logspace-ai/langflow into zustand/io/migration

This commit is contained in:
igorrCarvalho 2024-02-25 23:07:52 -03:00
commit afe0d42dd0
52 changed files with 163 additions and 83 deletions

View file

@ -9,9 +9,6 @@ class TextInput(CustomComponent):
description = "Used to pass text input to the next component." description = "Used to pass text input to the next component."
field_config = { field_config = {
"code": {
"show": False,
},
"value": {"display_name": "Value"}, "value": {"display_name": "Value"},
} }

View file

@ -0,0 +1,19 @@
from typing import Optional
from langflow import CustomComponent
from langflow.field_typing import Text
class TextOutput(CustomComponent):
display_name = "Text Output"
description = "Used to pass text output to the next component."
field_config = {
"value": {"display_name": "Value"},
}
def build(self, value: Optional[str] = "") -> Text:
self.status = value
if not value:
value = ""
return value

View file

@ -1,13 +1,13 @@
from typing import Optional from typing import Optional
from langchain_community.chat_models.bedrock import BedrockChat from langchain_community.chat_models.bedrock import BedrockChat
from langflow.field_typing import Text
from langflow import CustomComponent from langflow import CustomComponent
from langflow.field_typing import Text
class AmazonBedrockComponent(CustomComponent): class AmazonBedrockComponent(CustomComponent):
display_name: str = "Amazon Bedrock model" display_name: str = "Amazon Bedrock Model"
description: str = "Generate text using LLM model from Amazon Bedrock." description: str = "Generate text using LLM model from Amazon Bedrock."
def build_config(self): def build_config(self):

View file

@ -2,14 +2,13 @@ from typing import Optional
from langchain_community.chat_models.anthropic import ChatAnthropic from langchain_community.chat_models.anthropic import ChatAnthropic
from pydantic.v1 import SecretStr from pydantic.v1 import SecretStr
from langflow import CustomComponent
from langflow.field_typing import Text from langflow.field_typing import Text
from langflow import CustomComponent
class AnthropicLLM(CustomComponent): class AnthropicLLM(CustomComponent):
display_name: str = "Anthropic model" display_name: str = "AnthropicModel"
description: str = "Generate text using Anthropic Chat&Completion large language models." description: str = "Generate text using Anthropic Chat&Completion large language models."
def build_config(self): def build_config(self):
@ -67,7 +66,7 @@ class AnthropicLLM(CustomComponent):
try: try:
output = ChatAnthropic( output = ChatAnthropic(
model_name=model, model_name=model,
anthropic_api_key=SecretStr(anthropic_api_key) if anthropic_api_key else None, anthropic_api_key=(SecretStr(anthropic_api_key) if anthropic_api_key else None),
max_tokens_to_sample=max_tokens, # type: ignore max_tokens_to_sample=max_tokens, # type: ignore
temperature=temperature, temperature=temperature,
anthropic_api_url=api_endpoint, anthropic_api_url=api_endpoint,

View file

@ -7,7 +7,7 @@ from langflow import CustomComponent
class AzureChatOpenAIComponent(CustomComponent): class AzureChatOpenAIComponent(CustomComponent):
display_name: str = "AzureOpenAI model" display_name: str = "AzureOpenAIModel"
description: str = "Generate text using LLM model from Azure OpenAI." description: str = "Generate text using LLM model from Azure OpenAI."
documentation: str = "https://python.langchain.com/docs/integrations/llms/azure_openai" documentation: str = "https://python.langchain.com/docs/integrations/llms/azure_openai"
beta = False beta = False

View file

@ -1,13 +1,13 @@
from typing import Dict, Optional from typing import Dict, Optional
from langchain_community.llms.ctransformers import CTransformers from langchain_community.llms.ctransformers import CTransformers
from langflow.field_typing import Text
from langflow import CustomComponent from langflow import CustomComponent
from langflow.field_typing import Text
class CTransformersComponent(CustomComponent): class CTransformersComponent(CustomComponent):
display_name = "CTransformers model" display_name = "CTransformersModel"
description = "Generate text using CTransformers LLM models" description = "Generate text using CTransformers LLM models"
documentation = "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/ctransformers" documentation = "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/ctransformers"
@ -31,7 +31,14 @@ class CTransformersComponent(CustomComponent):
"inputs": {"display_name": "Input"}, "inputs": {"display_name": "Input"},
} }
def build(self, model: str, model_file: str, inputs: str, model_type: str, config: Optional[Dict] = None) -> Text: def build(
self,
model: str,
model_file: str,
inputs: str,
model_type: str,
config: Optional[Dict] = None,
) -> Text:
output = CTransformers(model=model, model_file=model_file, model_type=model_type, config=config) output = CTransformers(model=model, model_file=model_file, model_type=model_type, config=config)
message = output.invoke(inputs) message = output.invoke(inputs)
result = message.content if hasattr(message, "content") else message result = message.content if hasattr(message, "content") else message

View file

@ -1,18 +1,33 @@
from langchain_community.chat_models.cohere import ChatCohere from langchain_community.chat_models.cohere import ChatCohere
from langflow import CustomComponent from langflow import CustomComponent
from langflow.field_typing import Text from langflow.field_typing import Text
class CohereComponent(CustomComponent): class CohereComponent(CustomComponent):
display_name = "Cohere model" display_name = "CohereModel"
description = "Generate text using Cohere large language models." description = "Generate text using Cohere large language models."
documentation = "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/cohere" documentation = "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/cohere"
def build_config(self): def build_config(self):
return { return {
"cohere_api_key": {"display_name": "Cohere API Key", "type": "password", "password": True}, "cohere_api_key": {
"max_tokens": {"display_name": "Max Tokens", "default": 256, "type": "int", "show": True}, "display_name": "Cohere API Key",
"temperature": {"display_name": "Temperature", "default": 0.75, "type": "float", "show": True}, "type": "password",
"password": True,
},
"max_tokens": {
"display_name": "Max Tokens",
"default": 256,
"type": "int",
"show": True,
},
"temperature": {
"display_name": "Temperature",
"default": 0.75,
"type": "float",
"show": True,
},
"inputs": {"display_name": "Input"}, "inputs": {"display_name": "Input"},
} }
@ -23,8 +38,13 @@ class CohereComponent(CustomComponent):
max_tokens: int = 256, max_tokens: int = 256,
temperature: float = 0.75, temperature: float = 0.75,
) -> Text: ) -> Text:
output = ChatCohere(cohere_api_key=cohere_api_key, max_tokens=max_tokens, temperature=temperature) output = ChatCohere(
cohere_api_key=cohere_api_key,
max_tokens=max_tokens,
temperature=temperature,
)
message = output.invoke(inputs) message = output.invoke(inputs)
result = message.content if hasattr(message, "content") else message result = message.content if hasattr(message, "content") else message
self.status = result self.status = result
return result return result
return result

View file

@ -1,14 +1,14 @@
from typing import Optional from typing import Optional
from langchain_google_genai import ChatGoogleGenerativeAI # type: ignore from langchain_google_genai import ChatGoogleGenerativeAI # type: ignore
from langflow import CustomComponent
from langflow.field_typing import RangeSpec
from pydantic.v1.types import SecretStr from pydantic.v1.types import SecretStr
from langflow.field_typing import Text
from langflow import CustomComponent
from langflow.field_typing import RangeSpec, Text
class GoogleGenerativeAIComponent(CustomComponent): class GoogleGenerativeAIComponent(CustomComponent):
display_name: str = "Google Generative AI model" display_name: str = "Google Generative AIModel"
description: str = "Generate text using Google Generative AI to generate text." description: str = "Generate text using Google Generative AI to generate text."
documentation: str = "http://docs.langflow.org/components/custom" documentation: str = "http://docs.langflow.org/components/custom"

View file

@ -1,11 +1,13 @@
from typing import Optional, List, Dict, Any from typing import Any, Dict, List, Optional
from langflow import CustomComponent
from langchain_community.llms.llamacpp import LlamaCpp from langchain_community.llms.llamacpp import LlamaCpp
from langflow import CustomComponent
from langflow.field_typing import Text from langflow.field_typing import Text
class LlamaCppComponent(CustomComponent): class LlamaCppComponent(CustomComponent):
display_name = "LlamaCpp model" display_name = "LlamaCppModel"
description = "Generate text using llama.cpp model." description = "Generate text using llama.cpp model."
documentation = "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/llamacpp" documentation = "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/llamacpp"
@ -17,7 +19,10 @@ class LlamaCppComponent(CustomComponent):
"echo": {"display_name": "Echo", "advanced": True}, "echo": {"display_name": "Echo", "advanced": True},
"f16_kv": {"display_name": "F16 KV", "advanced": True}, "f16_kv": {"display_name": "F16 KV", "advanced": True},
"grammar_path": {"display_name": "Grammar Path", "advanced": True}, "grammar_path": {"display_name": "Grammar Path", "advanced": True},
"last_n_tokens_size": {"display_name": "Last N Tokens Size", "advanced": True}, "last_n_tokens_size": {
"display_name": "Last N Tokens Size",
"advanced": True,
},
"logits_all": {"display_name": "Logits All", "advanced": True}, "logits_all": {"display_name": "Logits All", "advanced": True},
"logprobs": {"display_name": "Logprobs", "advanced": True}, "logprobs": {"display_name": "Logprobs", "advanced": True},
"lora_base": {"display_name": "Lora Base", "advanced": True}, "lora_base": {"display_name": "Lora Base", "advanced": True},
@ -134,3 +139,5 @@ class LlamaCppComponent(CustomComponent):
result = message.content if hasattr(message, "content") else message result = message.content if hasattr(message, "content") else message
self.status = result self.status = result
return result return result
self.status = result
return result

View file

@ -12,7 +12,7 @@ from langflow.field_typing import Text
class ChatOllamaComponent(CustomComponent): class ChatOllamaComponent(CustomComponent):
display_name = "ChatOllama model" display_name = "ChatOllamaModel"
description = "Generate text using Local LLM for chat with Ollama." description = "Generate text using Local LLM for chat with Ollama."
def build_config(self) -> dict: def build_config(self) -> dict:

View file

@ -7,7 +7,7 @@ from langflow.field_typing import Text
class ChatVertexAIComponent(CustomComponent): class ChatVertexAIComponent(CustomComponent):
display_name = "ChatVertexAI model" display_name = "ChatVertexAIModel"
description = "Generate text using Vertex AI Chat large language models API." description = "Generate text using Vertex AI Chat large language models API."
def build_config(self): def build_config(self):

View file

@ -13,6 +13,7 @@ from langflow.graph.vertex.types import (
ChatVertex, ChatVertex,
FileToolVertex, FileToolVertex,
LLMVertex, LLMVertex,
RoutingVertex,
ToolkitVertex, ToolkitVertex,
) )
from langflow.interface.tools.constants import FILE_TOOLS from langflow.interface.tools.constants import FILE_TOOLS
@ -402,10 +403,12 @@ class Graph:
node_name = node_id.split("-")[0] node_name = node_id.split("-")[0]
if node_name in ["ChatOutput", "ChatInput"]: if node_name in ["ChatOutput", "ChatInput"]:
return ChatVertex return ChatVertex
if node_name in lazy_load_vertex_dict.VERTEX_TYPE_MAP: elif node_name in ["ShouldRunNext"]:
return lazy_load_vertex_dict.VERTEX_TYPE_MAP[node_name] return RoutingVertex
elif node_base_type in lazy_load_vertex_dict.VERTEX_TYPE_MAP: elif node_base_type in lazy_load_vertex_dict.VERTEX_TYPE_MAP:
return lazy_load_vertex_dict.VERTEX_TYPE_MAP[node_base_type] return lazy_load_vertex_dict.VERTEX_TYPE_MAP[node_base_type]
elif node_name in lazy_load_vertex_dict.VERTEX_TYPE_MAP:
return lazy_load_vertex_dict.VERTEX_TYPE_MAP[node_name]
if node_type in FILE_TOOLS: if node_type in FILE_TOOLS:
return FileToolVertex return FileToolVertex

View file

@ -67,7 +67,7 @@ class LLMVertex(StatelessVertex):
class_built_object = None class_built_object = None
def __init__(self, data: Dict, graph, params: Optional[Dict] = None): def __init__(self, data: Dict, graph, params: Optional[Dict] = None):
super().__init__(data, graph=graph, base_type="llms", params=params) super().__init__(data, graph=graph, base_type="models", params=params)
self.steps: List[Callable] = [self._custom_build] self.steps: List[Callable] = [self._custom_build]
async def _custom_build(self, *args, **kwargs): async def _custom_build(self, *args, **kwargs):

View file

@ -35,7 +35,7 @@ def import_by_type(_type: str, name: str) -> Any:
func_dict = { func_dict = {
"agents": import_agent, "agents": import_agent,
"prompts": import_prompt, "prompts": import_prompt,
"llms": {"llm": import_llm, "chat": import_chat_llm}, "models": {"llm": import_llm, "chat": import_chat_llm},
"tools": import_tool, "tools": import_tool,
"chains": import_chain, "chains": import_chain,
"toolkits": import_toolkit, "toolkits": import_toolkit,
@ -50,7 +50,7 @@ def import_by_type(_type: str, name: str) -> Any:
"retrievers": import_retriever, "retrievers": import_retriever,
"custom_components": import_custom_component, "custom_components": import_custom_component,
} }
if _type == "llms": if _type == "models":
key = "chat" if "chat" in name.lower() else "llm" key = "chat" if "chat" in name.lower() else "llm"
loaded_func = func_dict[_type][key] # type: ignore loaded_func = func_dict[_type][key] # type: ignore
else: else:

View file

@ -19,7 +19,11 @@ from langflow.interface.custom.utils import get_function
from langflow.interface.custom_lists import CUSTOM_NODES from langflow.interface.custom_lists import CUSTOM_NODES
from langflow.interface.importing.utils import import_by_type from langflow.interface.importing.utils import import_by_type
from langflow.interface.initialize.llm import initialize_vertexai from langflow.interface.initialize.llm import initialize_vertexai
from langflow.interface.initialize.utils import handle_format_kwargs, handle_node_type, handle_partial_variables from langflow.interface.initialize.utils import (
handle_format_kwargs,
handle_node_type,
handle_partial_variables,
)
from langflow.interface.initialize.vector_store import vecstore_initializer from langflow.interface.initialize.vector_store import vecstore_initializer
from langflow.interface.output_parsers.base import output_parser_creator from langflow.interface.output_parsers.base import output_parser_creator
from langflow.interface.retrievers.base import retriever_creator from langflow.interface.retrievers.base import retriever_creator
@ -105,7 +109,7 @@ async def instantiate_based_on_type(class_object, base_type, node_type, params,
return instantiate_chains(node_type, class_object, params) return instantiate_chains(node_type, class_object, params)
elif base_type == "output_parsers": elif base_type == "output_parsers":
return instantiate_output_parser(node_type, class_object, params) return instantiate_output_parser(node_type, class_object, params)
elif base_type == "llms": elif base_type == "models":
return instantiate_llm(node_type, class_object, params) return instantiate_llm(node_type, class_object, params)
elif base_type == "retrievers": elif base_type == "retrievers":
return instantiate_retriever(node_type, class_object, params) return instantiate_retriever(node_type, class_object, params)

View file

@ -1,16 +1,16 @@
from typing import Dict, List, Optional, Type from typing import Dict, List, Optional, Type
from loguru import logger
from langflow.interface.base import LangChainTypeCreator from langflow.interface.base import LangChainTypeCreator
from langflow.interface.custom_lists import llm_type_to_cls_dict from langflow.interface.custom_lists import llm_type_to_cls_dict
from langflow.services.deps import get_settings_service from langflow.services.deps import get_settings_service
from langflow.template.frontend_node.llms import LLMFrontendNode from langflow.template.frontend_node.llms import LLMFrontendNode
from loguru import logger
from langflow.utils.util import build_template_from_class from langflow.utils.util import build_template_from_class
class LLMCreator(LangChainTypeCreator): class LLMCreator(LangChainTypeCreator):
type_name: str = "llms" type_name: str = "models"
@property @property
def frontend_node_class(self) -> Type[LLMFrontendNode]: def frontend_node_class(self) -> Type[LLMFrontendNode]:

View file

@ -11,7 +11,11 @@ from starlette.websockets import WebSocket
from langflow.services.database.models.api_key.model import ApiKey from langflow.services.database.models.api_key.model import ApiKey
from langflow.services.database.models.api_key.crud import check_key from langflow.services.database.models.api_key.crud import check_key
from langflow.services.database.models.user.crud import get_user_by_id, get_user_by_username, update_user_last_login_at from langflow.services.database.models.user.crud import (
get_user_by_id,
get_user_by_username,
update_user_last_login_at,
)
from langflow.services.database.models.user.model import User from langflow.services.database.models.user.model import User
from langflow.services.deps import get_session, get_settings_service from langflow.services.deps import get_session, get_settings_service
@ -323,7 +327,7 @@ def add_padding(s):
def get_fernet(settings_service=Depends(get_settings_service)): def get_fernet(settings_service=Depends(get_settings_service)):
SECRET_KEY = settings_service.auth_settings.SECRET_KEY SECRET_KEY = settings_service.auth_settings.SECRET_KEY
# It's important that your secret key is 32 url-safe base64-encoded bytes # It's important that your secret key is 32 url-safe base64-encoded byte
padded_secret_key = add_padding(SECRET_KEY) padded_secret_key = add_padding(SECRET_KEY)
fernet = Fernet(padded_secret_key) fernet = Fernet(padded_secret_key)
return fernet return fernet

View file

@ -324,7 +324,9 @@ export default function ParameterComponent({
) : ( ) : (
title title
)} )}
<span className={(info === '' ? '' : 'ml-1 ') + " text-status-red"}>{required ? " *" : ""}</span> <span className={(info === "" ? "" : "ml-1 ") + " text-status-red"}>
{required ? " *" : ""}
</span>
<div className=""> <div className="">
{info !== "" && ( {info !== "" && (
<ShadTooltip content={infoHtml.current}> <ShadTooltip content={infoHtml.current}>

View file

@ -37,6 +37,7 @@ export default function GenericNode({
const flowPool = useFlowStore((state) => state.flowPool); const flowPool = useFlowStore((state) => state.flowPool);
const buildFlow = useFlowStore((state) => state.buildFlow); const buildFlow = useFlowStore((state) => state.buildFlow);
const setNode = useFlowStore((state) => state.setNode); const setNode = useFlowStore((state) => state.setNode);
const getBuildStatus = useFlowStore((state) => state.getBuildStatus);
const name = nodeIconsLucide[data.type] ? data.type : types[data.type]; const name = nodeIconsLucide[data.type] ? data.type : types[data.type];
const [inputName, setInputName] = useState(false); const [inputName, setInputName] = useState(false);
const [nodeName, setNodeName] = useState(data.node!.display_name); const [nodeName, setNodeName] = useState(data.node!.display_name);
@ -170,7 +171,6 @@ export default function GenericNode({
validationStatus: validationStatusType | null validationStatus: validationStatusType | null
) => { ) => {
const isValid = validationStatus && validationStatus.valid; const isValid = validationStatus && validationStatus.valid;
if (isValid) { if (isValid) {
return "green-status"; return "green-status";
} else if (!isValid && buildStatus === BuildStatus.INACTIVE) { } else if (!isValid && buildStatus === BuildStatus.INACTIVE) {
@ -179,10 +179,12 @@ export default function GenericNode({
return "green-status"; return "green-status";
} else if (!isValid && buildStatus === BuildStatus.BUILT) { } else if (!isValid && buildStatus === BuildStatus.BUILT) {
return "red-status"; return "red-status";
} else if (!validationStatus) { } else if (!validationStatus && buildStatus === BuildStatus.TO_BUILD) {
return "yellow-status"; return "green-status";
} else { } else if (buildStatus === BuildStatus.BUILDING) {
return "status-build-animation"; return "status-build-animation";
} else {
return "green-status";
} }
}; };
@ -205,6 +207,7 @@ export default function GenericNode({
validationStatus: validationStatusType | null validationStatus: validationStatusType | null
) => { ) => {
let isInvalid = validationStatus && !validationStatus.valid; let isInvalid = validationStatus && !validationStatus.valid;
if (buildStatus === BuildStatus.INACTIVE && isInvalid) { if (buildStatus === BuildStatus.INACTIVE && isInvalid) {
// INACTIVE should have its own class // INACTIVE should have its own class
return "inactive-status"; return "inactive-status";
@ -224,11 +227,17 @@ export default function GenericNode({
buildStatus: BuildStatus | undefined, buildStatus: BuildStatus | undefined,
validationStatus: validationStatusType | null validationStatus: validationStatusType | null
) => { ) => {
const specificClassFromBuildStatus = getSpecificClassFromBuildStatus(
buildStatus,
validationStatus
);
const baseBorderClass = getBaseBorderClass(selected);
const nodeSizeClass = getNodeSizeClass(showNode);
return classNames( return classNames(
getBaseBorderClass(selected), baseBorderClass,
getNodeSizeClass(showNode), nodeSizeClass,
"generic-node-div", "generic-node-div",
getSpecificClassFromBuildStatus(buildStatus, validationStatus) specificClassFromBuildStatus
); );
}; };
@ -265,7 +274,7 @@ export default function GenericNode({
className={getNodeBorderClassName( className={getNodeBorderClassName(
selected, selected,
showNode, showNode,
data?.build_status, getBuildStatus(data.id),
validationStatus validationStatus
)} )}
> >
@ -476,22 +485,26 @@ export default function GenericNode({
variant="outline" variant="outline"
className={"h-9 px-1.5"} className={"h-9 px-1.5"}
onClick={() => { onClick={() => {
if (data?.build_status === BuildStatus.BUILDING || isBuilding) if (
getBuildStatus(data.id) === BuildStatus.BUILDING ||
isBuilding
)
return; return;
buildFlow(data.id); buildFlow(data.id);
}} }}
> >
<div> <div>
<Tooltip <Tooltip
title={ title={
data?.build_status === BuildStatus.BUILDING ? ( getBuildStatus(data.id) === BuildStatus.BUILDING ? (
<span>Building...</span> <span>Building...</span>
) : !validationStatus ? ( ) : !validationStatus ? (
<span className="flex"> <span className="flex">
Build{" "} Build{" "}
<IconComponent <IconComponent
name="Play" name="Play"
className=" h-5 stroke-build-trigger stroke-2" className=" h-5 stroke-status-green stroke-2"
/>{" "} />{" "}
flow to validate status. flow to validate status.
</span> </span>
@ -510,7 +523,7 @@ export default function GenericNode({
> >
<div className="generic-node-status-position flex items-center justify-center"> <div className="generic-node-status-position flex items-center justify-center">
{renderIconPlayOrPauseComponents( {renderIconPlayOrPauseComponents(
data?.build_status, getBuildStatus(data.id),
validationStatus validationStatus
)} )}
</div> </div>

View file

@ -394,7 +394,10 @@ export default function NodeToolbarComponent({
/>{" "} />{" "}
<span className="">Delete</span>{" "} <span className="">Delete</span>{" "}
<span> <span>
<IconComponent name="Delete" className="text-red-300 absolute right-2 top-2 h-4 w-4"></IconComponent> <IconComponent
name="Delete"
className="absolute right-2 top-2 h-4 w-4 text-red-300"
></IconComponent>
</span> </span>
</div> </div>
</SelectItem> </SelectItem>

View file

@ -416,7 +416,6 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
useFlowStore.getState().updateBuildStatus(idList, BuildStatus.BUILDING); useFlowStore.getState().updateBuildStatus(idList, BuildStatus.BUILDING);
}, },
}); });
get().revertAllVerticesToBuild();
}, },
getFlow: () => { getFlow: () => {
return { return {
@ -425,26 +424,11 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
viewport: get().reactFlowInstance?.getViewport()!, viewport: get().reactFlowInstance?.getViewport()!,
}; };
}, },
updateBuildStatus: (nodeIdList: string[], status: BuildStatus) => {
nodeIdList.forEach((id) => {
const nodeToUpdate = get().nodes.find((node) => node.id === id);
if (nodeToUpdate) {
nodeToUpdate.data.build_status = status;
get().setNodes(get().nodes);
}
});
},
updateVerticesBuild: (vertices: string[]) => { updateVerticesBuild: (vertices: string[]) => {
set({ verticesBuild: vertices }); set({ verticesBuild: vertices });
}, },
verticesBuild: [], verticesBuild: [],
revertAllVerticesToBuild: () => {
// set all vertices to TO_BUILD
const verticesIds = get()
.nodes.filter((node) => node.data.build_status === BuildStatus.BUILDING)
.map((node) => node.id);
get().updateBuildStatus(verticesIds, BuildStatus.TO_BUILD);
},
removeFromVerticesBuild: (vertices: string[]) => { removeFromVerticesBuild: (vertices: string[]) => {
set({ set({
verticesBuild: get().verticesBuild.filter( verticesBuild: get().verticesBuild.filter(
@ -452,6 +436,25 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
), ),
}); });
}, },
updateBuildStatus: (nodeIdList: string[], status: BuildStatus) => {
let newBuildStatus = cloneDeep(get().buildStatus);
// check if nodeIdList is an array
if (!Array.isArray(nodeIdList)) {
nodeIdList = [nodeIdList];
}
nodeIdList.forEach((id) => {
newBuildStatus[id] = status;
});
set({ buildStatus: newBuildStatus });
},
buildStatus: {},
getBuildStatus: (nodeId: string) => {
// if the node is not in the buildStatus object, set it to TO_BUILD
if (!get().buildStatus[nodeId]) {
get().buildStatus[nodeId] = BuildStatus.TO_BUILD;
}
return get().buildStatus[nodeId];
},
})); }));
export default useFlowStore; export default useFlowStore;

View file

@ -296,7 +296,7 @@
@apply generic-node-status text-status-green; @apply generic-node-status text-status-green;
} }
.gray-status { .gray-status {
@apply generic-node-status text-muted-foreground; @apply generic-node-status text-status-gray;
} }
.red-status { .red-status {

View file

@ -60,6 +60,7 @@
--chat-send: #059669; --chat-send: #059669;
--status-green: #4ade80; --status-green: #4ade80;
--status-blue: #2563eb; --status-blue: #2563eb;
--status-gray: #6b7280;
--connection: #555; --connection: #555;
} }

View file

@ -1,5 +1,4 @@
import { Edge, Node, Viewport } from "reactflow"; import { Edge, Node, Viewport } from "reactflow";
import { BuildStatus } from "../../constants/enums";
import { FlowType } from "../flow"; import { FlowType } from "../flow";
//kind and class are just representative names to represent the actual structure of the object received by the API //kind and class are just representative names to represent the actual structure of the object received by the API
export type APIDataType = { [key: string]: APIKindType }; export type APIDataType = { [key: string]: APIKindType };
@ -37,7 +36,6 @@ export type APIClassType = {
| CustomFieldsType | CustomFieldsType
| boolean | boolean
| undefined; | undefined;
build_status?: BuildStatus;
}; };
export type TemplateVariableType = { export type TemplateVariableType = {

View file

@ -1,5 +1,4 @@
import { ReactFlowJsonObject, XYPosition } from "reactflow"; import { ReactFlowJsonObject, XYPosition } from "reactflow";
import { BuildStatus } from "../../constants/enums";
import { APIClassType } from "../api/index"; import { APIClassType } from "../api/index";
export type FlowType = { export type FlowType = {
@ -29,7 +28,6 @@ export type NodeDataType = {
node?: APIClassType; node?: APIClassType;
id: string; id: string;
output_types?: string[]; output_types?: string[];
build_status?: BuildStatus;
}; };
// FlowStyleType is the type of the style object that is used to style the // FlowStyleType is the type of the style object that is used to style the
// Flow card with an emoji and a color. // Flow card with an emoji and a color.

View file

@ -86,9 +86,10 @@ export type FlowStoreType = {
unselectAll: () => void; unselectAll: () => void;
buildFlow: (nodeId?: string) => Promise<void>; buildFlow: (nodeId?: string) => Promise<void>;
getFlow: () => { nodes: Node[]; edges: Edge[]; viewport: Viewport }; getFlow: () => { nodes: Node[]; edges: Edge[]; viewport: Viewport };
updateBuildStatus: (nodeId: string[], status: BuildStatus) => void;
updateVerticesBuild: (vertices: string[]) => void; updateVerticesBuild: (vertices: string[]) => void;
removeFromVerticesBuild: (vertices: string[]) => void; removeFromVerticesBuild: (vertices: string[]) => void;
revertAllVerticesToBuild: () => void;
verticesBuild: string[]; verticesBuild: string[];
updateBuildStatus: (nodeId: string[], status: BuildStatus) => void;
buildStatus: { [key: string]: BuildStatus };
getBuildStatus: (nodeId: string) => BuildStatus;
}; };

View file

@ -25,6 +25,7 @@ import {
Compass, Compass,
Copy, Copy,
Cpu, Cpu,
Delete,
Download, Download,
DownloadCloud, DownloadCloud,
Edit, Edit,
@ -117,7 +118,6 @@ import {
X, X,
XCircle, XCircle,
Zap, Zap,
Delete,
} from "lucide-react"; } from "lucide-react";
import { FaApple, FaGithub } from "react-icons/fa"; import { FaApple, FaGithub } from "react-icons/fa";
import { AWSIcon } from "../icons/AWS"; import { AWSIcon } from "../icons/AWS";
@ -195,7 +195,7 @@ export const gradients = [
export const nodeColors: { [char: string]: string } = { export const nodeColors: { [char: string]: string } = {
prompts: "#4367BF", prompts: "#4367BF",
models: "#AA2411", models: "#AA2411",
llms: "#6344BE", model_specs: "#6344BE",
chains: "#FE7500", chains: "#FE7500",
Document: "#7AAE42", Document: "#7AAE42",
list: "#9AAE42", list: "#9AAE42",
@ -224,7 +224,7 @@ export const nodeColors: { [char: string]: string } = {
export const nodeNames: { [char: string]: string } = { export const nodeNames: { [char: string]: string } = {
prompts: "Prompts", prompts: "Prompts",
models: "Language Models", models: "Language Models",
llms: "Model Settings", model_specs: "Model Specs",
chains: "Chains", chains: "Chains",
agents: "Agents", agents: "Agents",
tools: "Tools", tools: "Tools",
@ -296,7 +296,7 @@ export const nodeIconsLucide: iconsType = {
chains: Link, chains: Link,
memories: Cpu, memories: Cpu,
models: Bot, models: Bot,
llms: Lightbulb, model_specs: Lightbulb,
prompts: TerminalSquare, prompts: TerminalSquare,
tools: Wrench, tools: Wrench,
advanced: Laptop2, advanced: Laptop2,

View file

@ -80,6 +80,7 @@ module.exports = {
"status-green": "var(--status-green)", "status-green": "var(--status-green)",
"status-red": "var(--status-red)", "status-red": "var(--status-red)",
"status-yellow": "var(--status-yellow)", "status-yellow": "var(--status-yellow)",
"status-gray": "var(--status-gray)",
"success-background": "var(--success-background)", "success-background": "var(--success-background)",
"success-foreground": "var(--success-foreground)", "success-foreground": "var(--success-foreground)",
"beta-background": "var(--beta-background)", "beta-background": "var(--beta-background)",