Skip to content

Commit 5bcc9ab

Browse files
chore: upgrade langgraph >= 1.0.0, uipath-langchain >=1.0.0 and uipath >=2.2.0 (#24)
1 parent ad7a874 commit 5bcc9ab

12 files changed

Lines changed: 490 additions & 1054 deletions

File tree

pyproject.toml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ name = "uipath-agents"
33
version = "0.0.0"
44
description = "UiPath Agents"
55
readme = { file = "README.md", content-type = "text/markdown" }
6-
requires-python = ">=3.10"
6+
requires-python = ">=3.11"
77
dependencies = [
8+
"uipath>=2.2.4",
9+
"uipath-langchain>=0.1.0",
10+
"langgraph>=1.0.0",
811
"azure-monitor-opentelemetry>=1.7.0",
9-
"langgraph>=0.6.6, <0.7.0",
1012
"opentelemetry-instrumentation-aiohttp-client>=0.49.0",
1113
"opentelemetry-instrumentation-asyncio>=0.49.0",
1214
"opentelemetry-instrumentation-httpx>=0.49.0",
1315
"opentelemetry-instrumentation-sqlite3>=0.49.0",
14-
"uipath-langchain>=0.0.159",
15-
"uipath>=2.1.183, <2.2.0",
1616
]
1717
maintainers = [
1818
{ name = "Silviu Georgescu", email = "silviu.georgescu@uipath.com" },
@@ -22,10 +22,13 @@ maintainers = [
2222
[project.entry-points."uipath.middlewares"]
2323
register = "uipath_agents.middlewares:register_middleware"
2424

25+
[project.entry-points."uipath.runtime.factories"]
26+
langgraph = "uipath_agents.runtime:register_runtime_factory"
27+
2528
[project.urls]
2629
Homepage = "https://uipath.com"
27-
Repository = "https://github.com/UiPath/uipath-lowcode-python"
28-
Documentation = "https://github.com/UiPath/lowcode-as-coded/tree/main/uipath-lowcode-python#readme"
30+
Repository = "https://github.com/UiPath/uipath-agents-python"
31+
Documentation = "https://github.com/UiPath/uipath-agents-python/blob/main/README.md"
2932

3033
[build-system]
3134
requires = ["hatchling"]

src/uipath_agents/_cli/cli_debug.py

Lines changed: 127 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,159 @@
11
import asyncio
22
import logging
3-
import shutil
4-
from pathlib import Path
53
from typing import Optional
64

75
from dotenv import load_dotenv
8-
from openinference.instrumentation.langchain import (
9-
LangChainInstrumentor,
10-
get_current_span,
11-
)
12-
from uipath._cli._debug._bridge import UiPathDebugBridge, get_debug_bridge
13-
from uipath._cli._debug._runtime import UiPathDebugRuntime
14-
from uipath._cli._runtime._contracts import UiPathRuntimeContext
6+
from uipath._cli._debug._bridge import ConsoleDebugBridge, get_debug_bridge
7+
from uipath._cli._utils._debug import setup_debugging
158
from uipath._cli._utils._studio_project import StudioClient
169
from uipath._cli.middlewares import MiddlewareResult
1710
from uipath._config import UiPathConfig
1811
from uipath._utils._bindings import ResourceOverwritesContext
12+
from uipath.core import UiPathTraceManager
13+
from uipath.runtime import (
14+
UiPathDebugBridgeProtocol,
15+
UiPathDebugRuntime,
16+
UiPathExecuteOptions,
17+
UiPathRuntimeContext,
18+
UiPathRuntimeFactoryProtocol,
19+
UiPathRuntimeFactoryRegistry,
20+
UiPathRuntimeProtocol,
21+
UiPathRuntimeResult,
22+
UiPathStreamOptions,
23+
)
24+
from uipath.runtime.events import UiPathRuntimeStateEvent
1925
from uipath.tracing import LlmOpsHttpExporter
2026
from uipath_langchain._cli._runtime._exception import LangGraphRuntimeError
21-
from uipath_langchain._cli._runtime._memory import get_memory
22-
from uipath_langchain._tracing import _instrument_traceable_attributes
2327

24-
from .._observability import get_azure_exporter, shutdown_telemetry
25-
from .constants import AGENT_BUILDER_FILENAME
26-
from .runtime import create_agent_langgraph_runtime, setup_runtime_factory
28+
from .._observability import shutdown_telemetry
29+
from .utils import _prepare_agent_run_files
2730

2831
load_dotenv()
2932

3033
logger = logging.getLogger(__name__)
3134

3235

33-
def _prepare_run_files():
34-
"""Copy all files from .agent-builder to root directory."""
35-
agent_builder_dir = Path(AGENT_BUILDER_FILENAME)
36-
37-
if not agent_builder_dir.exists() or not agent_builder_dir.is_dir():
38-
logger.debug(f"Agent builder directory not found at {agent_builder_dir}")
39-
return
36+
async def execute_runtime(ctx: UiPathRuntimeContext) -> UiPathRuntimeResult:
37+
with ctx:
38+
runtime: UiPathRuntimeProtocol | None = None
39+
factory: UiPathRuntimeFactoryProtocol | None = None
40+
try:
41+
factory = UiPathRuntimeFactoryRegistry.get(context=ctx)
42+
runtime = await factory.new_runtime(ctx.entrypoint, ctx.job_id or "default")
43+
options = UiPathExecuteOptions(resume=ctx.resume)
44+
ctx.result = await runtime.execute(input=ctx.get_input(), options=options)
45+
return ctx.result
46+
finally:
47+
if runtime:
48+
await runtime.dispose()
49+
if factory:
50+
await factory.dispose()
51+
52+
53+
async def debug_runtime(
54+
ctx: UiPathRuntimeContext,
55+
) -> UiPathRuntimeResult | None:
56+
with ctx:
57+
runtime: UiPathRuntimeProtocol | None = None
58+
factory: UiPathRuntimeFactoryProtocol | None = None
59+
try:
60+
factory = UiPathRuntimeFactoryRegistry.get(context=ctx)
61+
runtime = await factory.new_runtime(ctx.entrypoint, "default")
62+
debug_bridge: UiPathDebugBridgeProtocol = ConsoleDebugBridge()
63+
await debug_bridge.emit_execution_started()
64+
options = UiPathStreamOptions(resume=ctx.resume)
65+
async for event in runtime.stream(ctx.get_input(), options=options):
66+
if isinstance(event, UiPathRuntimeResult):
67+
await debug_bridge.emit_execution_completed(event)
68+
ctx.result = event
69+
elif isinstance(event, UiPathRuntimeStateEvent):
70+
await debug_bridge.emit_state_update(event)
71+
return ctx.result
72+
finally:
73+
if runtime:
74+
await runtime.dispose()
75+
if factory:
76+
await factory.dispose()
77+
78+
79+
def agents_debug_middleware(
80+
entrypoint: Optional[str],
81+
input: Optional[str],
82+
resume: bool,
83+
input_file: Optional[str],
84+
output_file: Optional[str],
85+
debug: bool,
86+
debug_port: int,
87+
**kwargs,
88+
) -> MiddlewareResult:
89+
"""Middleware to handle LangGraph execution"""
4090

41-
try:
42-
for file_path in agent_builder_dir.iterdir():
43-
if file_path.is_file():
44-
target_path = Path.cwd() / file_path.name
45-
shutil.copy2(file_path, target_path)
46-
logger.info(f"Processed {file_path.name}")
47-
except Exception as e:
48-
logger.error(f"Failed to copy files from {agent_builder_dir}: {e}")
49-
raise
91+
if not setup_debugging(debug, debug_port):
92+
logger.error(f"Failed to start debug server on port {debug_port}")
5093

94+
_prepare_agent_run_files()
5195

52-
def lowcode_debug_middleware(
53-
entrypoint: Optional[str], input: Optional[str], resume: bool, **kwargs
54-
) -> MiddlewareResult:
55-
"""Middleware to handle LangGraph execution"""
5696
try:
57-
context = UiPathRuntimeContext.with_defaults(**kwargs)
58-
context.entrypoint = entrypoint
59-
context.input = input
60-
context.resume = resume
61-
context.execution_id = context.job_id or "default"
62-
63-
_prepare_run_files()
64-
65-
async def execute():
66-
async with get_memory(context) as memory:
67-
_instrument_traceable_attributes()
68-
69-
runtime_factory = setup_runtime_factory(
70-
runtime_generator=lambda ctx: create_agent_langgraph_runtime(
71-
ctx, memory
72-
),
73-
context_generator=lambda: context,
74-
)
75-
runtime_factory.add_instrumentor(
76-
LangChainInstrumentor, get_current_span
77-
)
78-
79-
if context.job_id:
80-
runtime_factory.add_span_exporter(
81-
LlmOpsHttpExporter(extra_process_spans=True)
97+
98+
async def execute_debug_runtime():
99+
trace_manager = UiPathTraceManager()
100+
101+
with UiPathRuntimeContext.with_defaults(
102+
input=input,
103+
input_file=input_file,
104+
output_file=output_file,
105+
resume=resume,
106+
trace_manager=trace_manager,
107+
command="debug",
108+
) as ctx:
109+
runtime: UiPathRuntimeProtocol | None = None
110+
debug_runtime: UiPathRuntimeProtocol | None = None
111+
factory: UiPathRuntimeFactoryProtocol | None = None
112+
113+
try:
114+
if ctx.job_id:
115+
trace_manager.add_span_exporter(LlmOpsHttpExporter())
116+
117+
factory = UiPathRuntimeFactoryRegistry.get(context=ctx)
118+
119+
runtime = await factory.new_runtime(
120+
entrypoint, ctx.job_id or "default"
82121
)
83122

84-
azure_exporter = get_azure_exporter()
85-
if azure_exporter:
86-
runtime_factory.add_span_exporter(azure_exporter)
123+
debug_bridge: UiPathDebugBridgeProtocol = get_debug_bridge(ctx)
87124

88-
async def execute_debug_runtime():
89-
async with UiPathDebugRuntime.from_debug_context(
90-
factory=runtime_factory,
91-
context=context,
125+
debug_runtime = UiPathDebugRuntime(
126+
delegate=runtime,
92127
debug_bridge=debug_bridge,
93-
) as debug_runtime:
94-
await debug_runtime.execute()
95-
96-
debug_bridge: UiPathDebugBridge = get_debug_bridge(context)
97-
project_id = UiPathConfig.project_id
98-
99-
if project_id:
100-
studio_client = StudioClient(project_id)
128+
)
101129

102-
async with ResourceOverwritesContext(
103-
lambda: studio_client.get_resource_overwrites()
104-
) as ctx:
105-
logger.info(
106-
f"Loaded {ctx.overwrites_count} resource overwrites"
130+
project_id = UiPathConfig.project_id
131+
132+
if project_id:
133+
studio_client = StudioClient(project_id)
134+
135+
async with ResourceOverwritesContext(
136+
lambda: studio_client.get_resource_overwrites()
137+
):
138+
ctx.result = await debug_runtime.execute(
139+
ctx.get_input(),
140+
options=UiPathExecuteOptions(resume=resume),
141+
)
142+
else:
143+
ctx.result = await debug_runtime.execute(
144+
ctx.get_input(),
145+
options=UiPathExecuteOptions(resume=resume),
107146
)
108-
await execute_debug_runtime()
109-
else:
110-
await execute_debug_runtime()
111147

112-
asyncio.run(execute())
148+
finally:
149+
if debug_runtime:
150+
await debug_runtime.dispose()
151+
if runtime:
152+
await runtime.dispose()
153+
if factory:
154+
await factory.dispose()
155+
156+
asyncio.run(execute_debug_runtime())
113157

114158
return MiddlewareResult(
115159
should_continue=False,

src/uipath_agents/_cli/cli_dev.py

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)