Skip to content

Commit 2eedd63

Browse files
committed
fix: use chat runtime on run and debug
1 parent 22e6296 commit 2eedd63

File tree

5 files changed

+64
-27
lines changed

5 files changed

+64
-27
lines changed

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[project]
22
name = "uipath"
3-
version = "2.2.22"
3+
version = "2.2.23"
44
description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.11"
77
dependencies = [
8-
"uipath-runtime>=0.2.2, <0.3.0",
8+
"uipath-runtime>=0.2.3, <0.3.0",
99
"click>=8.3.1",
1010
"httpx>=0.28.1",
1111
"pyjwt>=2.10.1",
Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
logger = logging.getLogger(__name__)
2020

2121

22-
class WebSocketChatBridge:
22+
class SocketIOChatBridge:
2323
"""WebSocket-based chat bridge for streaming conversational events to CAS.
2424
2525
Implements UiPathChatBridgeProtocol using python-socketio library.
@@ -221,8 +221,6 @@ async def _cleanup_client(self) -> None:
221221

222222
def get_chat_bridge(
223223
context: UiPathRuntimeContext,
224-
conversation_id: str,
225-
exchange_id: str,
226224
) -> UiPathChatProtocol:
227225
"""Factory to get WebSocket chat bridge for conversational agents.
228226
@@ -245,6 +243,9 @@ def get_chat_bridge(
245243
await bridge.disconnect(conversation_id, exchange_id)
246244
```
247245
"""
246+
assert context.conversation_id is not None, "conversation_id must be set in context"
247+
assert context.exchange_id is not None, "exchange_id must be set in context"
248+
248249
# Extract host from UIPATH_URL
249250
base_url = os.environ.get("UIPATH_URL")
250251
if not base_url:
@@ -259,7 +260,7 @@ def get_chat_bridge(
259260
host = parsed.netloc
260261

261262
# Construct WebSocket URL for CAS
262-
websocket_url = f"wss://{host}/autopilotforeveryone_/websocket_/socket.io?conversationId={conversation_id}"
263+
websocket_url = f"wss://{host}/autopilotforeveryone_/websocket_/socket.io?conversationId={context.conversation_id}"
263264

264265
# Build headers from context
265266
headers = {
@@ -268,12 +269,15 @@ def get_chat_bridge(
268269
or os.environ.get("UIPATH_TENANT_ID", ""),
269270
"X-UiPath-Internal-AccountId": context.org_id
270271
or os.environ.get("UIPATH_ORGANIZATION_ID", ""),
271-
"X-UiPath-ConversationId": conversation_id,
272+
"X-UiPath-ConversationId": context.conversation_id,
272273
}
273274

274-
return WebSocketChatBridge(
275+
return SocketIOChatBridge(
275276
websocket_url=websocket_url,
276-
conversation_id=conversation_id,
277-
exchange_id=exchange_id,
277+
conversation_id=context.conversation_id,
278+
exchange_id=context.exchange_id,
278279
headers=headers,
279280
)
281+
282+
283+
__all__ = ["get_chat_bridge"]

src/uipath/_cli/cli_debug.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,17 @@
99
UiPathRuntimeFactoryRegistry,
1010
UiPathRuntimeProtocol,
1111
)
12+
from uipath.runtime.chat import UiPathChatProtocol, UiPathChatRuntime
1213
from uipath.runtime.debug import UiPathDebugBridgeProtocol, UiPathDebugRuntime
1314

15+
from uipath._cli._chat._bridge import get_chat_bridge
16+
from uipath._cli._debug._bridge import get_debug_bridge
1417
from uipath._cli._utils._debug import setup_debugging
1518
from uipath._cli._utils._studio_project import StudioClient
1619
from uipath._utils._bindings import ResourceOverwritesContext
1720
from uipath.platform.common import UiPathConfig
1821
from uipath.tracing import LlmOpsHttpExporter
1922

20-
from ._debug._bridge import get_debug_bridge
2123
from ._utils._console import ConsoleLogger
2224
from .middlewares import Middlewares
2325

@@ -108,28 +110,36 @@ async def execute_debug_runtime():
108110
command="debug",
109111
) as ctx:
110112
runtime: UiPathRuntimeProtocol | None = None
113+
chat_runtime: UiPathRuntimeProtocol | None = None
111114
debug_runtime: UiPathRuntimeProtocol | None = None
112115
factory: UiPathRuntimeFactoryProtocol | None = None
113116

114117
try:
115118
trigger_poll_interval: float = 5.0
116119

120+
factory = UiPathRuntimeFactoryRegistry.get(context=ctx)
121+
122+
runtime = await factory.new_runtime(
123+
entrypoint, ctx.conversation_id or ctx.job_id or "default"
124+
)
125+
117126
if ctx.job_id:
118127
trace_manager.add_span_exporter(LlmOpsHttpExporter())
119128
trigger_poll_interval = (
120129
0.0 # Polling disabled for production jobs
121130
)
122-
123-
factory = UiPathRuntimeFactoryRegistry.get(context=ctx)
124-
125-
runtime = await factory.new_runtime(
126-
entrypoint, ctx.job_id or "default"
127-
)
131+
if ctx.conversation_id and ctx.exchange_id:
132+
chat_bridge: UiPathChatProtocol = get_chat_bridge(
133+
context=ctx
134+
)
135+
chat_runtime = UiPathChatRuntime(
136+
delegate=runtime, chat_bridge=chat_bridge
137+
)
128138

129139
debug_bridge: UiPathDebugBridgeProtocol = get_debug_bridge(ctx)
130140

131141
debug_runtime = UiPathDebugRuntime(
132-
delegate=runtime,
142+
delegate=chat_runtime or runtime,
133143
debug_bridge=debug_bridge,
134144
trigger_poll_interval=trigger_poll_interval,
135145
)
@@ -155,6 +165,8 @@ async def execute_debug_runtime():
155165
finally:
156166
if debug_runtime:
157167
await debug_runtime.dispose()
168+
if chat_runtime:
169+
await chat_runtime.dispose()
158170
if runtime:
159171
await runtime.dispose()
160172
if factory:

src/uipath/_cli/cli_run.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
UiPathRuntimeResult,
1111
UiPathStreamOptions,
1212
)
13+
from uipath.runtime.chat import UiPathChatProtocol, UiPathChatRuntime
1314
from uipath.runtime.context import UiPathRuntimeContext
1415
from uipath.runtime.debug import UiPathDebugBridgeProtocol
1516
from uipath.runtime.errors import UiPathRuntimeError
1617
from uipath.runtime.events import UiPathRuntimeStateEvent
1718

19+
from uipath._cli._chat._bridge import get_chat_bridge
1820
from uipath._cli._debug._bridge import ConsoleDebugBridge
1921
from uipath._cli._utils._common import read_resource_overwrites_from_file
2022
from uipath._cli._utils._debug import setup_debugging
@@ -113,15 +115,32 @@ async def execute_runtime(
113115
ctx: UiPathRuntimeContext, runtime: UiPathRuntimeProtocol
114116
) -> UiPathRuntimeResult:
115117
options = UiPathExecuteOptions(resume=resume)
116-
ctx.result = await runtime.execute(
117-
input=ctx.get_input(), options=options
118-
)
118+
chat_runtime: UiPathRuntimeProtocol | None = None
119+
120+
try:
121+
if ctx.conversation_id and ctx.exchange_id:
122+
chat_bridge: UiPathChatProtocol = get_chat_bridge(context=ctx)
123+
chat_runtime = UiPathChatRuntime(
124+
delegate=runtime, chat_bridge=chat_bridge
125+
)
126+
ctx.result = await chat_runtime.execute(
127+
input=ctx.get_input(), options=options
128+
)
129+
else:
130+
ctx.result = await runtime.execute(
131+
input=ctx.get_input(), options=options
132+
)
133+
finally:
134+
if chat_runtime:
135+
await chat_runtime.dispose()
136+
119137
return ctx.result
120138

121139
async def debug_runtime(
122140
ctx: UiPathRuntimeContext, runtime: UiPathRuntimeProtocol
123141
) -> UiPathRuntimeResult | None:
124142
debug_bridge: UiPathDebugBridgeProtocol = ConsoleDebugBridge()
143+
125144
await debug_bridge.emit_execution_started()
126145
options = UiPathStreamOptions(resume=resume)
127146
async for event in runtime.stream(ctx.get_input(), options=options):
@@ -160,11 +179,13 @@ async def execute() -> None:
160179
try:
161180
factory = UiPathRuntimeFactoryRegistry.get(context=ctx)
162181
runtime = await factory.new_runtime(
163-
entrypoint, ctx.job_id or "default"
182+
entrypoint,
183+
ctx.conversation_id or ctx.job_id or "default",
164184
)
165185

166186
if ctx.job_id:
167187
trace_manager.add_span_exporter(LlmOpsHttpExporter())
188+
168189
ctx.result = await execute_runtime(ctx, runtime)
169190
else:
170191
ctx.result = await debug_runtime(ctx, runtime)

uv.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)