diff --git a/src/uipath_langchain/_cli/_runtime/_output.py b/src/uipath_langchain/_cli/_runtime/_output.py index a039582f..775bf1cc 100644 --- a/src/uipath_langchain/_cli/_runtime/_output.py +++ b/src/uipath_langchain/_cli/_runtime/_output.py @@ -145,11 +145,9 @@ def serialized_output(self) -> Dict[str, Any]: try: if self.context.output is None: return {} - if hasattr(self.context.output, "dict"): - return self.context.output.dict() - elif hasattr(self.context.output, "to_dict"): - return self.context.output.to_dict() - return dict(self.context.output) + + return self._serialize_object(self.context.output) + except Exception as e: raise LangGraphRuntimeError( "OUTPUT_SERIALIZATION_FAILED", @@ -158,6 +156,31 @@ def serialized_output(self) -> Dict[str, Any]: UiPathErrorCategory.SYSTEM, ) from e + def _serialize_object(self, obj): + """Recursively serializes an object and all its nested components.""" + # Handle Pydantic models + if hasattr(obj, "dict"): + return self._serialize_object(obj.dict()) + elif hasattr(obj, "model_dump"): + return self._serialize_object(obj.model_dump(by_alias=True)) + elif hasattr(obj, "to_dict"): + return self._serialize_object(obj.to_dict()) + # Handle dictionaries + elif isinstance(obj, dict): + return {k: self._serialize_object(v) for k, v in obj.items()} + # Handle lists + elif isinstance(obj, list): + return [self._serialize_object(item) for item in obj] + # Handle other iterable objects (convert to dict first) + elif hasattr(obj, "__iter__") and not isinstance(obj, (str, bytes)): + try: + return self._serialize_object(dict(obj)) + except (TypeError, ValueError): + return obj + # Return primitive types as is + else: + return obj + async def process(self) -> UiPathRuntimeResult: """ Process the output and prepare the final execution result.