Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "uipath-langchain"
version = "0.8.2"
version = "0.8.6"
description = "Python SDK that enables developers to build and deploy LangGraph agents to the UiPath Cloud Platform"
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.11"
Expand Down
6 changes: 5 additions & 1 deletion src/uipath_langchain/runtime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
)

from uipath_langchain.runtime.factory import UiPathLangGraphRuntimeFactory
from uipath_langchain.runtime.runtime import UiPathLangGraphRuntime
from uipath_langchain.runtime.runtime import (
UiPathLangGraphRuntime,
VoiceLangGraphRuntime,
)
from uipath_langchain.runtime.schema import (
get_entrypoints_schema,
get_graph_schema,
Expand Down Expand Up @@ -33,4 +36,5 @@ def create_factory(
"get_graph_schema",
"UiPathLangGraphRuntimeFactory",
"UiPathLangGraphRuntime",
"VoiceLangGraphRuntime",
]
18 changes: 18 additions & 0 deletions src/uipath_langchain/runtime/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -534,3 +534,21 @@ def _build_node_name(self, namespace: Any, node_name: str) -> str:
async def dispose(self) -> None:
"""Cleanup runtime resources."""
pass


class VoiceLangGraphRuntime(UiPathLangGraphRuntime):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd hold off on adding this to the public library for now. Let's keep it in agents-python first while the feature is still taking shape. Once it's released and we know what the final form looks like, we can move it over.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it - I'll keep it agents repo

"""Passes input through without chat mapping.

Voice tool calls supply a synthetic AIMessage directly — the base
class's UiPathChatMessagesMapper would corrupt it.
"""

async def _get_graph_input(
self,
input: dict[str, Any] | None,
options: UiPathExecuteOptions | None,
) -> Any:
graph_input = input or {}
if options and options.resume:
return Command(resume=graph_input)
return graph_input
52 changes: 52 additions & 0 deletions tests/runtime/test_voice_runtime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Tests for VoiceLangGraphRuntime input handling."""

from typing import Any

import pytest
from langgraph.types import Command
from uipath.runtime import UiPathExecuteOptions

from uipath_langchain.runtime.runtime import VoiceLangGraphRuntime


@pytest.mark.asyncio
class TestVoiceLangGraphRuntimeInput:
"""Verify _get_graph_input skips chat message mapping."""

@staticmethod
def _make_runtime() -> VoiceLangGraphRuntime:
return VoiceLangGraphRuntime.__new__(VoiceLangGraphRuntime)

async def test_normal_input_passes_through(self) -> None:
runtime = self._make_runtime()
input_state = {"messages": [{"type": "ai", "content": "hello"}]}
options = UiPathExecuteOptions(resume=False)

result = await runtime._get_graph_input(input_state, options)

assert result == input_state

async def test_resume_wraps_in_command(self) -> None:
runtime = self._make_runtime()
input_state = {"messages": [{"type": "ai", "content": "hello"}]}
options = UiPathExecuteOptions(resume=True)

result = await runtime._get_graph_input(input_state, options)

assert isinstance(result, Command)

async def test_none_input_becomes_empty_dict(self) -> None:
runtime = self._make_runtime()

result = await runtime._get_graph_input(None, None)

assert result == {}

async def test_none_options_no_resume(self) -> None:
runtime = self._make_runtime()
input_state: dict[str, Any] = {"messages": []}

result = await runtime._get_graph_input(input_state, None)

assert result == input_state
assert not isinstance(result, Command)
20 changes: 10 additions & 10 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.