From 6e5ecd97e058b37a5439e010dd32c7d7e12ce8a3 Mon Sep 17 00:00:00 2001 From: radu-mocanu Date: Fri, 25 Jul 2025 15:40:28 +0300 Subject: [PATCH 1/2] chore: add eval required params to runtime context --- src/uipath_langchain/_cli/cli_run.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/uipath_langchain/_cli/cli_run.py b/src/uipath_langchain/_cli/cli_run.py index 798fb871..c87d9dd8 100644 --- a/src/uipath_langchain/_cli/cli_run.py +++ b/src/uipath_langchain/_cli/cli_run.py @@ -31,8 +31,8 @@ def langgraph_run_middleware( tracing = bool_map[tracing.lower()] async def execute(): - context = LangGraphRuntimeContext.from_config( - env.get("UIPATH_CONFIG_PATH", "uipath.json") + context: LangGraphRuntimeContext = LangGraphRuntimeContext.from_config( + env.get("UIPATH_CONFIG_PATH", "uipath.json"), **kwargs ) context.entrypoint = entrypoint context.input = input @@ -42,6 +42,7 @@ async def execute(): context.logs_min_level = env.get("LOG_LEVEL", "INFO") context.job_id = env.get("UIPATH_JOB_KEY") context.trace_id = env.get("UIPATH_TRACE_ID") + context.eval_run = kwargs.get("eval_run", False) context.tracing_enabled = tracing context.input_file = kwargs.get("input_file", None) context.execution_output_file = kwargs.get("execution_output_file", None) From b853647f5c5adb3f3f6ce9fd679cec5a362cdf05 Mon Sep 17 00:00:00 2001 From: radu-mocanu Date: Wed, 30 Jul 2025 12:59:00 +0300 Subject: [PATCH 2/2] fix: extract output from final chunk --- pyproject.toml | 6 +++--- .../_cli/_runtime/_runtime.py | 20 ++++++++++++++++--- src/uipath_langchain/_cli/cli_run.py | 2 +- uv.lock | 12 +++++------ 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 06693d55..9be7251c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,12 +1,12 @@ [project] name = "uipath-langchain" -version = "0.0.120" +version = "0.0.121" description = "UiPath Langchain" readme = { file = "README.md", content-type = "text/markdown" } requires-python = ">=3.10" dependencies = [ - "uipath>=2.1.0, <2.2.0", - "langgraph>=0.2.70", + "uipath>=2.1.10, <2.2.0", + "langgraph>=0.5.0, <0.7.0", "langchain-core>=0.3.34", "langgraph-checkpoint-sqlite>=2.0.3", "langchain-community>=0.3.21", diff --git a/src/uipath_langchain/_cli/_runtime/_runtime.py b/src/uipath_langchain/_cli/_runtime/_runtime.py index 6f4e741e..7872f5ae 100644 --- a/src/uipath_langchain/_cli/_runtime/_runtime.py +++ b/src/uipath_langchain/_cli/_runtime/_runtime.py @@ -101,7 +101,7 @@ async def execute(self) -> Optional[UiPathRuntimeResult]: graph_config["max_concurrency"] = int(max_concurrency) # Stream the output at debug time - if self.context.job_id is None: + if self.is_debug_run(): # Get final chunk while streaming final_chunk = None async for stream_chunk in graph.astream( @@ -115,7 +115,7 @@ async def execute(self) -> Optional[UiPathRuntimeResult]: self.context.output = self._extract_graph_result(final_chunk, graph) else: - # Execute the graph normally at runtime + # Execute the graph normally at runtime or eval self.context.output = await graph.ainvoke( processed_input, graph_config ) @@ -310,9 +310,23 @@ def _extract_graph_result( # Check which channels are present available_channels = [ch for ch in output_channels if ch in final_chunk] + # if no available channels, output may contain the last_node name as key + unwrapped_final_chunk = {} + if not available_channels: + if len(final_chunk) == 1 and isinstance( + unwrapped_final_chunk := next(iter(final_chunk.values())), dict + ): + available_channels = [ + ch for ch in output_channels if ch in unwrapped_final_chunk + ] + if available_channels: # Create a dict with the available channels - return {channel: final_chunk[channel] for channel in available_channels} + return { + channel: final_chunk.get(channel, None) + or unwrapped_final_chunk[channel] + for channel in available_channels + } # Fallback for any other case return final_chunk diff --git a/src/uipath_langchain/_cli/cli_run.py b/src/uipath_langchain/_cli/cli_run.py index c87d9dd8..6af1b543 100644 --- a/src/uipath_langchain/_cli/cli_run.py +++ b/src/uipath_langchain/_cli/cli_run.py @@ -42,7 +42,7 @@ async def execute(): context.logs_min_level = env.get("LOG_LEVEL", "INFO") context.job_id = env.get("UIPATH_JOB_KEY") context.trace_id = env.get("UIPATH_TRACE_ID") - context.eval_run = kwargs.get("eval_run", False) + context.is_eval_run = kwargs.get("is_eval_run", False) context.tracing_enabled = tracing context.input_file = kwargs.get("input_file", None) context.execution_output_file = kwargs.get("execution_output_file", None) diff --git a/uv.lock b/uv.lock index 23592462..71929450 100644 --- a/uv.lock +++ b/uv.lock @@ -2642,7 +2642,7 @@ wheels = [ [[package]] name = "uipath" -version = "2.1.0" +version = "2.1.10" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "azure-monitor-opentelemetry" }, @@ -2657,14 +2657,14 @@ dependencies = [ { name = "tomli" }, { name = "truststore" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/93/c0b0f4a25331943f880c38029b99c6d8bbdf1a683f45ee9256008b164997/uipath-2.1.0.tar.gz", hash = "sha256:862999fa4eb7599a2cfb4dfa98741238ead89b450bb8ffcb1552af4c4270808d", size = 1902998 } +sdist = { url = "https://files.pythonhosted.org/packages/fa/33/616d6342d54c2f5ee7fea43836c15e0ce90fca9f3cc72739fdcba32fb024/uipath-2.1.10.tar.gz", hash = "sha256:b01e3e4118c311d79b5feefeb07ac0912f3dd1f4fe50463cd1827a50d2d39397", size = 1942026 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/ff/a2fda98101d338727f17a517e143fb3b4ab99b41aaf067dd0940946b819d/uipath-2.1.0-py3-none-any.whl", hash = "sha256:16a02172676bf78b30bce8c20abcbcb2d282a0aa5fefffb6939319ccbff366f5", size = 136628 }, + { url = "https://files.pythonhosted.org/packages/ba/a7/0c954a57d3559d5b35b80affa72e2f66490f12f29b14b2c792b402771c9f/uipath-2.1.10-py3-none-any.whl", hash = "sha256:ec1a8d5237c13b1dbb828613b36f3da7c3046d4119e8dc3d42c8bcef20ce817c", size = 174010 }, ] [[package]] name = "uipath-langchain" -version = "0.0.119" +version = "0.0.121" source = { editable = "." } dependencies = [ { name = "httpx" }, @@ -2701,12 +2701,12 @@ requires-dist = [ { name = "langchain-community", specifier = ">=0.3.21" }, { name = "langchain-core", specifier = ">=0.3.34" }, { name = "langchain-openai", specifier = ">=0.3.3" }, - { name = "langgraph", specifier = ">=0.2.70" }, + { name = "langgraph", specifier = ">=0.5.0,<0.7.0" }, { name = "langgraph-checkpoint-sqlite", specifier = ">=2.0.3" }, { name = "openai", specifier = ">=1.65.5" }, { name = "pydantic-settings", specifier = ">=2.6.0" }, { name = "python-dotenv", specifier = ">=1.0.1" }, - { name = "uipath", specifier = ">=2.1.0,<2.2.0" }, + { name = "uipath", specifier = ">=2.1.10,<2.2.0" }, { name = "uipath-langchain", marker = "extra == 'langchain'", specifier = ">=0.0.2" }, ] provides-extras = ["langchain"]