uipath 2.1.81__py3-none-any.whl → 2.1.83__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of uipath might be problematic. Click here for more details.
- uipath/_cli/_auth/_auth_server.py +15 -12
- uipath/_cli/_auth/_auth_service.py +9 -3
- uipath/_cli/_auth/_oidc_utils.py +4 -8
- uipath/_cli/_evals/_runtime.py +38 -6
- uipath/_cli/_evals/_span_collection.py +24 -0
- uipath/_cli/_evals/mocks/llm_mocker.py +16 -2
- uipath/_cli/_evals/mocks/mocks.py +25 -6
- uipath/telemetry/_track.py +1 -0
- uipath/tracing/_utils.py +52 -0
- {uipath-2.1.81.dist-info → uipath-2.1.83.dist-info}/METADATA +1 -1
- {uipath-2.1.81.dist-info → uipath-2.1.83.dist-info}/RECORD +14 -13
- {uipath-2.1.81.dist-info → uipath-2.1.83.dist-info}/WHEEL +0 -0
- {uipath-2.1.81.dist-info → uipath-2.1.83.dist-info}/entry_points.txt +0 -0
- {uipath-2.1.81.dist-info → uipath-2.1.83.dist-info}/licenses/LICENSE +0 -0
|
@@ -7,8 +7,6 @@ import threading
|
|
|
7
7
|
import time
|
|
8
8
|
from typing import Optional
|
|
9
9
|
|
|
10
|
-
from ._oidc_utils import OidcUtils
|
|
11
|
-
|
|
12
10
|
# Server port
|
|
13
11
|
PORT = 6234
|
|
14
12
|
|
|
@@ -22,7 +20,9 @@ class TokenReceivedSignal(Exception):
|
|
|
22
20
|
super().__init__("Token received successfully")
|
|
23
21
|
|
|
24
22
|
|
|
25
|
-
def make_request_handler_class(
|
|
23
|
+
def make_request_handler_class(
|
|
24
|
+
state, code_verifier, token_callback, domain, redirect_uri, client_id
|
|
25
|
+
):
|
|
26
26
|
class SimpleHTTPSRequestHandler(http.server.SimpleHTTPRequestHandler):
|
|
27
27
|
"""Simple HTTPS request handler that serves static files."""
|
|
28
28
|
|
|
@@ -73,16 +73,10 @@ def make_request_handler_class(state, code_verifier, token_callback, domain):
|
|
|
73
73
|
with open(index_path, "r") as f:
|
|
74
74
|
content = f.read()
|
|
75
75
|
|
|
76
|
-
# Get the redirect URI from auth config
|
|
77
|
-
auth_config = OidcUtils.get_auth_config()
|
|
78
|
-
redirect_uri = auth_config["redirect_uri"]
|
|
79
|
-
|
|
80
76
|
content = content.replace("__PY_REPLACE_EXPECTED_STATE__", state)
|
|
81
77
|
content = content.replace("__PY_REPLACE_CODE_VERIFIER__", code_verifier)
|
|
82
78
|
content = content.replace("__PY_REPLACE_REDIRECT_URI__", redirect_uri)
|
|
83
|
-
content = content.replace(
|
|
84
|
-
"__PY_REPLACE_CLIENT_ID__", auth_config["client_id"]
|
|
85
|
-
)
|
|
79
|
+
content = content.replace("__PY_REPLACE_CLIENT_ID__", client_id)
|
|
86
80
|
content = content.replace("__PY_REPLACE_DOMAIN__", domain)
|
|
87
81
|
|
|
88
82
|
self.send_response(200)
|
|
@@ -107,14 +101,18 @@ def make_request_handler_class(state, code_verifier, token_callback, domain):
|
|
|
107
101
|
|
|
108
102
|
|
|
109
103
|
class HTTPServer:
|
|
110
|
-
def __init__(self, port=6234):
|
|
104
|
+
def __init__(self, port=6234, redirect_uri=None, client_id=None):
|
|
111
105
|
"""Initialize HTTP server with configurable parameters.
|
|
112
106
|
|
|
113
107
|
Args:
|
|
114
108
|
port (int, optional): Port number to run the server on. Defaults to 6234.
|
|
109
|
+
redirect_uri (str, optional): OAuth redirect URI. Defaults to None.
|
|
110
|
+
client_id (str, optional): OAuth client ID. Defaults to None.
|
|
115
111
|
"""
|
|
116
112
|
self.current_path = os.path.dirname(os.path.abspath(__file__))
|
|
117
113
|
self.port = port
|
|
114
|
+
self.redirect_uri = redirect_uri
|
|
115
|
+
self.client_id = client_id
|
|
118
116
|
self.httpd: Optional[socketserver.TCPServer] = None
|
|
119
117
|
self.token_data = None
|
|
120
118
|
self.should_shutdown = False
|
|
@@ -145,7 +143,12 @@ class HTTPServer:
|
|
|
145
143
|
# Create server with address reuse
|
|
146
144
|
socketserver.TCPServer.allow_reuse_address = True
|
|
147
145
|
handler = make_request_handler_class(
|
|
148
|
-
state,
|
|
146
|
+
state,
|
|
147
|
+
code_verifier,
|
|
148
|
+
self.token_received_callback,
|
|
149
|
+
domain,
|
|
150
|
+
self.redirect_uri,
|
|
151
|
+
self.client_id,
|
|
149
152
|
)
|
|
150
153
|
self.httpd = socketserver.TCPServer(("", self.port), handler)
|
|
151
154
|
return self.httpd
|
|
@@ -121,11 +121,17 @@ class AuthService:
|
|
|
121
121
|
return False
|
|
122
122
|
|
|
123
123
|
def _perform_oauth_flow(self) -> TokenData:
|
|
124
|
-
|
|
124
|
+
auth_config = OidcUtils.get_auth_config()
|
|
125
|
+
auth_url, code_verifier, state = OidcUtils.get_auth_url(
|
|
126
|
+
self._domain, auth_config
|
|
127
|
+
)
|
|
125
128
|
self._open_browser(auth_url)
|
|
126
129
|
|
|
127
|
-
|
|
128
|
-
|
|
130
|
+
server = HTTPServer(
|
|
131
|
+
port=auth_config["port"],
|
|
132
|
+
redirect_uri=auth_config["redirect_uri"],
|
|
133
|
+
client_id=auth_config["client_id"],
|
|
134
|
+
)
|
|
129
135
|
token_data = asyncio.run(server.start(state, code_verifier, self._domain))
|
|
130
136
|
|
|
131
137
|
if not token_data:
|
uipath/_cli/_auth/_oidc_utils.py
CHANGED
|
@@ -49,12 +49,8 @@ class OidcUtils:
|
|
|
49
49
|
) as f:
|
|
50
50
|
auth_config = json.load(f)
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
int(auth_config.get("portOptionOne", 8104)),
|
|
55
|
-
int(auth_config.get("portOptionTwo", 8055)),
|
|
56
|
-
int(auth_config.get("portOptionThree", 42042)),
|
|
57
|
-
]
|
|
52
|
+
custom_port = os.getenv("UIPATH_AUTH_PORT")
|
|
53
|
+
candidates = [int(custom_port)] if custom_port else [8104, 8055, 42042]
|
|
58
54
|
|
|
59
55
|
port = cls._find_free_port(candidates)
|
|
60
56
|
if port is None:
|
|
@@ -75,11 +71,12 @@ class OidcUtils:
|
|
|
75
71
|
)
|
|
76
72
|
|
|
77
73
|
@classmethod
|
|
78
|
-
def get_auth_url(cls, domain: str) -> tuple[str, str, str]:
|
|
74
|
+
def get_auth_url(cls, domain: str, auth_config: AuthConfig) -> tuple[str, str, str]:
|
|
79
75
|
"""Get the authorization URL for OAuth2 PKCE flow.
|
|
80
76
|
|
|
81
77
|
Args:
|
|
82
78
|
domain (str): The UiPath domain to authenticate against (e.g. 'alpha', 'cloud')
|
|
79
|
+
auth_config (AuthConfig): The authentication configuration to use
|
|
83
80
|
|
|
84
81
|
Returns:
|
|
85
82
|
tuple[str, str]: A tuple containing:
|
|
@@ -87,7 +84,6 @@ class OidcUtils:
|
|
|
87
84
|
- The code verifier for PKCE flow
|
|
88
85
|
"""
|
|
89
86
|
code_verifier, code_challenge = generate_code_verifier_and_challenge()
|
|
90
|
-
auth_config = cls.get_auth_config()
|
|
91
87
|
state = get_state_param()
|
|
92
88
|
query_params = {
|
|
93
89
|
"client_id": auth_config["client_id"],
|
uipath/_cli/_evals/_runtime.py
CHANGED
|
@@ -7,7 +7,8 @@ from pathlib import Path
|
|
|
7
7
|
from time import time
|
|
8
8
|
from typing import Any, Dict, Generic, List, Optional, Sequence, TypeVar
|
|
9
9
|
|
|
10
|
-
from opentelemetry
|
|
10
|
+
from opentelemetry import context as context_api
|
|
11
|
+
from opentelemetry.sdk.trace import ReadableSpan, Span
|
|
11
12
|
from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
|
|
12
13
|
|
|
13
14
|
from ..._events._event_bus import EventBus
|
|
@@ -24,6 +25,7 @@ from ...eval.models import EvaluationResult
|
|
|
24
25
|
from ...eval.models.models import AgentExecution, EvalItemResult
|
|
25
26
|
from .._runtime._contracts import (
|
|
26
27
|
UiPathBaseRuntime,
|
|
28
|
+
UiPathExecutionBatchTraceProcessor,
|
|
27
29
|
UiPathRuntimeContext,
|
|
28
30
|
UiPathRuntimeFactory,
|
|
29
31
|
UiPathRuntimeResult,
|
|
@@ -41,7 +43,11 @@ from ._models._output import (
|
|
|
41
43
|
UiPathEvalOutput,
|
|
42
44
|
UiPathEvalRunExecutionOutput,
|
|
43
45
|
)
|
|
44
|
-
from .
|
|
46
|
+
from ._span_collection import ExecutionSpanCollector
|
|
47
|
+
from .mocks.mocks import (
|
|
48
|
+
clear_execution_context,
|
|
49
|
+
set_execution_context,
|
|
50
|
+
)
|
|
45
51
|
|
|
46
52
|
T = TypeVar("T", bound=UiPathBaseRuntime)
|
|
47
53
|
C = TypeVar("C", bound=UiPathRuntimeContext)
|
|
@@ -78,6 +84,24 @@ class ExecutionSpanExporter(SpanExporter):
|
|
|
78
84
|
self.clear()
|
|
79
85
|
|
|
80
86
|
|
|
87
|
+
class ExecutionSpanProcessor(UiPathExecutionBatchTraceProcessor):
|
|
88
|
+
"""Span processor that adds spans to ExecutionSpanCollector when they start."""
|
|
89
|
+
|
|
90
|
+
def __init__(self, span_exporter: SpanExporter, collector: ExecutionSpanCollector):
|
|
91
|
+
super().__init__(span_exporter)
|
|
92
|
+
self.collector = collector
|
|
93
|
+
|
|
94
|
+
def on_start(
|
|
95
|
+
self, span: Span, parent_context: Optional[context_api.Context] = None
|
|
96
|
+
) -> None:
|
|
97
|
+
super().on_start(span, parent_context)
|
|
98
|
+
|
|
99
|
+
if span.attributes and "execution.id" in span.attributes:
|
|
100
|
+
exec_id = span.attributes["execution.id"]
|
|
101
|
+
if isinstance(exec_id, str):
|
|
102
|
+
self.collector.add_span(span, exec_id)
|
|
103
|
+
|
|
104
|
+
|
|
81
105
|
class ExecutionLogsExporter:
|
|
82
106
|
"""Custom exporter that stores multiple execution log handlers."""
|
|
83
107
|
|
|
@@ -127,8 +151,15 @@ class UiPathEvalRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
|
127
151
|
self.context: UiPathEvalContext = context
|
|
128
152
|
self.factory: UiPathRuntimeFactory[T, C] = factory
|
|
129
153
|
self.event_bus: EventBus = event_bus
|
|
154
|
+
|
|
130
155
|
self.span_exporter: ExecutionSpanExporter = ExecutionSpanExporter()
|
|
131
|
-
self.
|
|
156
|
+
self.span_collector: ExecutionSpanCollector = ExecutionSpanCollector()
|
|
157
|
+
|
|
158
|
+
# Span processor feeds both exporter and collector
|
|
159
|
+
span_processor = ExecutionSpanProcessor(self.span_exporter, self.span_collector)
|
|
160
|
+
self.factory.tracer_span_processors.append(span_processor)
|
|
161
|
+
self.factory.tracer_provider.add_span_processor(span_processor)
|
|
162
|
+
|
|
132
163
|
self.logs_exporter: ExecutionLogsExporter = ExecutionLogsExporter()
|
|
133
164
|
self.execution_id = str(uuid.uuid4())
|
|
134
165
|
|
|
@@ -180,7 +211,6 @@ class UiPathEvalRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
|
180
211
|
evaluation_set_name=evaluation_set.name,
|
|
181
212
|
evaluation_set_results=eval_run_result_list,
|
|
182
213
|
)
|
|
183
|
-
|
|
184
214
|
# Computing evaluator averages
|
|
185
215
|
evaluator_averages: Dict[str, float] = defaultdict(float)
|
|
186
216
|
evaluator_count: Dict[str, int] = defaultdict(int)
|
|
@@ -194,7 +224,6 @@ class UiPathEvalRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
|
194
224
|
evaluator_averages[eval_id] = (
|
|
195
225
|
evaluator_averages[eval_id] / evaluator_count[eval_id]
|
|
196
226
|
)
|
|
197
|
-
|
|
198
227
|
await event_bus.publish(
|
|
199
228
|
EvaluationEvents.UPDATE_EVAL_SET_RUN,
|
|
200
229
|
EvalSetRunUpdatedEvent(
|
|
@@ -289,7 +318,7 @@ class UiPathEvalRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
|
289
318
|
evaluators: List[BaseEvaluator[Any]],
|
|
290
319
|
event_bus: EventBus,
|
|
291
320
|
) -> EvaluationRunResult:
|
|
292
|
-
|
|
321
|
+
set_execution_context(eval_item, self.span_collector)
|
|
293
322
|
|
|
294
323
|
await event_bus.publish(
|
|
295
324
|
EvaluationEvents.CREATE_EVAL_RUN,
|
|
@@ -383,6 +412,8 @@ class UiPathEvalRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
|
383
412
|
eval_run_updated_event,
|
|
384
413
|
wait_for_completion=False,
|
|
385
414
|
)
|
|
415
|
+
finally:
|
|
416
|
+
clear_execution_context()
|
|
386
417
|
|
|
387
418
|
return evaluation_run_results
|
|
388
419
|
|
|
@@ -391,6 +422,7 @@ class UiPathEvalRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
|
391
422
|
) -> tuple[List[ReadableSpan], list[logging.LogRecord]]:
|
|
392
423
|
spans = self.span_exporter.get_spans(execution_id)
|
|
393
424
|
self.span_exporter.clear(execution_id)
|
|
425
|
+
self.span_collector.clear(execution_id)
|
|
394
426
|
|
|
395
427
|
logs = self.logs_exporter.get_logs(execution_id)
|
|
396
428
|
self.logs_exporter.clear(execution_id)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from collections import defaultdict
|
|
2
|
+
from typing import Dict, List, Optional
|
|
3
|
+
|
|
4
|
+
from opentelemetry.sdk.trace import ReadableSpan, Span
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ExecutionSpanCollector:
|
|
8
|
+
"""Collects spans as they are created during execution."""
|
|
9
|
+
|
|
10
|
+
def __init__(self):
|
|
11
|
+
# { execution_id -> list of spans }
|
|
12
|
+
self._spans: Dict[str, List[ReadableSpan]] = defaultdict(list)
|
|
13
|
+
|
|
14
|
+
def add_span(self, span: Span, execution_id: str) -> None:
|
|
15
|
+
self._spans[execution_id].append(span)
|
|
16
|
+
|
|
17
|
+
def get_spans(self, execution_id: str) -> List[ReadableSpan]:
|
|
18
|
+
return self._spans.get(execution_id, [])
|
|
19
|
+
|
|
20
|
+
def clear(self, execution_id: Optional[str] = None) -> None:
|
|
21
|
+
if execution_id:
|
|
22
|
+
self._spans.pop(execution_id, None)
|
|
23
|
+
else:
|
|
24
|
+
self._spans.clear()
|
|
@@ -6,6 +6,9 @@ from typing import Any, Callable
|
|
|
6
6
|
|
|
7
7
|
from pydantic import BaseModel
|
|
8
8
|
|
|
9
|
+
from uipath.tracing._traced import traced
|
|
10
|
+
from uipath.tracing._utils import _SpanUtils
|
|
11
|
+
|
|
9
12
|
from .._models._evaluation_set import (
|
|
10
13
|
EvaluationItem,
|
|
11
14
|
LLMMockingStrategy,
|
|
@@ -51,7 +54,7 @@ Based on the above information, provide a realistic response for this tool call.
|
|
|
51
54
|
3. Always include the entire output regardless of token length.
|
|
52
55
|
3. Consider the context of the current test run and the agent being tested. If the agent is acting on a property, make sure the output includes that property.
|
|
53
56
|
|
|
54
|
-
Respond ONLY with valid JSON that would be a realistic and
|
|
57
|
+
Respond ONLY with valid JSON that would be a realistic and complete tool response. Do not include any explanations or markdown.
|
|
55
58
|
"""
|
|
56
59
|
|
|
57
60
|
logger = logging.getLogger(__name__)
|
|
@@ -79,6 +82,7 @@ class LLMMocker(Mocker):
|
|
|
79
82
|
self.evaluation_item = evaluation_item
|
|
80
83
|
assert isinstance(self.evaluation_item.mocking_strategy, LLMMockingStrategy)
|
|
81
84
|
|
|
85
|
+
@traced(name="__mocker__")
|
|
82
86
|
async def response(
|
|
83
87
|
self, func: Callable[[T], R], params: dict[str, Any], *args: T, **kwargs
|
|
84
88
|
) -> R:
|
|
@@ -92,6 +96,8 @@ class LLMMocker(Mocker):
|
|
|
92
96
|
from uipath import UiPath
|
|
93
97
|
from uipath._services.llm_gateway_service import _cleanup_schema
|
|
94
98
|
|
|
99
|
+
from .mocks import evaluation_context, span_collector_context
|
|
100
|
+
|
|
95
101
|
llm = UiPath().llm
|
|
96
102
|
return_type: Any = func.__annotations__.get("return", None)
|
|
97
103
|
if return_type is None:
|
|
@@ -116,9 +122,17 @@ class LLMMocker(Mocker):
|
|
|
116
122
|
example_calls = [
|
|
117
123
|
call for call in example_calls if isinstance(call, ExampleCall)
|
|
118
124
|
]
|
|
125
|
+
|
|
126
|
+
test_run_history = "(empty)"
|
|
127
|
+
eval_item = evaluation_context.get()
|
|
128
|
+
span_collector = span_collector_context.get()
|
|
129
|
+
if eval_item and span_collector:
|
|
130
|
+
spans = span_collector.get_spans(eval_item.id)
|
|
131
|
+
test_run_history = _SpanUtils.spans_to_llm_context(spans)
|
|
132
|
+
|
|
119
133
|
prompt_input: dict[str, Any] = {
|
|
120
134
|
"toolRunExamples": example_calls,
|
|
121
|
-
"testRunHistory":
|
|
135
|
+
"testRunHistory": test_run_history,
|
|
122
136
|
"toolInfo": {
|
|
123
137
|
"name": function_name,
|
|
124
138
|
"description": params.get("description"),
|
|
@@ -5,30 +5,49 @@ from contextvars import ContextVar
|
|
|
5
5
|
from typing import Any, Callable, Optional
|
|
6
6
|
|
|
7
7
|
from uipath._cli._evals._models._evaluation_set import EvaluationItem
|
|
8
|
+
from uipath._cli._evals._span_collection import ExecutionSpanCollector
|
|
8
9
|
from uipath._cli._evals.mocks.mocker import Mocker, UiPathNoMockFoundError
|
|
9
10
|
from uipath._cli._evals.mocks.mocker_factory import MockerFactory
|
|
10
11
|
|
|
12
|
+
# Context variables for evaluation items and mockers
|
|
11
13
|
evaluation_context: ContextVar[Optional[EvaluationItem]] = ContextVar(
|
|
12
14
|
"evaluation", default=None
|
|
13
15
|
)
|
|
14
16
|
|
|
15
17
|
mocker_context: ContextVar[Optional[Mocker]] = ContextVar("mocker", default=None)
|
|
16
18
|
|
|
19
|
+
# Span collector for trace access during mocking
|
|
20
|
+
span_collector_context: ContextVar[Optional[ExecutionSpanCollector]] = ContextVar(
|
|
21
|
+
"span_collector", default=None
|
|
22
|
+
)
|
|
23
|
+
|
|
17
24
|
logger = logging.getLogger(__name__)
|
|
18
25
|
|
|
19
26
|
|
|
20
|
-
def
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
def set_execution_context(
|
|
28
|
+
eval_item: EvaluationItem, span_collector: ExecutionSpanCollector
|
|
29
|
+
) -> None:
|
|
30
|
+
"""Set the execution context for an evaluation run for mocking and trace access."""
|
|
31
|
+
evaluation_context.set(eval_item)
|
|
32
|
+
|
|
23
33
|
try:
|
|
24
|
-
if
|
|
25
|
-
mocker_context.set(MockerFactory.create(
|
|
34
|
+
if eval_item.mocking_strategy:
|
|
35
|
+
mocker_context.set(MockerFactory.create(eval_item))
|
|
26
36
|
else:
|
|
27
37
|
mocker_context.set(None)
|
|
28
38
|
except Exception:
|
|
29
|
-
logger.warning(f"Failed to create mocker for evaluation {
|
|
39
|
+
logger.warning(f"Failed to create mocker for evaluation {eval_item.name}")
|
|
30
40
|
mocker_context.set(None)
|
|
31
41
|
|
|
42
|
+
span_collector_context.set(span_collector)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def clear_execution_context() -> None:
|
|
46
|
+
"""Clear the execution context after evaluation completes."""
|
|
47
|
+
evaluation_context.set(None)
|
|
48
|
+
mocker_context.set(None)
|
|
49
|
+
span_collector_context.set(None)
|
|
50
|
+
|
|
32
51
|
|
|
33
52
|
async def get_mocked_response(
|
|
34
53
|
func: Callable[[Any], Any], params: dict[str, Any], *args, **kwargs
|
uipath/telemetry/_track.py
CHANGED
uipath/tracing/_utils.py
CHANGED
|
@@ -319,3 +319,55 @@ class _SpanUtils:
|
|
|
319
319
|
f"Error formatting arguments for trace: {e}. Using args and kwargs directly."
|
|
320
320
|
)
|
|
321
321
|
return {"args": args, "kwargs": kwargs}
|
|
322
|
+
|
|
323
|
+
@staticmethod
|
|
324
|
+
def _has_ancestor_with_name(
|
|
325
|
+
span: ReadableSpan, ancestor_name: str, span_map: Dict[int, ReadableSpan]
|
|
326
|
+
) -> bool:
|
|
327
|
+
"""Check if this span or any of its ancestors has a given name."""
|
|
328
|
+
if span.name == ancestor_name:
|
|
329
|
+
return True
|
|
330
|
+
|
|
331
|
+
current = span
|
|
332
|
+
while current.parent is not None:
|
|
333
|
+
parent_span = span_map.get(current.parent.span_id)
|
|
334
|
+
if parent_span is None:
|
|
335
|
+
break
|
|
336
|
+
if parent_span.name == ancestor_name:
|
|
337
|
+
return True
|
|
338
|
+
current = parent_span
|
|
339
|
+
|
|
340
|
+
return False
|
|
341
|
+
|
|
342
|
+
@staticmethod
|
|
343
|
+
def spans_to_llm_context(spans: list[ReadableSpan]) -> str:
|
|
344
|
+
"""Convert spans to a formatted conversation history string suitable for LLM context.
|
|
345
|
+
|
|
346
|
+
Includes function calls (including LLM calls) with their inputs and outputs.
|
|
347
|
+
"""
|
|
348
|
+
# Build span_id -> span map for parent chain traversal
|
|
349
|
+
span_map = {span.get_span_context().span_id: span for span in spans}
|
|
350
|
+
|
|
351
|
+
history = []
|
|
352
|
+
for span in spans:
|
|
353
|
+
attributes = dict(span.attributes) if span.attributes else {}
|
|
354
|
+
|
|
355
|
+
input_value = attributes.get("input.value")
|
|
356
|
+
output_value = attributes.get("output.value")
|
|
357
|
+
|
|
358
|
+
if not input_value or not output_value:
|
|
359
|
+
continue
|
|
360
|
+
|
|
361
|
+
# Skip spans that are internal LLM calls (eg. for tool mocking in evals)
|
|
362
|
+
if _SpanUtils._has_ancestor_with_name(span, "__mocker__", span_map):
|
|
363
|
+
continue
|
|
364
|
+
|
|
365
|
+
history.append(f"Function: {span.name}")
|
|
366
|
+
history.append(f"Input: {input_value}")
|
|
367
|
+
history.append(f"Output: {output_value}")
|
|
368
|
+
history.append("")
|
|
369
|
+
|
|
370
|
+
if not history:
|
|
371
|
+
return "(empty)"
|
|
372
|
+
|
|
373
|
+
return "\n".join(history)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: uipath
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.83
|
|
4
4
|
Summary: Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools.
|
|
5
5
|
Project-URL: Homepage, https://uipath.com
|
|
6
6
|
Project-URL: Repository, https://github.com/UiPath/uipath-python
|
|
@@ -20,10 +20,10 @@ uipath/_cli/cli_push.py,sha256=-j-gDIbT8GyU2SybLQqFl5L8KI9nu3CDijVtltDgX20,3132
|
|
|
20
20
|
uipath/_cli/cli_run.py,sha256=1FKv20EjxrrP1I5rNSnL_HzbWtOAIMjB3M--4RPA_Yo,3709
|
|
21
21
|
uipath/_cli/middlewares.py,sha256=0D9a-wphyetnH9T97F08o7-1OKWF1lMweFHHAR0xiOw,4979
|
|
22
22
|
uipath/_cli/spinner.py,sha256=bS-U_HA5yne11ejUERu7CQoXmWdabUD2bm62EfEdV8M,1107
|
|
23
|
-
uipath/_cli/_auth/_auth_server.py,sha256=
|
|
24
|
-
uipath/_cli/_auth/_auth_service.py,sha256=
|
|
23
|
+
uipath/_cli/_auth/_auth_server.py,sha256=v_b8KNwn0tAv8jxpeKdllOVzl31q9AcdwpE_koAK_w4,7235
|
|
24
|
+
uipath/_cli/_auth/_auth_service.py,sha256=gyOtaHnDmjYccW0R1HVmFgV69a7w53Dx1Mq-PM0uVag,5405
|
|
25
25
|
uipath/_cli/_auth/_models.py,sha256=kWhqd5FqBo_oi3DW2x1IaJHsEloXq0I24f-pX5zb_O4,753
|
|
26
|
-
uipath/_cli/_auth/_oidc_utils.py,sha256=
|
|
26
|
+
uipath/_cli/_auth/_oidc_utils.py,sha256=qGpognkz-Ks-8pt-QabSNTix5HE06lQpY3WZxptoJUE,3394
|
|
27
27
|
uipath/_cli/_auth/_portal_service.py,sha256=sq3Ls7v8Q1gQWbYlE37_p82gLYPhC_cXJRTuIxMsCPU,7997
|
|
28
28
|
uipath/_cli/_auth/_url_utils.py,sha256=MuMYesMQDgetLBzkwd19dPxw3fctys7EVpByDUQMyLE,2844
|
|
29
29
|
uipath/_cli/_auth/_utils.py,sha256=To4Ara_UF4g7nzUfKqFA11lTjhQWIZWNm4xwa5nNKmU,896
|
|
@@ -46,7 +46,8 @@ uipath/_cli/_dev/_terminal/_utils/_logger.py,sha256=_ipTl_oAiMF9I7keGt2AAFAMz40D
|
|
|
46
46
|
uipath/_cli/_evals/_console_progress_reporter.py,sha256=HgB6pdMyoS6YVwuI3EpM2LBcH3U69nrdaTyNgPG8ssg,9304
|
|
47
47
|
uipath/_cli/_evals/_evaluator_factory.py,sha256=Gycv94VtGOpMir_Gba-UoiAyrSRfbSfe8_pTfjzcA9Q,3875
|
|
48
48
|
uipath/_cli/_evals/_progress_reporter.py,sha256=kX7rNSa-QCLXIzK-vb9Jjf-XLEtucdeiQPgPlSkpp2U,16778
|
|
49
|
-
uipath/_cli/_evals/_runtime.py,sha256=
|
|
49
|
+
uipath/_cli/_evals/_runtime.py,sha256=5pEAh8ebQFCBGJ-wEXQ0YeEvq3MGxGxRcxrT7kU2L6k,19882
|
|
50
|
+
uipath/_cli/_evals/_span_collection.py,sha256=RoKoeDFG2XODdlgI27ionCjU7LLD_C0LJJ3gu0wab10,779
|
|
50
51
|
uipath/_cli/_evals/_models/_evaluation_set.py,sha256=TEinpTAIzy5JLkF7-JrG_623ec2Y-GN9pfz284KKL_8,4567
|
|
51
52
|
uipath/_cli/_evals/_models/_evaluator.py,sha256=fuC3UOYwPD4d_wdynHeLSCzbu82golNAnnPnxC8Y4rk,3315
|
|
52
53
|
uipath/_cli/_evals/_models/_evaluator_base_params.py,sha256=lTYKOV66tcjW85KHTyOdtF1p1VDaBNemrMAvH8bFIFc,382
|
|
@@ -55,11 +56,11 @@ uipath/_cli/_evals/_models/_mocks.py,sha256=mlD9qvdZNniuKxzY_ttJtwLVFvKGvvIukYvy
|
|
|
55
56
|
uipath/_cli/_evals/_models/_output.py,sha256=4KPgXypO2qvWsDf37KbdMGmlYgaIfBSeGgKL32J2nP0,3157
|
|
56
57
|
uipath/_cli/_evals/_models/_sw_reporting.py,sha256=tSBLQFAdOIun8eP0vsqt56K6bmCZz_uMaWI3hskg_24,536
|
|
57
58
|
uipath/_cli/_evals/mocks/__init__.py,sha256=2WXwAy_oZw5bKp6L0HB13QygCJeftOB_Bget0AI6Gik,32
|
|
58
|
-
uipath/_cli/_evals/mocks/llm_mocker.py,sha256=
|
|
59
|
+
uipath/_cli/_evals/mocks/llm_mocker.py,sha256=VrjzkeOVAJNKfkrHntQ17MBEtHZhwszEzc_uuPH3Tbc,7355
|
|
59
60
|
uipath/_cli/_evals/mocks/mocker.py,sha256=p9UpJDIckvCgkO0qqJHWdMMSbySBOoa8xpEIi2QIbhA,810
|
|
60
61
|
uipath/_cli/_evals/mocks/mocker_factory.py,sha256=V5QKSTtQxztTo4-fK1TyAaXw2Z3mHf2UC5mXqwuUGTs,811
|
|
61
62
|
uipath/_cli/_evals/mocks/mockito_mocker.py,sha256=AO2BmFwA6hz3Lte-STVr7aJDPvMCqKNKa4j2jeNZ_U4,2677
|
|
62
|
-
uipath/_cli/_evals/mocks/mocks.py,sha256=
|
|
63
|
+
uipath/_cli/_evals/mocks/mocks.py,sha256=jfenoCSnMPpaXEyAcRDVu5jIfb62eRredRenZDI_AzE,1965
|
|
63
64
|
uipath/_cli/_push/sw_file_handler.py,sha256=iE8Sk1Z-9hxmLFFj3j-k4kTK6TzNFP6hUCmxTudG6JQ,18251
|
|
64
65
|
uipath/_cli/_runtime/_contracts.py,sha256=E8Is7EQfAu7_hCbeZI68gmTxSxo4X7_U4vcSl7D3Syg,28988
|
|
65
66
|
uipath/_cli/_runtime/_escalation.py,sha256=x3vI98qsfRA-fL_tNkRVTFXioM5Gv2w0GFcXJJ5eQtg,7981
|
|
@@ -164,15 +165,15 @@ uipath/models/processes.py,sha256=bV31xTyF0hRWZmwy3bWj5L8dBD9wttWxfJjwzhjETmk,19
|
|
|
164
165
|
uipath/models/queues.py,sha256=gnbeEyYlHtdqdxBalio0lw8mq-78YBG9MPMSkv1BWOg,6934
|
|
165
166
|
uipath/telemetry/__init__.py,sha256=Wna32UFzZR66D-RzTKlPWlvji9i2HJb82NhHjCCXRjY,61
|
|
166
167
|
uipath/telemetry/_constants.py,sha256=uRDuEZayBYtBA0tMx-2AS_D-oiVA7oKgp9zid9jNats,763
|
|
167
|
-
uipath/telemetry/_track.py,sha256=
|
|
168
|
+
uipath/telemetry/_track.py,sha256=zD39zSs0sWsWnFkqf15xCLwFKu6Ic8CfjdPACTvIOoQ,4709
|
|
168
169
|
uipath/tracing/__init__.py,sha256=GKRINyWdHVrDsI-8mrZDLdf0oey6GHGlNZTOADK-kgc,224
|
|
169
170
|
uipath/tracing/_otel_exporters.py,sha256=c0GKU_oUrAwrOrqbyu64c55z1TR6xk01d3y5fLUN1lU,3215
|
|
170
171
|
uipath/tracing/_traced.py,sha256=yBIY05PCCrYyx50EIHZnwJaKNdHPNx-YTR1sHQl0a98,19901
|
|
171
|
-
uipath/tracing/_utils.py,sha256=
|
|
172
|
+
uipath/tracing/_utils.py,sha256=X-LFsyIxDeNOGuHPvkb6T5o9Y8ElYhr_rP3CEBJSu4s,13837
|
|
172
173
|
uipath/utils/__init__.py,sha256=VD-KXFpF_oWexFg6zyiWMkxl2HM4hYJMIUDZ1UEtGx0,105
|
|
173
174
|
uipath/utils/_endpoints_manager.py,sha256=iRTl5Q0XAm_YgcnMcJOXtj-8052sr6jpWuPNz6CgT0Q,8408
|
|
174
|
-
uipath-2.1.
|
|
175
|
-
uipath-2.1.
|
|
176
|
-
uipath-2.1.
|
|
177
|
-
uipath-2.1.
|
|
178
|
-
uipath-2.1.
|
|
175
|
+
uipath-2.1.83.dist-info/METADATA,sha256=0FpqZ7BXOLEsQ0jPwICiBE27Xbx9S6LS6FJo7LdgMV8,6593
|
|
176
|
+
uipath-2.1.83.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
177
|
+
uipath-2.1.83.dist-info/entry_points.txt,sha256=9C2_29U6Oq1ExFu7usihR-dnfIVNSKc-0EFbh0rskB4,43
|
|
178
|
+
uipath-2.1.83.dist-info/licenses/LICENSE,sha256=-KBavWXepyDjimmzH5fVAsi-6jNVpIKFc2kZs0Ri4ng,1058
|
|
179
|
+
uipath-2.1.83.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|