uipath-langchain 0.0.82__py3-none-any.whl → 0.0.84__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.

@@ -14,6 +14,7 @@ from uipath_sdk._cli._runtime._contracts import (
14
14
  UiPathRuntimeResult,
15
15
  )
16
16
 
17
+ from ..._utils import _instrument_traceable
17
18
  from ...tracers import AsyncUiPathTracer
18
19
  from ._context import LangGraphRuntimeContext
19
20
  from ._exception import LangGraphRuntimeError
@@ -43,6 +44,7 @@ class LangGraphRuntime(UiPathBaseRuntime):
43
44
  Raises:
44
45
  LangGraphRuntimeError: If execution fails
45
46
  """
47
+ _instrument_traceable()
46
48
 
47
49
  await self.validate()
48
50
 
@@ -71,7 +73,7 @@ class LangGraphRuntime(UiPathBaseRuntime):
71
73
  callbacks: List[BaseCallbackHandler] = []
72
74
 
73
75
  if self.context.job_id and self.context.tracing_enabled:
74
- tracer = AsyncUiPathTracer()
76
+ tracer = AsyncUiPathTracer(context=self.context.trace_context)
75
77
  await tracer.init_trace(
76
78
  self.context.entrypoint, self.context.job_id
77
79
  )
@@ -1,3 +1,4 @@
1
+ from ..tracers._instrument_traceable import _instrument_traceable
1
2
  from ._request_mixin import UiPathRequestMixin
2
3
 
3
- __all__ = ["UiPathRequestMixin"]
4
+ __all__ = ["UiPathRequestMixin", "_instrument_traceable"]
@@ -6,17 +6,21 @@ import re
6
6
  import uuid
7
7
  import warnings
8
8
  from os import environ as env
9
- from typing import Any, Optional
9
+ from typing import Any, Dict, Optional
10
10
 
11
11
  import httpx
12
12
  from langchain_core.tracers.base import AsyncBaseTracer
13
13
  from langchain_core.tracers.schemas import Run
14
14
  from pydantic import PydanticDeprecationWarning
15
+ from uipath_sdk._cli._runtime._contracts import UiPathTraceContext
15
16
 
16
- from ._utils import _simple_serialize_defaults
17
+ from ._events import CustomTraceEvents, FunctionCallEventData
18
+ from ._utils import _setup_tracer_httpx_logging, _simple_serialize_defaults
17
19
 
18
20
  logger = logging.getLogger(__name__)
19
21
 
22
+ _setup_tracer_httpx_logging("/llmops_/api/Agent/trace/")
23
+
20
24
 
21
25
  class Status:
22
26
  SUCCESS = 1
@@ -25,78 +29,98 @@ class Status:
25
29
 
26
30
 
27
31
  class AsyncUiPathTracer(AsyncBaseTracer):
28
- def __init__(self, client=None, **kwargs):
32
+ def __init__(
33
+ self,
34
+ context: Optional[UiPathTraceContext] = None,
35
+ client: Optional[httpx.AsyncClient] = None,
36
+ **kwargs,
37
+ ):
29
38
  super().__init__(**kwargs)
30
39
 
31
40
  self.client = client or httpx.AsyncClient()
32
41
  self.retries = 3
33
42
  self.log_queue: queue.Queue[dict[str, Any]] = queue.Queue()
34
43
 
44
+ self.context = context or UiPathTraceContext()
45
+
35
46
  llm_ops_pattern = self._get_base_url() + "{orgId}/llmops_"
36
- self.orgId = env.get(
37
- "UIPATH_ORGANIZATION_ID", "00000000-0000-0000-0000-000000000000"
38
- )
39
- self.tenantId = env.get(
40
- "UIPATH_TENANT_ID", "00000000-0000-0000-0000-000000000000"
41
- )
42
- self.url = llm_ops_pattern.format(orgId=self.orgId).rstrip("/")
43
47
 
44
- self.auth_token = env.get("UNATTENDED_USER_ACCESS_TOKEN") or env.get(
48
+ self.url = llm_ops_pattern.format(orgId=self.context.org_id).rstrip("/")
49
+
50
+ auth_token = env.get("UNATTENDED_USER_ACCESS_TOKEN") or env.get(
45
51
  "UIPATH_ACCESS_TOKEN"
46
52
  )
47
53
 
48
- self.jobKey = env.get("UIPATH_JOB_KEY")
49
- self.folderKey = env.get("UIPATH_FOLDER_KEY")
50
- self.processKey = env.get("UIPATH_PROCESS_UUID")
51
- self.parent_span_id = env.get("UIPATH_PARENT_SPAN_ID")
52
-
53
- self.referenceId = self.jobKey or str(uuid.uuid4())
54
-
55
- self.headers = {
56
- "Authorization": f"Bearer {self.auth_token}",
57
- }
54
+ self.headers = {"Authorization": f"Bearer {auth_token}"}
58
55
 
59
56
  self.running = True
60
57
  self.worker_task = asyncio.create_task(self._worker())
58
+ self.function_call_run_map: Dict[str, Run] = {}
59
+
60
+ async def on_custom_event(
61
+ self,
62
+ name: str,
63
+ data: Any,
64
+ *,
65
+ run_id: uuid.UUID,
66
+ tags=None,
67
+ metadata=None,
68
+ **kwargs: Any,
69
+ ) -> None:
70
+ if name == CustomTraceEvents.UIPATH_TRACE_FUNCTION_CALL:
71
+ # only handle the function call event
72
+
73
+ if not isinstance(data, FunctionCallEventData):
74
+ logger.warning(
75
+ f"Received unexpected data type for function call event: {type(data)}"
76
+ )
77
+ return
61
78
 
62
- def _get_base_url(self) -> str:
63
- uipath_url = (
64
- env.get("UIPATH_URL") or "https://cloud.uipath.com/dummyOrg/dummyTennant/"
65
- )
66
- uipath_url = uipath_url.rstrip("/")
79
+ if data.event_type == "call":
80
+ run = self.run_map[str(run_id)]
81
+ child_run = run.create_child(
82
+ name=data.function_name, run_type=data.run_type, tags=data.tags
83
+ )
67
84
 
68
- # split by "//" to get ['', 'https:', 'alpha.uipath.com/ada/byoa']
69
- parts = uipath_url.split("//")
85
+ if data.metadata is not None:
86
+ run.add_metadata(data.metadata)
70
87
 
71
- # after splitting by //, the base URL will be at index 1 along with the rest,
72
- # hence split it again using "/" to get ['https:', 'alpha.uipath.com', 'ada', 'byoa']
73
- base_url_parts = parts[1].split("/")
88
+ call_uuid = data.call_uuid
89
+ self.function_call_run_map[call_uuid] = child_run
74
90
 
75
- # combine scheme and netloc to get the base URL
76
- base_url = parts[0] + "//" + base_url_parts[0] + "/"
91
+ self._send_span(run)
77
92
 
78
- return base_url
93
+ if data.event_type == "completion":
94
+ call_uuid = data.call_uuid
95
+ previous_run = self.function_call_run_map.pop(call_uuid, None)
96
+
97
+ if previous_run:
98
+ previous_run.end(
99
+ outputs=self._safe_dict_dump(data.output), error=data.error
100
+ )
101
+ self._send_span(previous_run)
79
102
 
80
103
  async def init_trace(self, run_name, trace_id=None) -> None:
81
- trace_id_env = env.get("UIPATH_TRACE_ID")
104
+ if self.context.trace_id:
105
+ # trace id already set no need to do anything
106
+ return
82
107
 
83
- if trace_id_env:
84
- self.trace_parent = trace_id_env
85
- else:
86
- await self.start_trace(run_name, trace_id)
108
+ # no trace id, start a new trace
109
+ await self.start_trace(run_name, trace_id)
87
110
 
88
111
  async def start_trace(self, run_name, trace_id=None) -> None:
89
- self.trace_parent = trace_id or str(uuid.uuid4())
90
- run_name = run_name or f"Job Run: {self.trace_parent}"
112
+ self.context.trace_id = str(uuid.uuid4())
113
+
114
+ run_name = run_name or f"Job Run: {self.context.trace_id}"
91
115
  trace_data = {
92
- "id": self.trace_parent,
116
+ "id": self.context.trace_id,
93
117
  "name": re.sub(
94
118
  "[!@#$<>\.]", "", run_name
95
119
  ), # if we use these characters the Agents UI throws some error (but llmops backend seems fine)
96
- "referenceId": self.referenceId,
120
+ "referenceId": self.context.reference_id,
97
121
  "attributes": "{}",
98
- "organizationId": self.orgId,
99
- "tenantId": self.tenantId,
122
+ "organizationId": self.context.org_id,
123
+ "tenantId": self.context.tenant_id,
100
124
  }
101
125
 
102
126
  for attempt in range(self.retries):
@@ -174,9 +198,9 @@ class AsyncUiPathTracer(AsyncBaseTracer):
174
198
 
175
199
  async def _persist_run(self, run: Run) -> None:
176
200
  # Determine if this is a start or end trace based on whether end_time is set
177
- await self._send_span(run)
201
+ self._send_span(run)
178
202
 
179
- async def _send_span(self, run: Run) -> None:
203
+ def _send_span(self, run: Run) -> None:
180
204
  """Send span data for a run to the API"""
181
205
  run_id = str(run.id)
182
206
 
@@ -191,27 +215,27 @@ class AsyncUiPathTracer(AsyncBaseTracer):
191
215
  parent_id = (
192
216
  str(run.parent_run_id)
193
217
  if run.parent_run_id is not None
194
- else self.parent_span_id
218
+ else self.context.parent_span_id
195
219
  )
196
- attributes = self._safe_json_dump(self._run_to_dict(run))
220
+ attributes = self._safe_jsons_dump(self._run_to_dict(run))
197
221
  status = self._determine_status(run.error)
198
222
 
199
223
  span_data = {
200
224
  "id": run_id,
201
225
  "parentId": parent_id,
202
- "traceId": self.trace_parent,
226
+ "traceId": self.context.trace_id,
203
227
  "name": run.name,
204
228
  "startTime": start_time,
205
229
  "endTime": end_time,
206
- "referenceId": self.referenceId,
230
+ "referenceId": self.context.reference_id,
207
231
  "attributes": attributes,
208
- "organizationId": self.orgId,
209
- "tenantId": self.tenantId,
232
+ "organizationId": self.context.org_id,
233
+ "tenantId": self.context.tenant_id,
210
234
  "spanType": "LangGraphRun",
211
235
  "status": status,
212
- "jobKey": self.jobKey,
213
- "folderKey": self.folderKey,
214
- "processKey": self.processKey,
236
+ "jobKey": self.context.job_id,
237
+ "folderKey": self.context.folder_key,
238
+ "processKey": self.context.folder_key,
215
239
  }
216
240
 
217
241
  self.log_queue.put(span_data)
@@ -235,14 +259,23 @@ class AsyncUiPathTracer(AsyncBaseTracer):
235
259
 
236
260
  return Status.SUCCESS
237
261
 
238
- def _safe_json_dump(self, obj) -> str:
262
+ def _safe_jsons_dump(self, obj) -> str:
239
263
  try:
240
264
  json_str = json.dumps(obj, default=_simple_serialize_defaults)
241
265
  return json_str
242
266
  except Exception as e:
243
- logger.warning(e)
267
+ logger.warning(f"Error serializing object to JSON: {e}")
244
268
  return "{ }"
245
269
 
270
+ def _safe_dict_dump(self, obj) -> Dict[str, Any]:
271
+ try:
272
+ serialized = json.loads(json.dumps(obj, default=_simple_serialize_defaults))
273
+ return serialized
274
+ except Exception as e:
275
+ # Last resort - string representation
276
+ logger.warning(f"Error serializing object to JSON: {e}")
277
+ return {"raw": str(obj)}
278
+
246
279
  def _run_to_dict(self, run: Run):
247
280
  with warnings.catch_warnings():
248
281
  warnings.simplefilter("ignore", category=PydanticDeprecationWarning)
@@ -252,3 +285,21 @@ class AsyncUiPathTracer(AsyncBaseTracer):
252
285
  "inputs": run.inputs.copy() if run.inputs is not None else None,
253
286
  "outputs": run.outputs.copy() if run.outputs is not None else None,
254
287
  }
288
+
289
+ def _get_base_url(self) -> str:
290
+ uipath_url = (
291
+ env.get("UIPATH_URL") or "https://cloud.uipath.com/dummyOrg/dummyTennant/"
292
+ )
293
+ uipath_url = uipath_url.rstrip("/")
294
+
295
+ # split by "//" to get ['', 'https:', 'alpha.uipath.com/ada/byoa']
296
+ parts = uipath_url.split("//")
297
+
298
+ # after splitting by //, the base URL will be at index 1 along with the rest,
299
+ # hence split it again using "/" to get ['https:', 'alpha.uipath.com', 'ada', 'byoa']
300
+ base_url_parts = parts[1].split("/")
301
+
302
+ # combine scheme and netloc to get the base URL
303
+ base_url = parts[0] + "//" + base_url_parts[0] + "/"
304
+
305
+ return base_url
@@ -1,4 +1,5 @@
1
+ from ._instrument_traceable import _instrument_traceable
1
2
  from .AsyncUiPathTracer import AsyncUiPathTracer
2
3
  from .UiPathTracer import UiPathTracer
3
4
 
4
- __all__ = ["AsyncUiPathTracer", "UiPathTracer"]
5
+ __all__ = ["AsyncUiPathTracer", "UiPathTracer", "_instrument_traceable"]
@@ -0,0 +1,33 @@
1
+ from typing import Any, Dict, List, Literal, Optional
2
+
3
+ RUN_TYPE_T = Literal[
4
+ "tool", "chain", "llm", "retriever", "embedding", "prompt", "parser"
5
+ ]
6
+
7
+
8
+ class CustomTraceEvents:
9
+ UIPATH_TRACE_FUNCTION_CALL = "__uipath_trace_function_call"
10
+
11
+
12
+ class FunctionCallEventData:
13
+ def __init__(
14
+ self,
15
+ function_name: str,
16
+ event_type: str,
17
+ inputs: Dict[str, Any],
18
+ call_uuid: str,
19
+ output: Any,
20
+ error: str,
21
+ run_type: Optional[RUN_TYPE_T] = None,
22
+ tags: Optional[List[str]] = None,
23
+ metadata: Optional[Dict[str, Any]] = None,
24
+ ):
25
+ self.function_name = function_name
26
+ self.event_type = event_type
27
+ self.inputs = inputs
28
+ self.call_uuid = call_uuid
29
+ self.output = output
30
+ self.error = error
31
+ self.run_type = run_type or "chain"
32
+ self.tags = tags
33
+ self.metadata = metadata
@@ -0,0 +1,285 @@
1
+ import functools
2
+ import importlib
3
+ import inspect
4
+ import logging
5
+ import sys
6
+ import uuid
7
+ from typing import Any, Dict, List, Literal, Optional
8
+
9
+ from langchain_core.callbacks import dispatch_custom_event
10
+
11
+ from ._events import CustomTraceEvents, FunctionCallEventData
12
+
13
+ # Original module and traceable function references
14
+ original_langsmith: Any = None
15
+ original_traceable: Any = None
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ def dispatch_trace_event(
21
+ func_name,
22
+ inputs: Dict[str, Any],
23
+ event_type="call",
24
+ call_uuid=None,
25
+ result=None,
26
+ exception=None,
27
+ run_type: Optional[
28
+ Literal["tool", "chain", "llm", "retriever", "embedding", "prompt", "parser"]
29
+ ] = None,
30
+ tags: Optional[List[str]] = None,
31
+ metadata: Optional[Dict[str, Any]] = None,
32
+ ):
33
+ """Dispatch trace event to our server."""
34
+
35
+ event_data = FunctionCallEventData(
36
+ function_name=func_name,
37
+ event_type=event_type,
38
+ inputs=inputs,
39
+ call_uuid=call_uuid,
40
+ output=result,
41
+ error=str(exception),
42
+ run_type=run_type,
43
+ tags=tags,
44
+ metadata=metadata,
45
+ )
46
+ dispatch_custom_event(CustomTraceEvents.UIPATH_TRACE_FUNCTION_CALL, event_data)
47
+
48
+
49
+ def format_args_for_trace(
50
+ signature: inspect.Signature, *args: Any, **kwargs: Any
51
+ ) -> Dict[str, Any]:
52
+ try:
53
+ """Return a dictionary of inputs from the function signature."""
54
+ # Create a parameter mapping by partially binding the arguments
55
+ parameter_binding = signature.bind_partial(*args, **kwargs)
56
+
57
+ # Fill in default values for any unspecified parameters
58
+ parameter_binding.apply_defaults()
59
+
60
+ # Extract the input parameters, skipping special Python parameters
61
+ result = {}
62
+ for name, value in parameter_binding.arguments.items():
63
+ # Skip class and instance references
64
+ if name in ("self", "cls"):
65
+ continue
66
+
67
+ # Handle **kwargs parameters specially
68
+ param_info = signature.parameters.get(name)
69
+ if param_info and param_info.kind == inspect.Parameter.VAR_KEYWORD:
70
+ # Flatten nested kwargs directly into the result
71
+ if isinstance(value, dict):
72
+ result.update(value)
73
+ else:
74
+ # Regular parameter
75
+ result[name] = value
76
+
77
+ return result
78
+ except Exception as e:
79
+ logger.warning(
80
+ f"Error formatting arguments for trace: {e}. Using args and kwargs directly."
81
+ )
82
+ return {"args": args, "kwargs": kwargs}
83
+
84
+
85
+ # Create patched version of traceable
86
+ def patched_traceable(*decorator_args, **decorator_kwargs):
87
+ # Handle the case when @traceable is used directly as decorator without arguments
88
+ if (
89
+ len(decorator_args) == 1
90
+ and callable(decorator_args[0])
91
+ and not decorator_kwargs
92
+ ):
93
+ func = decorator_args[0]
94
+ return _create_appropriate_wrapper(func, original_traceable(func), {})
95
+
96
+ # Handle the case when @traceable(args) is used with parameters
97
+ original_decorated = original_traceable(*decorator_args, **decorator_kwargs)
98
+
99
+ def uipath_trace_decorator(func):
100
+ # Apply the original decorator with its arguments
101
+ wrapped_func = original_decorated(func)
102
+ return _create_appropriate_wrapper(func, wrapped_func, decorator_kwargs)
103
+
104
+ return uipath_trace_decorator
105
+
106
+
107
+ def _create_appropriate_wrapper(
108
+ original_func: Any, wrapped_func: Any, decorator_kwargs: Dict[str, Any]
109
+ ):
110
+ """Create the appropriate wrapper based on function type."""
111
+
112
+ # Get the function name and tags from decorator arguments
113
+ func_name = decorator_kwargs.get("name", original_func.__name__)
114
+ tags = decorator_kwargs.get("tags", None)
115
+ metadata = decorator_kwargs.get("metadata", None)
116
+ run_type = decorator_kwargs.get("run_type", None)
117
+
118
+ # Async generator function
119
+ if inspect.isasyncgenfunction(wrapped_func):
120
+
121
+ @functools.wraps(wrapped_func)
122
+ async def async_gen_wrapper(*args, **kwargs):
123
+ try:
124
+ call_uuid = str(uuid.uuid4())
125
+
126
+ inputs = format_args_for_trace(
127
+ inspect.signature(original_func), *args, **kwargs
128
+ )
129
+
130
+ dispatch_trace_event(
131
+ func_name,
132
+ inputs,
133
+ "call",
134
+ call_uuid,
135
+ run_type=run_type,
136
+ tags=tags,
137
+ metadata=metadata,
138
+ )
139
+ async_gen = wrapped_func(*args, **kwargs)
140
+
141
+ results = []
142
+
143
+ async for item in async_gen:
144
+ results.append(item)
145
+ yield item
146
+
147
+ dispatch_trace_event(
148
+ func_name, inputs, "completion", call_uuid, results
149
+ )
150
+ except Exception as e:
151
+ dispatch_trace_event(
152
+ func_name, inputs, "completion", call_uuid, exception=e
153
+ )
154
+ raise
155
+
156
+ return async_gen_wrapper
157
+
158
+ # Sync generator function
159
+ elif inspect.isgeneratorfunction(wrapped_func):
160
+
161
+ @functools.wraps(wrapped_func)
162
+ def gen_wrapper(*args, **kwargs):
163
+ try:
164
+ call_uuid = str(uuid.uuid4())
165
+
166
+ inputs = format_args_for_trace(
167
+ inspect.signature(original_func), *args, **kwargs
168
+ )
169
+
170
+ results = []
171
+
172
+ dispatch_trace_event(
173
+ func_name,
174
+ inputs,
175
+ "call",
176
+ call_uuid,
177
+ run_type=run_type,
178
+ tags=tags,
179
+ metadata=metadata,
180
+ )
181
+ gen = wrapped_func(*args, **kwargs)
182
+ for item in gen:
183
+ results.append(item)
184
+ yield item
185
+ dispatch_trace_event(
186
+ func_name, inputs, "completion", call_uuid, results
187
+ )
188
+ except Exception as e:
189
+ dispatch_trace_event(
190
+ func_name, inputs, "completion", call_uuid, exception=e
191
+ )
192
+ raise
193
+
194
+ return gen_wrapper
195
+
196
+ # Async function
197
+ elif inspect.iscoroutinefunction(wrapped_func):
198
+
199
+ @functools.wraps(wrapped_func)
200
+ async def async_wrapper(*args, **kwargs):
201
+ try:
202
+ call_uuid = str(uuid.uuid4())
203
+
204
+ inputs = format_args_for_trace(
205
+ inspect.signature(original_func), *args, **kwargs
206
+ )
207
+
208
+ dispatch_trace_event(
209
+ func_name,
210
+ inputs,
211
+ "call",
212
+ call_uuid,
213
+ run_type=run_type,
214
+ tags=tags,
215
+ metadata=metadata,
216
+ )
217
+ result = await wrapped_func(*args, **kwargs)
218
+ dispatch_trace_event(func_name, inputs, "completion", call_uuid, result)
219
+ return result
220
+ except Exception as e:
221
+ dispatch_trace_event(
222
+ func_name, inputs, "completion", call_uuid, exception=e
223
+ )
224
+ raise
225
+
226
+ return async_wrapper
227
+
228
+ # Regular sync function (default case)
229
+ else:
230
+
231
+ @functools.wraps(wrapped_func)
232
+ def sync_wrapper(*args, **kwargs):
233
+ try:
234
+ call_uuid = str(uuid.uuid4())
235
+
236
+ inputs = format_args_for_trace(
237
+ inspect.signature(original_func), *args, **kwargs
238
+ )
239
+
240
+ dispatch_trace_event(
241
+ func_name,
242
+ inputs,
243
+ "call",
244
+ call_uuid,
245
+ run_type=run_type,
246
+ tags=tags,
247
+ metadata=metadata,
248
+ )
249
+ result = wrapped_func(*args, **kwargs)
250
+ dispatch_trace_event(func_name, inputs, "completion", call_uuid, result)
251
+ return result
252
+ except Exception as e:
253
+ dispatch_trace_event(
254
+ func_name, inputs, "completion", call_uuid, exception=e
255
+ )
256
+ raise
257
+
258
+ return sync_wrapper
259
+
260
+
261
+ # Apply the patch
262
+ def _instrument_traceable():
263
+ """Apply the patch to langsmith module at import time."""
264
+ global original_langsmith, original_traceable
265
+
266
+ # Import the original module if not already done
267
+ if original_langsmith is None:
268
+ # Temporarily remove our custom module from sys.modules
269
+ if "langsmith" in sys.modules:
270
+ original_langsmith = sys.modules["langsmith"]
271
+ del sys.modules["langsmith"]
272
+
273
+ # Import the original module
274
+ original_langsmith = importlib.import_module("langsmith")
275
+
276
+ # Store the original traceable
277
+ original_traceable = original_langsmith.traceable
278
+
279
+ # Replace the traceable function with our patched version
280
+ original_langsmith.traceable = patched_traceable
281
+
282
+ # Put our modified module back
283
+ sys.modules["langsmith"] = original_langsmith
284
+
285
+ return original_langsmith
@@ -1,7 +1,35 @@
1
1
  import datetime
2
+ import logging
2
3
  from zoneinfo import ZoneInfo
3
4
 
4
5
 
6
+ class IgnoreSpecificUrl(logging.Filter):
7
+ def __init__(self, url_to_ignore):
8
+ super().__init__()
9
+ self.url_to_ignore = url_to_ignore
10
+
11
+ def filter(self, record):
12
+ try:
13
+ if record.msg == 'HTTP Request: %s %s "%s %d %s"':
14
+ # Ignore the log if the URL matches the one we want to ignore
15
+ method = record.args[0]
16
+ url = record.args[1]
17
+
18
+ if method == "POST" and url.path.endswith(self.url_to_ignore):
19
+ # Check if the URL contains the specific path we want to ignore
20
+ return True
21
+ return False
22
+
23
+ except Exception:
24
+ return False
25
+
26
+
27
+ def _setup_tracer_httpx_logging(url: str):
28
+ # Create a custom logger for httpx
29
+ # Add the custom filter to the root logger
30
+ logging.getLogger("httpx").addFilter(IgnoreSpecificUrl(url))
31
+
32
+
5
33
  def _simple_serialize_defaults(obj):
6
34
  if hasattr(obj, "model_dump"):
7
35
  return obj.model_dump(exclude_none=True, mode="json")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uipath-langchain
3
- Version: 0.0.82
3
+ Version: 0.0.84
4
4
  Summary: UiPath Langchain
5
5
  Project-URL: Homepage, https://uipath.com
6
6
  Project-URL: Repository, https://github.com/UiPath/uipath-python
@@ -8,9 +8,9 @@ uipath_langchain/_cli/_runtime/_escalation.py,sha256=Ii8FTRODQFuzZNRFU8F52QxDNWK
8
8
  uipath_langchain/_cli/_runtime/_exception.py,sha256=0KKJh7wR54HapGW4BNQvEsGUWumvTuF_t0k3huVmn-g,550
9
9
  uipath_langchain/_cli/_runtime/_input.py,sha256=77TdtrWYwa1NJSIPU3xTlq9KoqPcc__B-37pUDAMXhA,5432
10
10
  uipath_langchain/_cli/_runtime/_output.py,sha256=W7vlpiVYAkfRkGRwEk8LkxlZv2MadkH87QK7peHOCQ0,13383
11
- uipath_langchain/_cli/_runtime/_runtime.py,sha256=PoPNVGaBfx6I--Cu1VXNYzozIaIfxv4iBSCKtKNnU0A,11015
11
+ uipath_langchain/_cli/_runtime/_runtime.py,sha256=pFLbCBXdYCDcFP3ZMDPccbGRDN7sa3HdMA7yVpWc584,11125
12
12
  uipath_langchain/_cli/_utils/_graph.py,sha256=WLBSJfPc3_C07SqJhePRe17JIc5wcBvEqLviMcNOdTA,6950
13
- uipath_langchain/_utils/__init__.py,sha256=-w-4TD9ZnJDCpj4VIPXhJciukrmDJJbmnOFnhAkAaEU,81
13
+ uipath_langchain/_utils/__init__.py,sha256=Sp2qnEXLAp9ftQ09x7CZMenYnpXIIGFJNv8zNN7vAsw,172
14
14
  uipath_langchain/_utils/_request_mixin.py,sha256=t_1HWBxqEl-wsSk9ubmIM-8vs9BlNy4ZVBxtDxktn6U,18489
15
15
  uipath_langchain/_utils/_settings.py,sha256=MhwEVj4gVRSar0RBf2w2hTjO-5Qm-HpCuufqN3gSWjA,3390
16
16
  uipath_langchain/_utils/_sleep_policy.py,sha256=e9pHdjmcCj4CVoFM1jMyZFelH11YatsgWfpyrfXzKBQ,1251
@@ -25,11 +25,13 @@ uipath_langchain/embeddings/__init__.py,sha256=QICtYB58ZyqFfDQrEaO8lTEgAU5NuEKlR
25
25
  uipath_langchain/embeddings/embeddings.py,sha256=gntzTfwO1pHbgnXiPdfETJaaurvQWqxVUCH75VMah54,4274
26
26
  uipath_langchain/retrievers/__init__.py,sha256=rOn7PyyHgZ4pMnXWPkGqmuBmx8eGuo-Oyndo7Wm9IUU,108
27
27
  uipath_langchain/retrievers/context_grounding_retriever.py,sha256=lPn8mkIwgsPbEGw937vqSb3rPrvhGWA-GQJclzIUkSw,1165
28
- uipath_langchain/tracers/AsyncUiPathTracer.py,sha256=S1BRgLBdjsqADNhG-Tq6AEs9ttdMvETsdtXeCmCtIpA,8537
28
+ uipath_langchain/tracers/AsyncUiPathTracer.py,sha256=tBWA5OYN3kOPOgTzv1aGgXl1C8rL97K1zNJfVE-tunw,10385
29
29
  uipath_langchain/tracers/UiPathTracer.py,sha256=BpkbDbJEYYy61Qf3_O4qk51t6cxbjBXdDeVSCXUq_dU,5600
30
- uipath_langchain/tracers/__init__.py,sha256=wH-enSqPsMo70cTExRhavWooDFZ1Yfa36CKQdYUspXs,137
31
- uipath_langchain/tracers/_utils.py,sha256=W37jXVmB1K4sgqr5nwWlku243VTijq2rUPYhm7ZqLHs,665
32
- uipath_langchain-0.0.82.dist-info/METADATA,sha256=qwi5psCDmIgisfhlY6Ar_oztCrgOY429oM34kf0Bcm0,1182
33
- uipath_langchain-0.0.82.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
34
- uipath_langchain-0.0.82.dist-info/entry_points.txt,sha256=vB4ttaYft0qEsoCQ8qAoQGLmOYysY42x8p_rM-c_jF4,85
35
- uipath_langchain-0.0.82.dist-info/RECORD,,
30
+ uipath_langchain/tracers/__init__.py,sha256=8DeXfBFhu6IaqDRj_ffjRV01I8q5i_8wXbnhBZTwXnc,219
31
+ uipath_langchain/tracers/_events.py,sha256=9X7Brn3iP-USAY4Wz11HE5ItLjtNhmeuborBOpr0ktA,938
32
+ uipath_langchain/tracers/_instrument_traceable.py,sha256=ROtTcOPHqLAQ6bdKmQQvhzQUAOZj6ftwWrzSzsFzpRI,9506
33
+ uipath_langchain/tracers/_utils.py,sha256=j16MEhuCkG81JN4viUx43QxwRXtOcL7oKPFW0JphDwo,1595
34
+ uipath_langchain-0.0.84.dist-info/METADATA,sha256=P7v7-q8eGcRgKzx5jDoseT6QtVxu6j965QSw5VHy8VY,1182
35
+ uipath_langchain-0.0.84.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
36
+ uipath_langchain-0.0.84.dist-info/entry_points.txt,sha256=vB4ttaYft0qEsoCQ8qAoQGLmOYysY42x8p_rM-c_jF4,85
37
+ uipath_langchain-0.0.84.dist-info/RECORD,,