diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index cdffcdf4f..b394afc99 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -139,6 +139,7 @@ async def stream_build(flow_id: str): # We need to reset the chat history chat_manager.chat_history.empty_history(flow_id) except Exception as exc: + logger.exception(exc) logger.error("Error while building the flow: %s", exc) yield str(StreamData(event="error", data={"error": str(exc)})) finally: diff --git a/src/backend/langflow/graph/edge/base.py b/src/backend/langflow/graph/edge/base.py index 08f084a5c..341c3c78f 100644 --- a/src/backend/langflow/graph/edge/base.py +++ b/src/backend/langflow/graph/edge/base.py @@ -6,9 +6,15 @@ if TYPE_CHECKING: class Edge: - def __init__(self, source: "Vertex", target: "Vertex"): + def __init__(self, source: "Vertex", target: "Vertex", edge: dict): self.source: "Vertex" = source self.target: "Vertex" = target + self.source_handle = edge.get("sourceHandle", "") + self.target_handle = edge.get("targetHandle", "") + # 'BaseLoader;BaseOutputParser|documents|PromptTemplate-zmTlD' + # target_param is documents + self.target_param = self.target_handle.split("|")[1] + self.validate_edge() def validate_edge(self) -> None: diff --git a/src/backend/langflow/graph/graph/base.py b/src/backend/langflow/graph/graph/base.py index 46425ddf6..65fff3239 100644 --- a/src/backend/langflow/graph/graph/base.py +++ b/src/backend/langflow/graph/graph/base.py @@ -179,7 +179,7 @@ class Graph: raise ValueError(f"Source node {edge['source']} not found") if target is None: raise ValueError(f"Target node {edge['target']} not found") - edges.append(Edge(source, target)) + edges.append(Edge(source, target, edge)) return edges def _get_vertex_class(self, node_type: str, node_lc_type: str) -> Type[Vertex]: diff --git a/src/backend/langflow/graph/vertex/base.py b/src/backend/langflow/graph/vertex/base.py index 79c3270fb..a7fcf88b5 100644 --- a/src/backend/langflow/graph/vertex/base.py +++ b/src/backend/langflow/graph/vertex/base.py @@ -1,14 +1,11 @@ -from langflow.utils.constants import DIRECT_TYPES from langflow.interface.initialize import loading from langflow.interface.listing import ALL_TYPES_DICT from langflow.utils.logger import logger from langflow.utils.util import sync_to_async -import contextlib import inspect import types -import warnings from typing import Any, Dict, List, Optional from typing import TYPE_CHECKING @@ -69,6 +66,7 @@ class Vertex: break def _build_params(self): + # sourcery skip: merge-list-append, remove-redundant-if # Some params are required, some are optional # but most importantly, some params are python base classes # like str and others are LangChain objects like LLMChain, BasePromptTemplate @@ -89,8 +87,19 @@ class Vertex: if isinstance(value, dict) } params = {} + + for edge in self.edges: + param_key = edge.target_param + if param_key in template_dict: + if template_dict[param_key]["list"]: + if param_key not in params: + params[param_key] = [] + params[param_key].append(edge.source) + else: + params[param_key] = edge.source + for key, value in template_dict.items(): - if key == "_type": + if key == "_type" or not value.get("show"): continue # If the type is not transformable to a python base class # then we need to get the edge that connects to this node @@ -101,45 +110,8 @@ class Vertex: file_path = value.get("file_path") params[key] = file_path - - elif value.get("type") not in DIRECT_TYPES: - # Get the edge that connects to this node - edges = [ - edge - for edge in self.edges - if edge.target == self and edge.matched_type in value["type"] - ] - - # Get the output of the node that the edge connects to - # if the value['list'] is True, then there will be more - # than one time setting to params[key] - # so we need to append to a list if it exists - # or create a new list if it doesn't - - if value["required"] and not edges: - # If a required parameter is not found, raise an error - raise ValueError( - f"Required input {key} for module {self.vertex_type} not found" - ) - elif value["list"]: - # If this is a list parameter, append all sources to a list - params[key] = [edge.source for edge in edges] - elif edges: - # If a single parameter is found, use its source - params[key] = edges[0].source - - elif value["required"] or value.get("value"): - # If value does not have value this still passes - # but then gives a keyError - # so we need to check if value has value - new_value = value.get("value") - if new_value is None: - warnings.warn(f"Value for {key} in {self.vertex_type} is None. ") - if value.get("type") == "int": - with contextlib.suppress(TypeError, ValueError): - new_value = int(new_value) # type: ignore - params[key] = new_value - + elif value.get("type") in ["str", "prompt"] and params.get(key) is None: + params[key] = value.get("value") # Add _type to params self.params = params