Skip to content

Commit cb0cd72

Browse files
committed
fix: add mock template runtime with chat events
1 parent 1c34109 commit cb0cd72

File tree

12 files changed

+9595
-32
lines changed

12 files changed

+9595
-32
lines changed

demo/chat_agent/entry-points.json

Lines changed: 2204 additions & 0 deletions
Large diffs are not rendered by default.

demo/chat_agent/events.json

Lines changed: 7076 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,50 @@
11
"""Minimal demo script to run UiPathDevTerminal with mock runtimes."""
22

33
import logging
4+
from pathlib import Path
45

56
from uipath.runtime import (
67
UiPathRuntimeProtocol,
78
)
89

9-
from uipath.dev._demo.mock_context_runtime import ENTRYPOINT_CONTEXT, MockContextRuntime
10-
from uipath.dev._demo.mock_greeting_runtime import (
10+
from demo.mock_greeting_runtime import (
1111
ENTRYPOINT_GREETING,
1212
MockGreetingRuntime,
1313
)
14-
from uipath.dev._demo.mock_numbers_runtime import (
14+
from demo.mock_numbers_runtime import (
1515
ENTRYPOINT_ANALYZE_NUMBERS,
1616
MockNumberAnalyticsRuntime,
1717
)
18-
from uipath.dev._demo.mock_support_runtime import (
18+
from demo.mock_support_runtime import (
1919
ENTRYPOINT_SUPPORT_CHAT,
2020
MockSupportChatRuntime,
2121
)
22+
from demo.mock_telemetry_runtime import (
23+
ENTRYPOINT_TELEMETRY,
24+
MockTelemetryRuntime,
25+
)
26+
from demo.mock_template_runtime import (
27+
create_template_runtime,
28+
)
2229

2330
logger = logging.getLogger(__name__)
2431

32+
# Template mappings: entrypoint -> (events_file, schema_file)
33+
TEMPLATE_RUNTIMES = {
34+
"chat/movies.py:graph": (
35+
"chat_agent/events.json",
36+
"chat_agent/entry-points.json",
37+
),
38+
}
39+
2540

2641
class MockRuntimeFactory:
2742
"""Runtime factory compatible with UiPathRuntimeFactoryProtocol."""
2843

44+
def __init__(self):
45+
"""Initialize the mock runtime factory."""
46+
self.demo_dir = Path(__file__).parent
47+
2948
async def new_runtime(
3049
self, entrypoint: str, runtime_id: str
3150
) -> UiPathRuntimeProtocol:
@@ -36,8 +55,19 @@ async def new_runtime(
3655
return MockNumberAnalyticsRuntime(entrypoint=entrypoint)
3756
if entrypoint == ENTRYPOINT_SUPPORT_CHAT:
3857
return MockSupportChatRuntime(entrypoint=entrypoint)
39-
if entrypoint == ENTRYPOINT_CONTEXT:
40-
return MockContextRuntime(entrypoint=entrypoint)
58+
if entrypoint == ENTRYPOINT_TELEMETRY:
59+
return MockTelemetryRuntime(entrypoint=entrypoint)
60+
61+
if entrypoint in TEMPLATE_RUNTIMES:
62+
events_file, schema_file = TEMPLATE_RUNTIMES[entrypoint]
63+
64+
events_path = self.demo_dir / events_file
65+
schema_path = self.demo_dir / schema_file
66+
67+
return create_template_runtime(
68+
events_json=events_path,
69+
schema_json=schema_path,
70+
)
4171

4272
# Fallback: still return something so the demo doesn't explode
4373
logger.warning(
@@ -47,20 +77,32 @@ async def new_runtime(
4777

4878
async def discover_runtimes(self) -> list[UiPathRuntimeProtocol]:
4979
"""Return prototype instances for discovery (not really used by the UI)."""
50-
return [
80+
runtimes: list[UiPathRuntimeProtocol] = [
5181
MockGreetingRuntime(entrypoint=ENTRYPOINT_GREETING),
5282
MockNumberAnalyticsRuntime(entrypoint=ENTRYPOINT_ANALYZE_NUMBERS),
5383
MockSupportChatRuntime(entrypoint=ENTRYPOINT_SUPPORT_CHAT),
54-
MockContextRuntime(entrypoint=ENTRYPOINT_CONTEXT),
84+
MockTelemetryRuntime(entrypoint=ENTRYPOINT_TELEMETRY),
5585
]
5686

87+
for entrypoint in TEMPLATE_RUNTIMES.keys():
88+
try:
89+
runtime: UiPathRuntimeProtocol = await self.new_runtime(
90+
entrypoint, runtime_id="discovery"
91+
)
92+
runtimes.append(runtime)
93+
except Exception as e:
94+
logger.error(f"Failed to load template runtime '{entrypoint}': {e}")
95+
96+
return runtimes
97+
5798
def discover_entrypoints(self) -> list[str]:
5899
"""Return all available entrypoints."""
59100
return [
60-
ENTRYPOINT_CONTEXT,
101+
ENTRYPOINT_TELEMETRY,
61102
ENTRYPOINT_GREETING,
62103
ENTRYPOINT_ANALYZE_NUMBERS,
63104
ENTRYPOINT_SUPPORT_CHAT,
105+
*TEMPLATE_RUNTIMES.keys(),
64106
]
65107

66108
async def dispose(self) -> None:

src/uipath/dev/_demo/mock_greeting_runtime.py renamed to demo/mock_greeting_runtime.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Mock Greeting Runtime for demonstration purposes."""
2+
13
import asyncio
24
import logging
35
from typing import Any, AsyncGenerator
@@ -21,10 +23,12 @@ class MockGreetingRuntime:
2123
"""Mock runtime that builds a greeting and simulates a small pipeline."""
2224

2325
def __init__(self, entrypoint: str = ENTRYPOINT_GREETING) -> None:
26+
"""Initialize the MockGreetingRuntime."""
2427
self.entrypoint = entrypoint
2528
self.tracer = trace.get_tracer("uipath.dev.mock.greeting")
2629

2730
async def get_schema(self) -> UiPathRuntimeSchema:
31+
"""Get the schema for the greeting runtime."""
2832
return UiPathRuntimeSchema(
2933
filePath=self.entrypoint,
3034
uniqueId="mock-greeting-runtime",
@@ -62,6 +66,7 @@ async def execute(
6266
input: dict[str, Any] | None = None,
6367
options: UiPathExecuteOptions | None = None,
6468
) -> UiPathRuntimeResult:
69+
"""Execute the greeting runtime."""
6570
payload = input or {}
6671
name = str(payload.get("name", "world")).strip() or "world"
6772
excited = bool(payload.get("excited", True))
@@ -124,8 +129,10 @@ async def stream(
124129
input: dict[str, Any] | None = None,
125130
options: UiPathStreamOptions | None = None,
126131
) -> AsyncGenerator[UiPathRuntimeEvent, None]:
132+
"""Stream events from the greeting runtime."""
127133
logger.info("GreetingRuntime: stream() invoked")
128134
yield await self.execute(input=input, options=options)
129135

130136
async def dispose(self) -> None:
137+
"""Dispose of any resources used by the greeting runtime."""
131138
logger.info("GreetingRuntime: dispose() invoked")

src/uipath/dev/_demo/mock_numbers_runtime.py renamed to demo/mock_numbers_runtime.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""An example mock runtime that analyzes numbers."""
2+
13
import asyncio
24
import logging
35
from typing import Any, AsyncGenerator
@@ -12,7 +14,7 @@
1214
)
1315
from uipath.runtime.schema import UiPathRuntimeSchema
1416

15-
ENTRYPOINT_ANALYZE_NUMBERS = "analytics/numbers.py:analyze"
17+
ENTRYPOINT_ANALYZE_NUMBERS = "agent/numbers.py:analyze"
1618

1719
logger = logging.getLogger(__name__)
1820

@@ -21,10 +23,12 @@ class MockNumberAnalyticsRuntime:
2123
"""Mock runtime that analyzes a list of numbers."""
2224

2325
def __init__(self, entrypoint: str = ENTRYPOINT_ANALYZE_NUMBERS) -> None:
26+
"""Initialize the MockNumberAnalyticsRuntime."""
2427
self.entrypoint = entrypoint
2528
self.tracer = trace.get_tracer("uipath.dev.mock.number-analytics")
2629

2730
async def get_schema(self) -> UiPathRuntimeSchema:
31+
"""Get the schema for the number analytics runtime."""
2832
return UiPathRuntimeSchema(
2933
filePath=self.entrypoint,
3034
uniqueId="mock-number-analytics-runtime",
@@ -61,6 +65,7 @@ async def execute(
6165
input: dict[str, Any] | None = None,
6266
options: UiPathExecuteOptions | None = None,
6367
) -> UiPathRuntimeResult:
68+
"""Execute the number analytics runtime."""
6469
payload = input or {}
6570
numbers = payload.get("numbers") or []
6671
operation = str(payload.get("operation", "sum")).lower()
@@ -137,8 +142,10 @@ async def stream(
137142
input: dict[str, Any] | None = None,
138143
options: UiPathStreamOptions | None = None,
139144
) -> AsyncGenerator[UiPathRuntimeEvent, None]:
145+
"""Stream events from the number analytics runtime."""
140146
logger.info("NumberAnalyticsRuntime: stream() invoked")
141147
yield await self.execute(input=input, options=options)
142148

143149
async def dispose(self) -> None:
150+
"""Dispose of any resources used by the number analytics runtime."""
144151
logger.info("NumberAnalyticsRuntime: dispose() invoked")

src/uipath/dev/_demo/mock_support_runtime.py renamed to demo/mock_support_runtime.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Mock runtime that simulates a support chat agent."""
2+
13
import asyncio
24
import logging
35
from typing import Any, AsyncGenerator
@@ -12,7 +14,7 @@
1214
)
1315
from uipath.runtime.schema import UiPathRuntimeSchema
1416

15-
ENTRYPOINT_SUPPORT_CHAT = "agent/support.py:chat"
17+
ENTRYPOINT_SUPPORT_CHAT = "agent/support.py:main"
1618

1719
logger = logging.getLogger(__name__)
1820

@@ -21,10 +23,12 @@ class MockSupportChatRuntime:
2123
"""Mock runtime that simulates a tiny support agent."""
2224

2325
def __init__(self, entrypoint: str = ENTRYPOINT_SUPPORT_CHAT) -> None:
26+
"""Initialize the MockSupportChatRuntime."""
2427
self.entrypoint = entrypoint
2528
self.tracer = trace.get_tracer("uipath.dev.mock.support-chat")
2629

2730
async def get_schema(self) -> UiPathRuntimeSchema:
31+
"""Get the schema for the support chat runtime."""
2832
return UiPathRuntimeSchema(
2933
filePath=self.entrypoint,
3034
uniqueId="mock-support-chat-runtime",
@@ -60,6 +64,7 @@ async def execute(
6064
input: dict[str, Any] | None = None,
6165
options: UiPathExecuteOptions | None = None,
6266
) -> UiPathRuntimeResult:
67+
"""Execute the support chat runtime."""
6368
payload = input or {}
6469
message = str(payload.get("message", "")).strip()
6570
previous = payload.get("previousIssues") or []
@@ -139,8 +144,10 @@ async def stream(
139144
input: dict[str, Any] | None = None,
140145
options: UiPathStreamOptions | None = None,
141146
) -> AsyncGenerator[UiPathRuntimeEvent, None]:
147+
"""Stream events from the support chat runtime."""
142148
logger.info("SupportChatRuntime: stream() invoked")
143149
yield await self.execute(input=input, options=options)
144150

145151
async def dispose(self) -> None:
152+
"""Dispose of any resources used by the support chat runtime."""
146153
logger.info("SupportChatRuntime: dispose() invoked")

src/uipath/dev/_demo/mock_context_runtime.py renamed to demo/mock_telemetry_runtime.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Mock runtime that simulates a multi-step workflow with rich telemetry."""
2+
13
import asyncio
24
import logging
35
from typing import Any, AsyncGenerator
@@ -10,17 +12,19 @@
1012
UiPathRuntimeStatus,
1113
UiPathStreamOptions,
1214
)
15+
from uipath.runtime.debug import UiPathBreakpointResult
1316
from uipath.runtime.schema import UiPathRuntimeSchema
1417

15-
ENTRYPOINT_CONTEXT = "agent/context.py:run"
18+
ENTRYPOINT_TELEMETRY = "agent/telemetry.py:run"
1619

1720
logger = logging.getLogger(__name__)
1821

1922

20-
class MockContextRuntime:
23+
class MockTelemetryRuntime:
2124
"""A mock runtime that simulates a multi-step workflow with rich telemetry."""
2225

23-
def __init__(self, entrypoint: str = ENTRYPOINT_CONTEXT) -> None:
26+
def __init__(self, entrypoint: str = ENTRYPOINT_TELEMETRY) -> None:
27+
"""Initialize the MockTelemetryRuntime."""
2428
self.entrypoint = entrypoint
2529
self.tracer = trace.get_tracer("uipath.dev.mock.context")
2630
# State tracking for breakpoints
@@ -39,6 +43,7 @@ def __init__(self, entrypoint: str = ENTRYPOINT_CONTEXT) -> None:
3943
]
4044

4145
async def get_schema(self) -> UiPathRuntimeSchema:
46+
"""Get the schema for the mock telemetry runtime."""
4247
return UiPathRuntimeSchema(
4348
filePath=self.entrypoint,
4449
uniqueId="mock-runtime",
@@ -60,8 +65,7 @@ async def execute(
6065
input: dict[str, Any] | None = None,
6166
options: UiPathExecuteOptions | None = None,
6267
) -> UiPathRuntimeResult:
63-
from uipath.runtime.debug import UiPathBreakpointResult
64-
68+
"""Execute the mock telemetry runtime."""
6569
payload = input or {}
6670
entrypoint = "mock-entrypoint"
6771
message = str(payload.get("message", ""))
@@ -454,10 +458,12 @@ async def stream(
454458
input: dict[str, Any] | None = None,
455459
options: UiPathStreamOptions | None = None,
456460
) -> AsyncGenerator[UiPathRuntimeEvent, None]:
461+
"""Stream events from the mock telemetry runtime."""
457462
logger.info("MockRuntime: stream() invoked")
458463
print("[MockRuntime] stream() invoked")
459464
yield await self.execute(input=input, options=options)
460465

461466
async def dispose(self) -> None:
467+
"""Dispose of any resources used by the mock telemetry runtime."""
462468
logger.info("MockRuntime: dispose() invoked")
463469
print("[MockRuntime] dispose() invoked")

0 commit comments

Comments
 (0)