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

@@ -17,7 +17,11 @@ from tenacity import (
17
17
  stop_after_attempt,
18
18
  wait_exponential_jitter,
19
19
  )
20
- from uipath._cli._runtime._contracts import UiPathErrorCategory, UiPathRuntimeError
20
+ from uipath._cli._runtime._contracts import (
21
+ UiPathErrorCategory,
22
+ UiPathErrorCode,
23
+ UiPathRuntimeError,
24
+ )
21
25
  from uipath._utils._ssl_context import get_httpx_client_kwargs
22
26
 
23
27
  from uipath_langchain._cli._runtime._exception import (
@@ -59,7 +63,7 @@ def _get_access_token(data):
59
63
  return get_uipath_token_header(settings)
60
64
  except ValidationError:
61
65
  raise UiPathRuntimeError(
62
- code="AUTHENTICATION_REQUIRED",
66
+ UiPathErrorCode.AUTHENTICATION_REQUIRED,
63
67
  title="Authorization required",
64
68
  detail="Authorization required. Please run uipath auth",
65
69
  category=UiPathErrorCategory.USER,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uipath-langchain
3
- Version: 0.0.147
3
+ Version: 0.0.148
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
@@ -26,7 +26,7 @@ Requires-Dist: openai>=1.65.5
26
26
  Requires-Dist: openinference-instrumentation-langchain>=0.1.50
27
27
  Requires-Dist: pydantic-settings>=2.6.0
28
28
  Requires-Dist: python-dotenv>=1.0.1
29
- Requires-Dist: uipath<2.2.0,>=2.1.110
29
+ Requires-Dist: uipath<2.2.0,>=2.1.123
30
30
  Provides-Extra: langchain
31
31
  Description-Content-Type: text/markdown
32
32
 
@@ -26,7 +26,7 @@ uipath_langchain/_tracing/__init__.py,sha256=C2dRvQ2ynxCmyICgE-rJHimWKEcFRME_o9g
26
26
  uipath_langchain/_tracing/_instrument_traceable.py,sha256=8f9FyAKWE6kH1N8ErbpwqZHAzNjGwbLjQn7jdX5yAgA,4343
27
27
  uipath_langchain/_tracing/_utils.py,sha256=r_fiSk3HDDAcePY_UbbEYiSbNqzn5gFeMPYBDvGrFx0,902
28
28
  uipath_langchain/_utils/__init__.py,sha256=-w-4TD9ZnJDCpj4VIPXhJciukrmDJJbmnOFnhAkAaEU,81
29
- uipath_langchain/_utils/_request_mixin.py,sha256=_drxHTRpfyVn3g3ppKgn466EBaUWH83qyeGKLY41CGY,20142
29
+ uipath_langchain/_utils/_request_mixin.py,sha256=AqdXUuV8hHNJYUAmAoBA1sptK52H46-QcgutVPyUfao,20185
30
30
  uipath_langchain/_utils/_settings.py,sha256=2fExMQJ88YptfldmzMfZIpsx-m1gfMkeYGf5t6KIe0A,3084
31
31
  uipath_langchain/_utils/_sleep_policy.py,sha256=e9pHdjmcCj4CVoFM1jMyZFelH11YatsgWfpyrfXzKBQ,1251
32
32
  uipath_langchain/agent/react/__init__.py,sha256=XXplWNiD9XCxMVVyE0RL8tOwJjkP9ZKU6mFR5Em0ONk,314
@@ -53,12 +53,10 @@ uipath_langchain/embeddings/__init__.py,sha256=QICtYB58ZyqFfDQrEaO8lTEgAU5NuEKlR
53
53
  uipath_langchain/embeddings/embeddings.py,sha256=45gKyb6HVKigwE-0CXeZcAk33c0mteaEdPGa8hviqcw,4339
54
54
  uipath_langchain/retrievers/__init__.py,sha256=rOn7PyyHgZ4pMnXWPkGqmuBmx8eGuo-Oyndo7Wm9IUU,108
55
55
  uipath_langchain/retrievers/context_grounding_retriever.py,sha256=YLCIwy89LhLnNqcM0YJ5mZoeNyCs5UiKD3Wly8gnW1E,2239
56
- uipath_langchain/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
- uipath_langchain/tools/preconfigured.py,sha256=SyvrLrM1kezZxVVytgScVO8nBfVYfFGobWjY7erzsYU,7490
58
56
  uipath_langchain/vectorstores/__init__.py,sha256=w8qs1P548ud1aIcVA_QhBgf_jZDrRMK5Lono78yA8cs,114
59
57
  uipath_langchain/vectorstores/context_grounding_vectorstore.py,sha256=E0iuDBMAOl50Bdhl3YxywR0CngH1I99mkmfMh3byMFY,8396
60
- uipath_langchain-0.0.147.dist-info/METADATA,sha256=IxSINnczz6chaAcdHlkwSzyLdGRN04PKd0MXY8m2fRg,4276
61
- uipath_langchain-0.0.147.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
62
- uipath_langchain-0.0.147.dist-info/entry_points.txt,sha256=FUtzqGOEntlJKMJIXhQUfT7ZTbQmGhke1iCmDWZaQZI,81
63
- uipath_langchain-0.0.147.dist-info/licenses/LICENSE,sha256=JDpt-uotAkHFmxpwxi6gwx6HQ25e-lG4U_Gzcvgp7JY,1063
64
- uipath_langchain-0.0.147.dist-info/RECORD,,
58
+ uipath_langchain-0.0.148.dist-info/METADATA,sha256=ucOXQNU19PUpVFPtiK3VrjAkGtx-jgXC8RkLtZspgoA,4276
59
+ uipath_langchain-0.0.148.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
60
+ uipath_langchain-0.0.148.dist-info/entry_points.txt,sha256=FUtzqGOEntlJKMJIXhQUfT7ZTbQmGhke1iCmDWZaQZI,81
61
+ uipath_langchain-0.0.148.dist-info/licenses/LICENSE,sha256=JDpt-uotAkHFmxpwxi6gwx6HQ25e-lG4U_Gzcvgp7JY,1063
62
+ uipath_langchain-0.0.148.dist-info/RECORD,,
File without changes
@@ -1,220 +0,0 @@
1
- import json
2
- import logging
3
- from typing import Any, Iterable, Optional, Type
4
-
5
- import httpx
6
- from jsonschema_pydantic import jsonschema_to_pydantic as create_model # type: ignore
7
- from langchain_core.caches import BaseCache
8
- from langchain_core.runnables.utils import Output
9
- from langchain_core.tools import BaseTool, StructuredTool
10
- from langgraph.types import interrupt
11
- from pydantic import BaseModel
12
- from uipath import UiPath
13
- from uipath.agent.models.agent import (
14
- AgentEscalationChannel,
15
- AgentEscalationResourceConfig,
16
- AgentIntegrationToolParameter,
17
- AgentIntegrationToolResourceConfig,
18
- AgentProcessToolResourceConfig,
19
- AgentResourceConfig,
20
- LowCodeAgentDefinition,
21
- )
22
- from uipath.models import CreateAction, InvokeProcess
23
- from uipath.models.connections import ConnectionTokenType
24
-
25
- logger = logging.getLogger(__name__)
26
-
27
-
28
- def create_process_tool(resource: AgentProcessToolResourceConfig) -> Iterable[BaseTool]:
29
- async def process(**kwargs) -> BaseModel:
30
- return interrupt(
31
- InvokeProcess(
32
- name=resource.name,
33
- input_arguments=kwargs,
34
- process_folder_path=resource.properties.folder_path,
35
- )
36
- )
37
-
38
- input_schema = create_model(resource.input_schema)
39
-
40
- class ProcessTool(StructuredTool):
41
- @property
42
- def OutputType(self) -> type[Output]:
43
- return create_model(resource.output_schema)
44
-
45
- yield ProcessTool(
46
- name=resource.name,
47
- args_schema=input_schema,
48
- description=resource.description,
49
- coroutine=process,
50
- )
51
-
52
-
53
- def create_escalation_tool_from_channel(channel: AgentEscalationChannel) -> BaseTool:
54
- async def escalate(**kwargs) -> BaseModel:
55
- recipients = channel.recipients
56
- if len(recipients) > 1:
57
- logger.warning(
58
- "Received more than one recipient. Defaulting to first recipient."
59
- )
60
- assignee = recipients[0].value if recipients else None
61
- return interrupt(
62
- CreateAction(
63
- title=channel.description,
64
- data=kwargs,
65
- assignee=assignee,
66
- app_name=channel.properties.app_name,
67
- app_folder_path=None, # Channels specify folder name but not folder path.
68
- app_folder_key=channel.properties.resource_key,
69
- app_key=channel.properties.resource_key,
70
- app_version=channel.properties.app_version,
71
- )
72
- )
73
-
74
- input_schema = create_model(channel.input_schema)
75
-
76
- class EscalationTool(StructuredTool):
77
- @property
78
- def OutputType(self) -> type[Output]:
79
- return create_model(channel.output_schema)
80
-
81
- return EscalationTool(
82
- name=channel.name,
83
- args_schema=input_schema,
84
- description=channel.description,
85
- coroutine=escalate,
86
- )
87
-
88
-
89
- def create_escalation_tool(
90
- resource: AgentEscalationResourceConfig,
91
- ) -> Iterable[BaseTool]:
92
- for channel in resource.channels:
93
- yield create_escalation_tool_from_channel(channel)
94
-
95
-
96
- METHOD_MAP = {"GETBYID": "GET"}
97
-
98
-
99
- def build_query_params(parameters: list[AgentIntegrationToolParameter]):
100
- query_params = [
101
- x for x in parameters if x.field_location == "query" and x.value is not None
102
- ]
103
- if query_params:
104
- return "?" + "&".join(f"{q.name}={q.value}" for q in query_params)
105
- return ""
106
-
107
-
108
- def filter_query_params(
109
- kwargs: dict[str, Any], parameters: list[AgentIntegrationToolParameter]
110
- ):
111
- query_params = {x.name for x in parameters if x.field_location == "query"}
112
- non_query_params = {x.name for x in parameters if x.field_location != "query"}
113
- fields_to_ignore = query_params - non_query_params
114
- return {k: v for k, v in kwargs.items() if k not in fields_to_ignore}
115
-
116
-
117
- def create_integration_tool(
118
- resource: AgentIntegrationToolResourceConfig,
119
- ) -> Iterable[BaseTool]:
120
- async def integration(**kwargs) -> BaseModel:
121
- uipath = UiPath()
122
- remote_connection = await uipath.connections.retrieve_async(
123
- resource.properties.connection.id
124
- )
125
- token = await uipath.connections.retrieve_token_async(
126
- resource.properties.connection.id, ConnectionTokenType.BEARER
127
- )
128
- tool_url = f"{remote_connection.api_base_uri}/v3/element/instances/{remote_connection.element_instance_id}{resource.properties.tool_path}"
129
- tool_url = f"{tool_url}{build_query_params(resource.properties.parameters)}"
130
- tool_url = tool_url.format(**kwargs)
131
-
132
- authorization = f"{token.token_type} {token.access_token}"
133
- method = METHOD_MAP.get(resource.properties.method, resource.properties.method)
134
- response = await httpx.AsyncClient().request(
135
- method,
136
- tool_url,
137
- headers={"Authorization": authorization},
138
- content=json.dumps(
139
- filter_query_params(kwargs, resource.properties.parameters)
140
- ),
141
- )
142
- return response.json()
143
-
144
- input_schema = create_model(resource.input_schema)
145
-
146
- class IntegrationTool(StructuredTool):
147
- @property
148
- def OutputType(self) -> type[Output]:
149
- return create_model({})
150
-
151
- yield IntegrationTool(
152
- name=resource.name,
153
- args_schema=input_schema,
154
- description=resource.description,
155
- coroutine=integration,
156
- )
157
-
158
-
159
- def create_cached_wrapper_from_tool(
160
- wrapped: BaseTool, cache: Optional[BaseCache]
161
- ) -> BaseTool:
162
- if cache is None:
163
- return wrapped
164
- else:
165
-
166
- async def cached_invocation(**kwargs) -> BaseModel:
167
- namespace = f"{wrapped.name}.tool_invoke"
168
- key = str(kwargs)
169
- cached = cache.lookup(namespace, key)
170
- if cached:
171
- return cached[0]
172
- response = await wrapped.ainvoke(input=kwargs)
173
- cache.update(namespace, key, [response])
174
- return response
175
-
176
- input_schema = wrapped.args_schema
177
-
178
- class CachedTool(StructuredTool):
179
- OutputType: Type[BaseModel] = wrapped.OutputType
180
-
181
- return CachedTool(
182
- name=wrapped.name,
183
- args_schema=input_schema,
184
- description=wrapped.description,
185
- coroutine=cached_invocation,
186
- )
187
-
188
-
189
- def create_cached_wrapper(
190
- tools: Iterable[BaseTool], cache: Optional[BaseCache]
191
- ) -> Iterable[BaseTool]:
192
- for wrapped in tools:
193
- yield create_cached_wrapper_from_tool(wrapped, cache)
194
-
195
-
196
- def create_resource_tool(
197
- resource: AgentResourceConfig, cache: Optional[BaseCache] = None
198
- ) -> Iterable[BaseTool]:
199
- match resource:
200
- case AgentProcessToolResourceConfig():
201
- return create_cached_wrapper(create_process_tool(resource), cache)
202
- case AgentIntegrationToolResourceConfig():
203
- return create_cached_wrapper(create_integration_tool(resource), cache)
204
- case AgentEscalationResourceConfig():
205
- return create_cached_wrapper(create_escalation_tool(resource), cache)
206
- case _:
207
- raise NotImplementedError()
208
-
209
-
210
- def safe_extract_tools(
211
- agent_definition: LowCodeAgentDefinition, cache: Optional[BaseCache] = None
212
- ) -> list[BaseTool]:
213
- tools = []
214
- for resource in agent_definition.resources:
215
- try:
216
- for structured_tool in create_resource_tool(resource, cache):
217
- tools.append(structured_tool)
218
- except NotImplementedError:
219
- logger.warning(f"Unable to convert {resource.name} into a tool.")
220
- return tools