uipath-langchain 0.0.108__py3-none-any.whl → 0.0.110__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-langchain might be problematic. Click here for more details.
- uipath_langchain/tracers/AsyncUiPathTracer.py +10 -2
- uipath_langchain/tracers/__init__.py +0 -2
- {uipath_langchain-0.0.108.dist-info → uipath_langchain-0.0.110.dist-info}/METADATA +2 -2
- {uipath_langchain-0.0.108.dist-info → uipath_langchain-0.0.110.dist-info}/RECORD +7 -8
- uipath_langchain/tracers/UiPathTracer.py +0 -161
- {uipath_langchain-0.0.108.dist-info → uipath_langchain-0.0.110.dist-info}/WHEEL +0 -0
- {uipath_langchain-0.0.108.dist-info → uipath_langchain-0.0.110.dist-info}/entry_points.txt +0 -0
- {uipath_langchain-0.0.108.dist-info → uipath_langchain-0.0.110.dist-info}/licenses/LICENSE +0 -0
|
@@ -246,10 +246,18 @@ class AsyncUiPathTracer(AsyncBaseTracer):
|
|
|
246
246
|
with warnings.catch_warnings():
|
|
247
247
|
warnings.simplefilter("ignore", category=PydanticDeprecationWarning)
|
|
248
248
|
|
|
249
|
+
# Helper function to safely copy values
|
|
250
|
+
def safe_copy(value):
|
|
251
|
+
if value is None:
|
|
252
|
+
return None
|
|
253
|
+
if hasattr(value, "copy") and callable(value.copy):
|
|
254
|
+
return value.copy()
|
|
255
|
+
return value
|
|
256
|
+
|
|
249
257
|
return {
|
|
250
258
|
**run.dict(exclude={"child_runs", "inputs", "outputs", "serialized"}),
|
|
251
|
-
"inputs": run.inputs
|
|
252
|
-
"outputs": run.outputs
|
|
259
|
+
"inputs": safe_copy(run.inputs),
|
|
260
|
+
"outputs": safe_copy(run.outputs),
|
|
253
261
|
}
|
|
254
262
|
|
|
255
263
|
def _get_base_url(self) -> str:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: uipath-langchain
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.110
|
|
4
4
|
Summary: UiPath Langchain
|
|
5
5
|
Project-URL: Homepage, https://uipath.com
|
|
6
6
|
Project-URL: Repository, https://github.com/UiPath/uipath-langchain-python
|
|
@@ -24,7 +24,7 @@ Requires-Dist: langgraph>=0.2.70
|
|
|
24
24
|
Requires-Dist: openai>=1.65.5
|
|
25
25
|
Requires-Dist: pydantic-settings>=2.6.0
|
|
26
26
|
Requires-Dist: python-dotenv>=1.0.1
|
|
27
|
-
Requires-Dist: uipath<2.1.0,>=2.0.
|
|
27
|
+
Requires-Dist: uipath<2.1.0,>=2.0.55
|
|
28
28
|
Provides-Extra: langchain
|
|
29
29
|
Description-Content-Type: text/markdown
|
|
30
30
|
|
|
@@ -23,16 +23,15 @@ uipath_langchain/embeddings/__init__.py,sha256=QICtYB58ZyqFfDQrEaO8lTEgAU5NuEKlR
|
|
|
23
23
|
uipath_langchain/embeddings/embeddings.py,sha256=gntzTfwO1pHbgnXiPdfETJaaurvQWqxVUCH75VMah54,4274
|
|
24
24
|
uipath_langchain/retrievers/__init__.py,sha256=rOn7PyyHgZ4pMnXWPkGqmuBmx8eGuo-Oyndo7Wm9IUU,108
|
|
25
25
|
uipath_langchain/retrievers/context_grounding_retriever.py,sha256=YLCIwy89LhLnNqcM0YJ5mZoeNyCs5UiKD3Wly8gnW1E,2239
|
|
26
|
-
uipath_langchain/tracers/AsyncUiPathTracer.py,sha256=
|
|
27
|
-
uipath_langchain/tracers/
|
|
28
|
-
uipath_langchain/tracers/__init__.py,sha256=MwrQh6iuPXMS72S5EX0JdCAX0TKe-l7fIPGV3EG0Ssk,256
|
|
26
|
+
uipath_langchain/tracers/AsyncUiPathTracer.py,sha256=SgFLVU8ZtRaUjIiiM5jjYqlKc-4ec3tAXwZVceDM2ng,9147
|
|
27
|
+
uipath_langchain/tracers/__init__.py,sha256=bMmqGCC4DsuLUdDVM4zvmVbRLPeULZ8K9ity0GAfy_4,197
|
|
29
28
|
uipath_langchain/tracers/_events.py,sha256=CJri76SSdu7rGJIkXurJ2C5sQahfSK4E5UWwWYdEAtE,922
|
|
30
29
|
uipath_langchain/tracers/_instrument_traceable.py,sha256=0e841zVzcPWjOGtmBx0GeHbq3JoqsmWv6gVPzDOKNTM,13496
|
|
31
30
|
uipath_langchain/tracers/_utils.py,sha256=JOT1tKMdvqjMDtj2WbmbOWMeMlTXBWavxWpogX7KlRA,1543
|
|
32
31
|
uipath_langchain/vectorstores/__init__.py,sha256=w8qs1P548ud1aIcVA_QhBgf_jZDrRMK5Lono78yA8cs,114
|
|
33
32
|
uipath_langchain/vectorstores/context_grounding_vectorstore.py,sha256=eTa5sX43-ydB1pj9VNHUPbB-hC36fZK_CGrNe5U2Nrw,9393
|
|
34
|
-
uipath_langchain-0.0.
|
|
35
|
-
uipath_langchain-0.0.
|
|
36
|
-
uipath_langchain-0.0.
|
|
37
|
-
uipath_langchain-0.0.
|
|
38
|
-
uipath_langchain-0.0.
|
|
33
|
+
uipath_langchain-0.0.110.dist-info/METADATA,sha256=hgEO7QrBVpVmOUglrPN6Gi0VCZcKXGvuNjjgiC9lIPA,4166
|
|
34
|
+
uipath_langchain-0.0.110.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
35
|
+
uipath_langchain-0.0.110.dist-info/entry_points.txt,sha256=FUtzqGOEntlJKMJIXhQUfT7ZTbQmGhke1iCmDWZaQZI,81
|
|
36
|
+
uipath_langchain-0.0.110.dist-info/licenses/LICENSE,sha256=JDpt-uotAkHFmxpwxi6gwx6HQ25e-lG4U_Gzcvgp7JY,1063
|
|
37
|
+
uipath_langchain-0.0.110.dist-info/RECORD,,
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import logging
|
|
3
|
-
import re
|
|
4
|
-
import uuid
|
|
5
|
-
import warnings
|
|
6
|
-
from os import environ as env
|
|
7
|
-
from time import sleep
|
|
8
|
-
|
|
9
|
-
import httpx
|
|
10
|
-
from langchain_core.tracers.base import BaseTracer
|
|
11
|
-
from langchain_core.tracers.schemas import Run
|
|
12
|
-
from pydantic import PydanticDeprecationWarning
|
|
13
|
-
|
|
14
|
-
from ._utils import _simple_serialize_defaults
|
|
15
|
-
|
|
16
|
-
logger = logging.getLogger(__name__)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class UiPathTracer(BaseTracer):
|
|
20
|
-
def __init__(self, client, **kwargs):
|
|
21
|
-
super().__init__(**kwargs)
|
|
22
|
-
|
|
23
|
-
self.client = client or httpx.Client()
|
|
24
|
-
self.retries = 3
|
|
25
|
-
|
|
26
|
-
llm_ops_pattern = self._get_base_url() + "{orgId}/llmops_"
|
|
27
|
-
self.orgId = env.get("UIPATH_ORGANIZATION_ID")
|
|
28
|
-
self.tenantId = env.get("UIPATH_TENANT_ID")
|
|
29
|
-
self.url = llm_ops_pattern.format(orgId=self.orgId).rstrip("/")
|
|
30
|
-
|
|
31
|
-
self.auth_token = env.get("UNATTENDED_USER_ACCESS_TOKEN") or env.get(
|
|
32
|
-
"UIPATH_ACCESS_TOKEN"
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
self.jobKey = env.get("UIPATH_JOB_KEY")
|
|
36
|
-
self.folderKey = env.get("UIPATH_FOLDER_KEY")
|
|
37
|
-
self.processKey = env.get("UIPATH_PROCESS_UUID")
|
|
38
|
-
|
|
39
|
-
self.referenceId = self.jobKey or str(uuid.uuid4())
|
|
40
|
-
|
|
41
|
-
self.headers = {
|
|
42
|
-
"Authorization": f"Bearer {self.auth_token}",
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
def _get_base_url(self) -> str:
|
|
46
|
-
uipath_url = (
|
|
47
|
-
env.get("UIPATH_URL") or "https://cloud.uipath.com/dummyOrg/dummyTennant/"
|
|
48
|
-
)
|
|
49
|
-
uipath_url = uipath_url.rstrip("/")
|
|
50
|
-
|
|
51
|
-
# split by "//" to get ['', 'https:', 'alpha.uipath.com/ada/byoa']
|
|
52
|
-
parts = uipath_url.split("//")
|
|
53
|
-
|
|
54
|
-
# after splitting by //, the base URL will be at index 1 along with the rest,
|
|
55
|
-
# hence split it again using "/" to get ['https:', 'alpha.uipath.com', 'ada', 'byoa']
|
|
56
|
-
base_url_parts = parts[1].split("/")
|
|
57
|
-
|
|
58
|
-
# combine scheme and netloc to get the base URL
|
|
59
|
-
base_url = parts[0] + "//" + base_url_parts[0] + "/"
|
|
60
|
-
|
|
61
|
-
return base_url
|
|
62
|
-
|
|
63
|
-
def init_trace(self, run_name, trace_id=None) -> None:
|
|
64
|
-
trace_id_env = env.get("UIPATH_TRACE_ID")
|
|
65
|
-
|
|
66
|
-
if trace_id_env:
|
|
67
|
-
self.trace_parent = trace_id_env
|
|
68
|
-
else:
|
|
69
|
-
self.start_trace(run_name, trace_id)
|
|
70
|
-
|
|
71
|
-
def start_trace(self, run_name, trace_id=None) -> None:
|
|
72
|
-
self.trace_parent = trace_id or str(uuid.uuid4())
|
|
73
|
-
run_name = run_name or f"Job Run: {self.trace_parent}"
|
|
74
|
-
trace_data = {
|
|
75
|
-
"id": self.trace_parent,
|
|
76
|
-
"name": re.sub(
|
|
77
|
-
r"[!@#$<>\.]", "", run_name
|
|
78
|
-
), # if we use these characters the Agents UI throws some error (but llmops backend seems fine)
|
|
79
|
-
"referenceId": self.referenceId,
|
|
80
|
-
"attributes": "{}",
|
|
81
|
-
"organizationId": self.orgId,
|
|
82
|
-
"tenantId": self.tenantId,
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
for attempt in range(self.retries):
|
|
86
|
-
response = self.client.post(
|
|
87
|
-
f"{self.url}/api/Agent/trace/", headers=self.headers, json=trace_data
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
if response.is_success:
|
|
91
|
-
break
|
|
92
|
-
|
|
93
|
-
sleep(0.5 * (2**attempt)) # Exponential backoff
|
|
94
|
-
|
|
95
|
-
if 400 <= response.status_code < 600:
|
|
96
|
-
logger.warning(
|
|
97
|
-
f"Error when sending trace: {response}. Body is: {response.text}"
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
def _persist_run(self, run: Run) -> None:
|
|
101
|
-
# when (run.id == run.parent_run_id) it's the start of a new trace
|
|
102
|
-
# but we treat all as spans and parent to a single Trace with Id == Job.Key
|
|
103
|
-
start_time = run.start_time.isoformat() if run.start_time is not None else None
|
|
104
|
-
end_time = run.end_time.isoformat() if run.end_time is not None else start_time
|
|
105
|
-
|
|
106
|
-
span_data = {
|
|
107
|
-
"id": str(run.id),
|
|
108
|
-
"parentId": str(run.parent_run_id)
|
|
109
|
-
if run.parent_run_id is not None
|
|
110
|
-
else None,
|
|
111
|
-
"traceId": self.trace_parent,
|
|
112
|
-
"name": run.name,
|
|
113
|
-
"startTime": start_time,
|
|
114
|
-
"endTime": end_time,
|
|
115
|
-
"referenceId": self.referenceId,
|
|
116
|
-
"attributes": self._safe_json_dump(self._run_to_dict(run)),
|
|
117
|
-
"organizationId": self.orgId,
|
|
118
|
-
"tenantId": self.tenantId,
|
|
119
|
-
"spanType": "LangGraphRun",
|
|
120
|
-
"status": 2 if run.error else 1,
|
|
121
|
-
"jobKey": self.jobKey,
|
|
122
|
-
"folderKey": self.folderKey,
|
|
123
|
-
"processKey": self.processKey,
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
for attempt in range(self.retries):
|
|
127
|
-
response = self.client.post(
|
|
128
|
-
f"{self.url}/api/Agent/span/", headers=self.headers, json=span_data
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
if response.is_success:
|
|
132
|
-
break
|
|
133
|
-
|
|
134
|
-
sleep(0.5 * (2**attempt)) # Exponential backoff
|
|
135
|
-
|
|
136
|
-
if 400 <= response.status_code < 600:
|
|
137
|
-
logger.warning(
|
|
138
|
-
f"Error when sending trace: {response}. Body is: {response.text}"
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
def _end_trace(self, run: Run) -> None:
|
|
142
|
-
super()._end_trace(run)
|
|
143
|
-
self._persist_run(run)
|
|
144
|
-
|
|
145
|
-
def _safe_json_dump(self, obj) -> str:
|
|
146
|
-
try:
|
|
147
|
-
json_str = json.dumps(obj, default=_simple_serialize_defaults)
|
|
148
|
-
return json_str
|
|
149
|
-
except Exception as e:
|
|
150
|
-
logger.warning(e)
|
|
151
|
-
return "{ }"
|
|
152
|
-
|
|
153
|
-
def _run_to_dict(self, run: Run):
|
|
154
|
-
with warnings.catch_warnings():
|
|
155
|
-
warnings.simplefilter("ignore", category=PydanticDeprecationWarning)
|
|
156
|
-
|
|
157
|
-
return {
|
|
158
|
-
**run.dict(exclude={"child_runs", "inputs", "outputs"}),
|
|
159
|
-
"inputs": run.inputs.copy() if run.inputs is not None else None,
|
|
160
|
-
"outputs": run.outputs.copy() if run.outputs is not None else None,
|
|
161
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|