Merge branch 'zustand/io/migration' of github.com:logspace-ai/langflow into zustand/io/migration
This commit is contained in:
commit
f57af2da52
13 changed files with 203 additions and 109 deletions
|
|
@ -10,6 +10,9 @@ from fastapi import (
|
||||||
WebSocketException,
|
WebSocketException,
|
||||||
status,
|
status,
|
||||||
)
|
)
|
||||||
|
from loguru import logger
|
||||||
|
from sqlmodel import Session
|
||||||
|
|
||||||
from langflow.api.utils import build_and_cache_graph, format_elapsed_time
|
from langflow.api.utils import build_and_cache_graph, format_elapsed_time
|
||||||
from langflow.api.v1.schemas import (
|
from langflow.api.v1.schemas import (
|
||||||
ResultData,
|
ResultData,
|
||||||
|
|
@ -24,8 +27,6 @@ from langflow.services.auth.utils import (
|
||||||
from langflow.services.chat.service import ChatService
|
from langflow.services.chat.service import ChatService
|
||||||
from langflow.services.deps import get_chat_service, get_session
|
from langflow.services.deps import get_chat_service, get_session
|
||||||
from langflow.services.monitor.utils import log_vertex_build
|
from langflow.services.monitor.utils import log_vertex_build
|
||||||
from loguru import logger
|
|
||||||
from sqlmodel import Session
|
|
||||||
|
|
||||||
router = APIRouter(tags=["Chat"])
|
router = APIRouter(tags=["Chat"])
|
||||||
|
|
||||||
|
|
@ -172,7 +173,7 @@ async def build_vertex(
|
||||||
raise ValueError(f"No result found for vertex {vertex_id}")
|
raise ValueError(f"No result found for vertex {vertex_id}")
|
||||||
chat_service.set_cache(flow_id, graph)
|
chat_service.set_cache(flow_id, graph)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
params = repr(exc)
|
params = str(exc)
|
||||||
valid = False
|
valid = False
|
||||||
result_dict = ResultData(results={})
|
result_dict = ResultData(results={})
|
||||||
artifacts = {}
|
artifacts = {}
|
||||||
|
|
|
||||||
|
|
@ -23,19 +23,25 @@ class ConversationChainComponent(CustomComponent):
|
||||||
|
|
||||||
def build(
|
def build(
|
||||||
self,
|
self,
|
||||||
|
inputs: str,
|
||||||
llm: BaseLanguageModel,
|
llm: BaseLanguageModel,
|
||||||
memory: Optional[BaseMemory] = None,
|
memory: Optional[BaseMemory] = None,
|
||||||
inputs: dict = {},
|
|
||||||
) -> Union[Chain, Callable, Text]:
|
) -> Union[Chain, Callable, Text]:
|
||||||
if memory is None:
|
if memory is None:
|
||||||
chain = ConversationChain(llm=llm)
|
chain = ConversationChain(llm=llm)
|
||||||
chain = ConversationChain(llm=llm, memory=memory)
|
else:
|
||||||
|
chain = ConversationChain(llm=llm, memory=memory)
|
||||||
result = chain.invoke(inputs)
|
result = chain.invoke(inputs)
|
||||||
# result is an AIMessage which is a subclass of BaseMessage
|
# result is an AIMessage which is a subclass of BaseMessage
|
||||||
# We need to check if it is a string or a BaseMessage
|
# We need to check if it is a string or a BaseMessage
|
||||||
if hasattr(result, "content") and isinstance(result.content, str):
|
if hasattr(result, "content") and isinstance(result.content, str):
|
||||||
return result.content
|
self.status = "is message"
|
||||||
|
result = result.content
|
||||||
elif isinstance(result, str):
|
elif isinstance(result, str):
|
||||||
return result
|
self.status = "is_string"
|
||||||
|
result = result
|
||||||
return str(result)
|
else:
|
||||||
|
# is dict
|
||||||
|
result = result.get("response")
|
||||||
|
self.status = result
|
||||||
|
return result
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import os
|
|
||||||
from typing import Any, Callable, Dict, Optional, Union
|
from typing import Any, Callable, Dict, Optional, Union
|
||||||
|
|
||||||
from langchain_community.chat_models.litellm import ChatLiteLLM, ChatLiteLLMException
|
from langchain_community.chat_models.litellm import ChatLiteLLM, ChatLiteLLMException
|
||||||
|
|
@ -27,6 +26,18 @@ class ChatLiteLLMComponent(CustomComponent):
|
||||||
"required": False,
|
"required": False,
|
||||||
"password": True,
|
"password": True,
|
||||||
},
|
},
|
||||||
|
"provider": {
|
||||||
|
"display_name": "Provider",
|
||||||
|
"info": "The provider of the API key.",
|
||||||
|
"options": [
|
||||||
|
"OpenAI",
|
||||||
|
"Azure",
|
||||||
|
"Anthropic",
|
||||||
|
"Replicate",
|
||||||
|
"Cohere",
|
||||||
|
"OpenRouter",
|
||||||
|
],
|
||||||
|
},
|
||||||
"streaming": {
|
"streaming": {
|
||||||
"display_name": "Streaming",
|
"display_name": "Streaming",
|
||||||
"field_type": "bool",
|
"field_type": "bool",
|
||||||
|
|
@ -96,7 +107,8 @@ class ChatLiteLLMComponent(CustomComponent):
|
||||||
def build(
|
def build(
|
||||||
self,
|
self,
|
||||||
model: str,
|
model: str,
|
||||||
api_key: str,
|
provider: str,
|
||||||
|
api_key: Optional[str] = None,
|
||||||
streaming: bool = True,
|
streaming: bool = True,
|
||||||
temperature: Optional[float] = 0.7,
|
temperature: Optional[float] = 0.7,
|
||||||
model_kwargs: Optional[Dict[str, Any]] = {},
|
model_kwargs: Optional[Dict[str, Any]] = {},
|
||||||
|
|
@ -114,13 +126,19 @@ class ChatLiteLLMComponent(CustomComponent):
|
||||||
litellm.set_verbose = verbose
|
litellm.set_verbose = verbose
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise ChatLiteLLMException(
|
raise ChatLiteLLMException(
|
||||||
"Could not import litellm python package. " "Please install it with `pip install litellm`"
|
"Could not import litellm python package. "
|
||||||
|
"Please install it with `pip install litellm`"
|
||||||
)
|
)
|
||||||
if api_key:
|
provider_map = {
|
||||||
if "perplexity" in model:
|
"OpenAI": "openai_api_key",
|
||||||
os.environ["PERPLEXITYAI_API_KEY"] = api_key
|
"Azure": "azure_api_key",
|
||||||
elif "replicate" in model:
|
"Anthropic": "anthropic_api_key",
|
||||||
os.environ["REPLICATE_API_KEY"] = api_key
|
"Replicate": "replicate_api_key",
|
||||||
|
"Cohere": "cohere_api_key",
|
||||||
|
"OpenRouter": "openrouter_api_key",
|
||||||
|
}
|
||||||
|
# Set the API key based on the provider
|
||||||
|
kwarg = {provider_map[provider]: api_key}
|
||||||
|
|
||||||
LLM = ChatLiteLLM(
|
LLM = ChatLiteLLM(
|
||||||
model=model,
|
model=model,
|
||||||
|
|
@ -133,5 +151,6 @@ class ChatLiteLLMComponent(CustomComponent):
|
||||||
n=n,
|
n=n,
|
||||||
max_tokens=max_tokens,
|
max_tokens=max_tokens,
|
||||||
max_retries=max_retries,
|
max_retries=max_retries,
|
||||||
|
**kwarg,
|
||||||
)
|
)
|
||||||
return LLM
|
return LLM
|
||||||
|
|
|
||||||
31
src/backend/langflow/interface/custom/attributes.py
Normal file
31
src/backend/langflow/interface/custom/attributes.py
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
def validate_icon(value: str, *args, **kwargs):
|
||||||
|
# we are going to use the emoji library to validate the emoji
|
||||||
|
# emojis can be defined using the :emoji_name: syntax
|
||||||
|
if not value.startswith(":") or not value.endswith(":"):
|
||||||
|
warnings.warn("Invalid emoji. Please use the :emoji_name: syntax.")
|
||||||
|
return value
|
||||||
|
emoji_value = emoji.emojize(value, variant="emoji_type")
|
||||||
|
if value == emoji_value:
|
||||||
|
warnings.warn(f"Invalid emoji. {value} is not a valid emoji.")
|
||||||
|
return value
|
||||||
|
return emoji_value
|
||||||
|
|
||||||
|
|
||||||
|
def getattr_return_str(value):
|
||||||
|
|
||||||
|
return str(value) if value else ""
|
||||||
|
|
||||||
|
|
||||||
|
def getattr_return_bool(value):
|
||||||
|
if isinstance(value, bool):
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
ATTR_FUNC_MAPPING = {
|
||||||
|
"display_name": getattr_return_str,
|
||||||
|
"description": getattr_return_str,
|
||||||
|
"beta": getattr_return_str,
|
||||||
|
"documentation": getattr_return_str,
|
||||||
|
"icon": validate_icon,
|
||||||
|
"pinned": getattr_return_bool,
|
||||||
|
}
|
||||||
|
|
@ -2,9 +2,10 @@ import operator
|
||||||
import warnings
|
import warnings
|
||||||
from typing import Any, ClassVar, Optional
|
from typing import Any, ClassVar, Optional
|
||||||
|
|
||||||
import emoji
|
|
||||||
from cachetools import TTLCache, cachedmethod
|
from cachetools import TTLCache, cachedmethod
|
||||||
from fastapi import HTTPException
|
from fastapi import HTTPException
|
||||||
|
|
||||||
|
from langflow.interface.custom.attributes import ATTR_FUNC_MAPPING
|
||||||
from langflow.interface.custom.code_parser import CodeParser
|
from langflow.interface.custom.code_parser import CodeParser
|
||||||
from langflow.interface.custom.eval import eval_custom_component_code
|
from langflow.interface.custom.eval import eval_custom_component_code
|
||||||
from langflow.utils import validate
|
from langflow.utils import validate
|
||||||
|
|
@ -65,14 +66,6 @@ class Component:
|
||||||
|
|
||||||
return validate.create_function(self.code, self._function_entrypoint_name)
|
return validate.create_function(self.code, self._function_entrypoint_name)
|
||||||
|
|
||||||
def getattr_return_str(self, value):
|
|
||||||
|
|
||||||
return str(value) if value else ""
|
|
||||||
|
|
||||||
def getattr_return_bool(self, value):
|
|
||||||
if isinstance(value, bool):
|
|
||||||
return value
|
|
||||||
|
|
||||||
def build_template_config(self) -> dict:
|
def build_template_config(self) -> dict:
|
||||||
if not self.code:
|
if not self.code:
|
||||||
return {}
|
return {}
|
||||||
|
|
@ -80,15 +73,8 @@ class Component:
|
||||||
cc_class = eval_custom_component_code(self.code)
|
cc_class = eval_custom_component_code(self.code)
|
||||||
component_instance = cc_class()
|
component_instance = cc_class()
|
||||||
template_config = {}
|
template_config = {}
|
||||||
attributes_func_mapping = {
|
|
||||||
"display_name": self.getattr_return_str,
|
|
||||||
"description": self.getattr_return_str,
|
|
||||||
"beta": self.getattr_return_str,
|
|
||||||
"documentation": self.getattr_return_str,
|
|
||||||
"icon": self.validate_icon,
|
|
||||||
}
|
|
||||||
|
|
||||||
for attribute, func in attributes_func_mapping.items():
|
for attribute, func in ATTR_FUNC_MAPPING.items():
|
||||||
if hasattr(component_instance, attribute):
|
if hasattr(component_instance, attribute):
|
||||||
value = getattr(component_instance, attribute)
|
value = getattr(component_instance, attribute)
|
||||||
if value is not None:
|
if value is not None:
|
||||||
|
|
@ -96,17 +82,5 @@ class Component:
|
||||||
|
|
||||||
return template_config
|
return template_config
|
||||||
|
|
||||||
def validate_icon(self, value: str, *args, **kwargs):
|
|
||||||
# we are going to use the emoji library to validate the emoji
|
|
||||||
# emojis can be defined using the :emoji_name: syntax
|
|
||||||
if not value.startswith(":") or not value.endswith(":"):
|
|
||||||
warnings.warn("Invalid emoji. Please use the :emoji_name: syntax.")
|
|
||||||
return value
|
|
||||||
emoji_value = emoji.emojize(value, variant="emoji_type")
|
|
||||||
if value == emoji_value:
|
|
||||||
warnings.warn(f"Invalid emoji. {value} is not a valid emoji.")
|
|
||||||
return value
|
|
||||||
return emoji_value
|
|
||||||
|
|
||||||
def build(self, *args: Any, **kwargs: Any) -> Any:
|
def build(self, *args: Any, **kwargs: Any) -> Any:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ from uuid import UUID
|
||||||
import yaml
|
import yaml
|
||||||
from cachetools import TTLCache, cachedmethod
|
from cachetools import TTLCache, cachedmethod
|
||||||
from fastapi import HTTPException
|
from fastapi import HTTPException
|
||||||
|
|
||||||
from langflow.interface.custom.code_parser.utils import (
|
from langflow.interface.custom.code_parser.utils import (
|
||||||
extract_inner_type_from_generic_alias,
|
extract_inner_type_from_generic_alias,
|
||||||
extract_union_types_from_generic_alias,
|
extract_union_types_from_generic_alias,
|
||||||
|
|
@ -35,6 +36,8 @@ class CustomComponent(Component):
|
||||||
"""The field configuration of the component. Defaults to an empty dictionary."""
|
"""The field configuration of the component. Defaults to an empty dictionary."""
|
||||||
field_order: Optional[List[str]] = None
|
field_order: Optional[List[str]] = None
|
||||||
"""The field order of the component. Defaults to an empty list."""
|
"""The field order of the component. Defaults to an empty list."""
|
||||||
|
pinned: Optional[bool] = False
|
||||||
|
"""The default pinned state of the component. Defaults to False."""
|
||||||
code_class_base_inheritance: ClassVar[str] = "CustomComponent"
|
code_class_base_inheritance: ClassVar[str] = "CustomComponent"
|
||||||
function_entrypoint_name: ClassVar[str] = "build"
|
function_entrypoint_name: ClassVar[str] = "build"
|
||||||
function: Optional[Callable] = None
|
function: Optional[Callable] = None
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,10 @@ from typing import Any, Dict, List, Optional, Union
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from fastapi import HTTPException
|
from fastapi import HTTPException
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
from langflow.field_typing.range_spec import RangeSpec
|
from langflow.field_typing.range_spec import RangeSpec
|
||||||
|
from langflow.interface.custom.attributes import ATTR_FUNC_MAPPING
|
||||||
from langflow.interface.custom.code_parser.utils import extract_inner_type
|
from langflow.interface.custom.code_parser.utils import extract_inner_type
|
||||||
from langflow.interface.custom.custom_component import CustomComponent
|
from langflow.interface.custom.custom_component import CustomComponent
|
||||||
from langflow.interface.custom.directory_reader.utils import (
|
from langflow.interface.custom.directory_reader.utils import (
|
||||||
|
|
@ -22,7 +25,6 @@ from langflow.template.frontend_node.custom_components import (
|
||||||
)
|
)
|
||||||
from langflow.utils import validate
|
from langflow.utils import validate
|
||||||
from langflow.utils.util import get_base_classes
|
from langflow.utils.util import get_base_classes
|
||||||
from loguru import logger
|
|
||||||
|
|
||||||
|
|
||||||
def add_output_types(
|
def add_output_types(
|
||||||
|
|
@ -263,16 +265,9 @@ def run_build_config(
|
||||||
|
|
||||||
def sanitize_template_config(template_config):
|
def sanitize_template_config(template_config):
|
||||||
"""Sanitize the template config"""
|
"""Sanitize the template config"""
|
||||||
attributes = {
|
|
||||||
"display_name",
|
|
||||||
"description",
|
|
||||||
"beta",
|
|
||||||
"documentation",
|
|
||||||
"output_types",
|
|
||||||
"icon",
|
|
||||||
}
|
|
||||||
for key in template_config.copy():
|
for key in template_config.copy():
|
||||||
if key not in attributes:
|
if key not in ATTR_FUNC_MAPPING.keys():
|
||||||
template_config.pop(key, None)
|
template_config.pop(key, None)
|
||||||
|
|
||||||
return template_config
|
return template_config
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ import re
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from typing import ClassVar, Dict, List, Optional, Union
|
from typing import ClassVar, Dict, List, Optional, Union
|
||||||
|
|
||||||
|
from pydantic import BaseModel, Field, field_serializer, model_serializer
|
||||||
|
|
||||||
from langflow.template.field.base import TemplateField
|
from langflow.template.field.base import TemplateField
|
||||||
from langflow.template.frontend_node.constants import (
|
from langflow.template.frontend_node.constants import (
|
||||||
CLASSES_TO_REMOVE,
|
CLASSES_TO_REMOVE,
|
||||||
|
|
@ -10,7 +12,6 @@ from langflow.template.frontend_node.constants import (
|
||||||
from langflow.template.frontend_node.formatter import field_formatters
|
from langflow.template.frontend_node.formatter import field_formatters
|
||||||
from langflow.template.template.base import Template
|
from langflow.template.template.base import Template
|
||||||
from langflow.utils import constants
|
from langflow.utils import constants
|
||||||
from pydantic import BaseModel, Field, field_serializer, model_serializer
|
|
||||||
|
|
||||||
|
|
||||||
class FieldFormatters(BaseModel):
|
class FieldFormatters(BaseModel):
|
||||||
|
|
@ -44,17 +45,31 @@ class FieldFormatters(BaseModel):
|
||||||
class FrontendNode(BaseModel):
|
class FrontendNode(BaseModel):
|
||||||
_format_template: bool = True
|
_format_template: bool = True
|
||||||
template: Template
|
template: Template
|
||||||
|
"""Template for the frontend node."""
|
||||||
description: Optional[str] = None
|
description: Optional[str] = None
|
||||||
|
"""Description of the frontend node."""
|
||||||
icon: Optional[str] = None
|
icon: Optional[str] = None
|
||||||
|
"""Icon of the frontend node."""
|
||||||
is_composition: Optional[bool] = None
|
is_composition: Optional[bool] = None
|
||||||
|
"""Whether the frontend node is used for composition."""
|
||||||
base_classes: List[str]
|
base_classes: List[str]
|
||||||
|
"""List of base classes for the frontend node."""
|
||||||
name: str = ""
|
name: str = ""
|
||||||
|
"""Name of the frontend node."""
|
||||||
display_name: Optional[str] = ""
|
display_name: Optional[str] = ""
|
||||||
|
"""Display name of the frontend node."""
|
||||||
documentation: str = ""
|
documentation: str = ""
|
||||||
|
"""Documentation of the frontend node."""
|
||||||
custom_fields: Optional[Dict] = defaultdict(list)
|
custom_fields: Optional[Dict] = defaultdict(list)
|
||||||
|
"""Custom fields of the frontend node."""
|
||||||
output_types: List[str] = []
|
output_types: List[str] = []
|
||||||
|
"""List of output types for the frontend node."""
|
||||||
full_path: Optional[str] = None
|
full_path: Optional[str] = None
|
||||||
|
"""Full path of the frontend node."""
|
||||||
field_formatters: FieldFormatters = Field(default_factory=FieldFormatters)
|
field_formatters: FieldFormatters = Field(default_factory=FieldFormatters)
|
||||||
|
"""Field formatters for the frontend node."""
|
||||||
|
pinned: bool = False
|
||||||
|
"""Whether the frontend node is pinned."""
|
||||||
|
|
||||||
beta: bool = False
|
beta: bool = False
|
||||||
error: Optional[str] = None
|
error: Optional[str] = None
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ from langchain_community.chat_message_histories.mongodb import (
|
||||||
DEFAULT_COLLECTION_NAME,
|
DEFAULT_COLLECTION_NAME,
|
||||||
DEFAULT_DBNAME,
|
DEFAULT_DBNAME,
|
||||||
)
|
)
|
||||||
from langchain_community.chat_message_histories.postgres import DEFAULT_CONNECTION_STRING
|
from langchain_community.chat_message_histories.postgres import (
|
||||||
|
DEFAULT_CONNECTION_STRING,
|
||||||
|
)
|
||||||
|
|
||||||
from langflow.template.field.base import TemplateField
|
from langflow.template.field.base import TemplateField
|
||||||
from langflow.template.frontend_node.base import FrontendNode
|
from langflow.template.frontend_node.base import FrontendNode
|
||||||
|
|
@ -13,7 +15,9 @@ from langflow.template.template.base import Template
|
||||||
|
|
||||||
|
|
||||||
class MemoryFrontendNode(FrontendNode):
|
class MemoryFrontendNode(FrontendNode):
|
||||||
#! Needs testing
|
|
||||||
|
pinned: bool = True
|
||||||
|
|
||||||
def add_extra_fields(self) -> None:
|
def add_extra_fields(self) -> None:
|
||||||
# chat history should have another way to add common field?
|
# chat history should have another way to add common field?
|
||||||
# prevent adding incorect field in ChatMessageHistory
|
# prevent adding incorect field in ChatMessageHistory
|
||||||
|
|
@ -77,7 +81,9 @@ class MemoryFrontendNode(FrontendNode):
|
||||||
field.show = True
|
field.show = True
|
||||||
field.advanced = False
|
field.advanced = False
|
||||||
field.value = ""
|
field.value = ""
|
||||||
field.info = INPUT_KEY_INFO if field.name == "input_key" else OUTPUT_KEY_INFO
|
field.info = (
|
||||||
|
INPUT_KEY_INFO if field.name == "input_key" else OUTPUT_KEY_INFO
|
||||||
|
)
|
||||||
|
|
||||||
if field.name == "memory_key":
|
if field.name == "memory_key":
|
||||||
field.value = "chat_history"
|
field.value = "chat_history"
|
||||||
|
|
|
||||||
|
|
@ -62,5 +62,10 @@ export default function IOInputField({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return <div className="h-full w-full">{handleInputType()}</div>;
|
return (
|
||||||
|
<div className="font-xl flex h-full w-full flex-col gap-4 p-4 font-semibold">
|
||||||
|
{inputType}
|
||||||
|
{handleInputType()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,5 +43,10 @@ export default function IOOutputView({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return <div className="h-full w-full">{handleOutputType()}</div>;
|
return (
|
||||||
|
<div className="font-xl flex h-full w-full flex-col gap-4 p-4 font-semibold">
|
||||||
|
{outputType}
|
||||||
|
{handleOutputType()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,11 +60,17 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
function UpdateAccordion() {
|
function UpdateAccordion() {
|
||||||
return (categories[selectedCategory]?.name ?? "Inputs") === "Inputs" ? inputs : outputs;
|
return (categories[selectedCategory]?.name ?? "Inputs") === "Inputs"
|
||||||
|
? inputs
|
||||||
|
: outputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseModal size={handleSelectChange() ? "large" : "small"} open={open} setOpen={setOpen}>
|
<BaseModal
|
||||||
|
size={handleSelectChange() ? "large" : "small"}
|
||||||
|
open={open}
|
||||||
|
setOpen={setOpen}
|
||||||
|
>
|
||||||
<BaseModal.Trigger>{children}</BaseModal.Trigger>
|
<BaseModal.Trigger>{children}</BaseModal.Trigger>
|
||||||
{/* TODO ADAPT TO ALL TYPES OF INPUTS AND OUTPUTS */}
|
{/* TODO ADAPT TO ALL TYPES OF INPUTS AND OUTPUTS */}
|
||||||
<BaseModal.Header description={CHAT_FORM_DIALOG_SUBTITLE}>
|
<BaseModal.Header description={CHAT_FORM_DIALOG_SUBTITLE}>
|
||||||
|
|
@ -85,47 +91,59 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
|
||||||
handleSelectChange() ? "w-2/6" : "w-full"
|
handleSelectChange() ? "w-2/6" : "w-full"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex items-start gap-4 py-2">
|
<div className="flex w-full items-center justify-between py-2">
|
||||||
{categories.map((category, index) => {
|
<div className="flex items-start gap-4">
|
||||||
return (
|
{categories.map((category, index) => {
|
||||||
//hide chat button if chat is alredy on the view
|
return (
|
||||||
<Button
|
//hide chat button if chat is alredy on the view
|
||||||
onClick={() => setSelectedCategory(index)}
|
<Button
|
||||||
variant={
|
onClick={() => setSelectedCategory(index)}
|
||||||
index === selectedCategory ? "primary" : "secondary"
|
variant={
|
||||||
}
|
index === selectedCategory ? "primary" : "secondary"
|
||||||
key={index}
|
}
|
||||||
>
|
key={index}
|
||||||
<IconComponent
|
>
|
||||||
name={category.icon}
|
<IconComponent
|
||||||
className=" file-component-variable"
|
name={category.icon}
|
||||||
/>
|
className=" file-component-variable"
|
||||||
<span className="file-component-variables-span text-md">
|
/>
|
||||||
{category.name}
|
<span className="file-component-variables-span text-md">
|
||||||
</span>
|
{category.name}
|
||||||
</Button>
|
</span>
|
||||||
);
|
</Button>
|
||||||
})}
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
{(outputs.map((output) => output.type).includes("ChatOutput") ||
|
{(outputs.map((output) => output.type).includes("ChatOutput") ||
|
||||||
inputs.map((output) => output.type).includes("chatInput")) &&
|
inputs.map((output) => output.type).includes("chatInput")) &&
|
||||||
selectedView.type !== "ChatOutput" && (
|
selectedView.type !== "ChatOutput" && (
|
||||||
<button
|
<Button
|
||||||
onClick={() => setSelectedView({ type: "ChatOutput" })}
|
onClick={() => setSelectedView({ type: "ChatOutput" })}
|
||||||
className={
|
variant="outline"
|
||||||
"cursor flex items-center rounded-md rounded-b-none px-1 hover:bg-muted-foreground"
|
|
||||||
}
|
|
||||||
key={"chat"}
|
key={"chat"}
|
||||||
|
className="self-end px-2.5"
|
||||||
>
|
>
|
||||||
<IconComponent
|
<IconComponent
|
||||||
name="Variable"
|
name="MessageSquareMore"
|
||||||
className=" file-component-variable"
|
className="h-5 w-5"
|
||||||
/>
|
/>
|
||||||
<span className="file-component-variables-span text-md">
|
</Button>
|
||||||
Chat
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mx-2 mb-2 mt-4 flex items-center gap-2 font-semibold">
|
||||||
|
{categories[selectedCategory]?.name === "Inputs" && (
|
||||||
|
<>
|
||||||
|
<IconComponent name={"FormInput"} />
|
||||||
|
Text Inputs
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{categories[selectedCategory]?.name === "Outputs" && (
|
||||||
|
<>
|
||||||
|
<IconComponent name={"ChevronRightSquare"} />
|
||||||
|
Prompt Outputs
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
{UpdateAccordion()
|
{UpdateAccordion()
|
||||||
.filter(
|
.filter(
|
||||||
(input) =>
|
(input) =>
|
||||||
|
|
@ -164,25 +182,35 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
|
||||||
keyValue={input.id}
|
keyValue={input.id}
|
||||||
>
|
>
|
||||||
<div className="file-component-tab-column">
|
<div className="file-component-tab-column">
|
||||||
{node &&
|
<div className="">
|
||||||
(categories[selectedCategory].name === "Inputs" ? (
|
{node &&
|
||||||
<IOInputField
|
(categories[selectedCategory]?.name === "Inputs" ? (
|
||||||
inputType={input.type}
|
<IOInputField
|
||||||
inputId={input.id}
|
inputType={input.type}
|
||||||
/>
|
inputId={input.id}
|
||||||
) : (
|
/>
|
||||||
<IOOutputView
|
) : (
|
||||||
outputType={input.type}
|
<IOOutputView
|
||||||
outputId={input.id}
|
outputType={input.type}
|
||||||
/>
|
outputId={input.id}
|
||||||
))}
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</AccordionComponent>
|
</AccordionComponent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
{handleSelectChange() && handleSelectChange()}
|
{handleSelectChange() ? (
|
||||||
|
handleSelectChange()
|
||||||
|
) : (
|
||||||
|
<div className="absolute bottom-8 right-8">
|
||||||
|
<Button className="px-3">
|
||||||
|
<IconComponent name="Play" className="h-6 w-6" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</BaseModal.Content>
|
</BaseModal.Content>
|
||||||
</BaseModal>
|
</BaseModal>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import {
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
ChevronLeft,
|
ChevronLeft,
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
Sliders,
|
ChevronRightSquare,
|
||||||
ChevronUp,
|
ChevronUp,
|
||||||
ChevronsLeft,
|
ChevronsLeft,
|
||||||
ChevronsRight,
|
ChevronsRight,
|
||||||
|
|
@ -40,6 +40,7 @@ import {
|
||||||
Fingerprint,
|
Fingerprint,
|
||||||
FlaskConical,
|
FlaskConical,
|
||||||
FolderPlus,
|
FolderPlus,
|
||||||
|
FormInput,
|
||||||
Forward,
|
Forward,
|
||||||
Gift,
|
Gift,
|
||||||
GitBranchPlus,
|
GitBranchPlus,
|
||||||
|
|
@ -64,6 +65,7 @@ import {
|
||||||
Menu,
|
Menu,
|
||||||
MessageCircle,
|
MessageCircle,
|
||||||
MessageSquare,
|
MessageSquare,
|
||||||
|
MessageSquareMore,
|
||||||
MessagesSquare,
|
MessagesSquare,
|
||||||
Minimize2,
|
Minimize2,
|
||||||
Minus,
|
Minus,
|
||||||
|
|
@ -88,6 +90,7 @@ import {
|
||||||
Share,
|
Share,
|
||||||
Share2,
|
Share2,
|
||||||
Shield,
|
Shield,
|
||||||
|
Sliders,
|
||||||
Sparkles,
|
Sparkles,
|
||||||
Square,
|
Square,
|
||||||
Store,
|
Store,
|
||||||
|
|
@ -385,7 +388,10 @@ export const nodeIconsLucide: iconsType = {
|
||||||
Square,
|
Square,
|
||||||
Minimize2,
|
Minimize2,
|
||||||
Maximize2,
|
Maximize2,
|
||||||
|
FormInput,
|
||||||
|
ChevronRightSquare,
|
||||||
SaveAll,
|
SaveAll,
|
||||||
|
MessageSquareMore,
|
||||||
Forward,
|
Forward,
|
||||||
Share2,
|
Share2,
|
||||||
Share,
|
Share,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue