diff --git a/src/backend/base/langflow/schema/schema.py b/src/backend/base/langflow/schema/schema.py index fb7ada8e02f3..2d509d6eb4fe 100644 --- a/src/backend/base/langflow/schema/schema.py +++ b/src/backend/base/langflow/schema/schema.py @@ -8,7 +8,7 @@ from langflow.schema.data import Data from langflow.schema.dataframe import DataFrame from langflow.schema.message import Message -from langflow.serialization.serialization import serialize +from langflow.serialization.serialization import serialize as original_serialize INPUT_FIELD_NAME = "input_value" @@ -41,77 +41,57 @@ class OutputValue(BaseModel): def get_type(payload): - result = LogType.UNKNOWN - match payload: - case Message(): - result = LogType.MESSAGE - - case Data(): - result = LogType.DATA - - case dict(): - result = LogType.OBJECT - - case list() | DataFrame(): - result = LogType.ARRAY - - case str(): - result = LogType.TEXT - - if result == LogType.UNKNOWN and ( - (payload and isinstance(payload, Generator)) - or (isinstance(payload, Message) and isinstance(payload.text, Generator)) - ): - result = LogType.STREAM - - return result + if isinstance(payload, Message): + return LogType.MESSAGE + if isinstance(payload, Data): + return LogType.DATA + if isinstance(payload, dict): + return LogType.OBJECT + if isinstance(payload, (list, DataFrame)): + return LogType.ARRAY + if isinstance(payload, str): + return LogType.TEXT + if isinstance(payload, Generator) or (isinstance(payload, Message) and isinstance(payload.text, Generator)): + return LogType.STREAM + return LogType.UNKNOWN def get_message(payload): - message = None if hasattr(payload, "data"): - message = payload.data - - elif hasattr(payload, "model_dump"): - message = payload.model_dump() - - if message is None and isinstance(payload, dict | str | Data): - message = payload.data if isinstance(payload, Data) else payload - - return message or payload + return payload.data + if hasattr(payload, "model_dump"): + return payload.model_dump() + if isinstance(payload, (dict, str, Data)): + return payload.data if isinstance(payload, Data) else payload + return payload def build_output_logs(vertex, result) -> dict: - outputs: dict[str, OutputValue] = {} + outputs = {} component_instance = result[0] for index, output in enumerate(vertex.outputs): - if component_instance.status is None: - payload = component_instance._results - output_result = payload.get(output["name"]) - else: - payload = component_instance._artifacts - output_result = payload.get(output["name"], {}).get("raw") + payload = component_instance._results if component_instance.status is None else component_instance._artifacts + output_result = ( + payload.get(output["name"], {}).get("raw") if component_instance.status else payload.get(output["name"]) + ) message = get_message(output_result) type_ = get_type(output_result) - match type_: - case LogType.STREAM if "stream_url" in message: + if type_ == LogType.STREAM: + if isinstance(message, dict) and "stream_url" in message: message = StreamURL(location=message["stream_url"]) - - case LogType.STREAM: + else: message = "" - case LogType.MESSAGE if hasattr(message, "message"): - message = message.message + elif type_ == LogType.MESSAGE and hasattr(message, "message"): + message = message.message - case LogType.UNKNOWN: - message = "" + elif type_ in {LogType.UNKNOWN, LogType.ARRAY}: + if isinstance(message, DataFrame): + message = message.to_dict(orient="records") + message = [original_serialize(item) for item in message] - case LogType.ARRAY: - if isinstance(message, DataFrame): - message = message.to_dict(orient="records") - message = [serialize(item) for item in message] name = output.get("name", f"output_{index}") - outputs |= {name: OutputValue(message=message, type=type_).model_dump()} + outputs[name] = OutputValue(message=message, type=type_).model_dump() return outputs diff --git a/src/backend/base/langflow/serialization/serialization.py b/src/backend/base/langflow/serialization/serialization.py index d94a166ae217..b09dada1d494 100644 --- a/src/backend/base/langflow/serialization/serialization.py +++ b/src/backend/base/langflow/serialization/serialization.py @@ -226,49 +226,28 @@ def serialize( *, to_str: bool = False, ) -> Any: - """Unified serialization with optional truncation support. - - Coordinates specialized serializers through a dispatcher pattern. - Maintains recursive processing for nested structures. - - Args: - obj: Object to serialize - max_length: Maximum length for string values, None for no truncation - max_items: Maximum items in list-like structures, None for no truncation - to_str: If True, return a string representation of the object if serialization fails - """ + """Unified serialization with optional truncation support.""" if obj is None: return None try: - # First try type-specific serialization result = _serialize_dispatcher(obj, max_length, max_items) - if result is not UNSERIALIZABLE_SENTINEL: # Special check for None since it's a valid result + if result is not UNSERIALIZABLE_SENTINEL: return result - # Handle class-based Pydantic types and other types if isinstance(obj, type): - if issubclass(obj, BaseModel | BaseModelV1): - return repr(obj) - return str(obj) # Handle other class types - - # Handle type aliases and generic types - if hasattr(obj, "__origin__") or hasattr(obj, "__parameters__"): # Type alias or generic type check - try: - return repr(obj) - except Exception as e: # noqa: BLE001 - logger.debug(f"Cannot serialize object {obj}: {e!s}") - - # Fallback to common serialization patterns + return repr(obj) if issubclass(obj, (BaseModel, BaseModelV1)) else str(obj) + + if hasattr(obj, "__origin__") or hasattr(obj, "__parameters__"): + return repr(obj) + if hasattr(obj, "model_dump"): return serialize(obj.model_dump(), max_length, max_items) if hasattr(obj, "dict") and not isinstance(obj, type): return serialize(obj.dict(), max_length, max_items) - # Final fallback to string conversion only if explicitly requested if to_str: return str(obj) - - except Exception as e: # noqa: BLE001 + except Exception as e: logger.debug(f"Cannot serialize object {obj}: {e!s}") return "[Unserializable Object]" return obj