langchain-arcade 1.4.4__py3-none-any.whl → 2.0.1__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.
- langchain_arcade/__init__.py +16 -6
- langchain_arcade-2.0.1.dist-info/METADATA +54 -0
- langchain_arcade-2.0.1.dist-info/RECORD +6 -0
- {langchain_arcade-1.4.4.dist-info → langchain_arcade-2.0.1.dist-info}/WHEEL +1 -1
- langchain_arcade/_utilities.py +0 -313
- langchain_arcade/manager.py +0 -848
- langchain_arcade-1.4.4.dist-info/METADATA +0 -195
- langchain_arcade-1.4.4.dist-info/RECORD +0 -8
- {langchain_arcade-1.4.4.dist-info → langchain_arcade-2.0.1.dist-info}/licenses/LICENSE +0 -0
langchain_arcade/__init__.py
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
import warnings
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
3
|
+
warnings.warn(
|
|
4
|
+
"\n" + "=" * 70 + "\n"
|
|
5
|
+
"DEPRECATION NOTICE: langchain-arcade is no longer maintained.\n"
|
|
6
|
+
"\n"
|
|
7
|
+
"This package has been deprecated. Please visit https://docs.arcade.dev\n"
|
|
8
|
+
"for the latest documentation on integrating Arcade tools into your\n"
|
|
9
|
+
"applications.\n"
|
|
10
|
+
"\n"
|
|
11
|
+
"Arcade now supports MCP (Model Context Protocol) and direct API\n"
|
|
12
|
+
"integration via the Arcade Python SDK.\n" + "=" * 70,
|
|
13
|
+
DeprecationWarning,
|
|
14
|
+
stacklevel=2,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
__all__: list[str] = []
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: langchain-arcade
|
|
3
|
+
Version: 2.0.1
|
|
4
|
+
Summary: This package is no longer maintained. Please visit https://docs.arcade.dev for the latest Arcade integrations.
|
|
5
|
+
Project-URL: Homepage, https://docs.arcade.dev
|
|
6
|
+
Project-URL: Documentation, https://docs.arcade.dev
|
|
7
|
+
Project-URL: Repository, https://github.com/arcadeai/arcade-mcp
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: arcade,deprecated,langchain
|
|
11
|
+
Classifier: Development Status :: 7 - Inactive
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
<h3 align="center">
|
|
22
|
+
<img
|
|
23
|
+
src="https://docs.arcade.dev/images/logo/arcade-logo.png"
|
|
24
|
+
>
|
|
25
|
+
</h3>
|
|
26
|
+
|
|
27
|
+
<div align="center">
|
|
28
|
+
<h1>⚠️ DEPRECATED ⚠️</h1>
|
|
29
|
+
<h3>langchain-arcade is no longer maintained</h3>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Important Notice
|
|
35
|
+
|
|
36
|
+
**This package has been deprecated and is no longer maintained.**
|
|
37
|
+
|
|
38
|
+
The `langchain-arcade` package is no longer needed. Arcade now provides better ways to integrate with your AI applications.
|
|
39
|
+
|
|
40
|
+
## What Should I Use Instead?
|
|
41
|
+
|
|
42
|
+
Please visit **[docs.arcade.dev](https://docs.arcade.dev)** for the latest documentation on how to integrate Arcade tools into your applications.
|
|
43
|
+
|
|
44
|
+
## Migration Guide
|
|
45
|
+
|
|
46
|
+
If you were previously using `langchain-arcade`, we recommend:
|
|
47
|
+
|
|
48
|
+
1. Visit [docs.arcade.dev](https://docs.arcade.dev) to learn about the new integration options
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
<p align="center">
|
|
53
|
+
Thank you for using langchain-arcade. We hope to see you using Arcade's new integrations!
|
|
54
|
+
</p>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
langchain_arcade/__init__.py,sha256=J-ho9Zu8O-nA49jTixtJIM4n33r8sdsanHC9slkxFRg,523
|
|
2
|
+
langchain_arcade/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
langchain_arcade-2.0.1.dist-info/METADATA,sha256=MX6bhKSfRBDd6vg-GfAOi30PiJj6loLCigwU3ASLEtY,1749
|
|
4
|
+
langchain_arcade-2.0.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
5
|
+
langchain_arcade-2.0.1.dist-info/licenses/LICENSE,sha256=f4Q0XUZJ2MqZBO1XsqqHhuZfSs2ar1cZEJ45150zERo,1067
|
|
6
|
+
langchain_arcade-2.0.1.dist-info/RECORD,,
|
langchain_arcade/_utilities.py
DELETED
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
from typing import Any, Callable, Union
|
|
2
|
-
|
|
3
|
-
from arcadepy import NOT_GIVEN, Arcade, AsyncArcade
|
|
4
|
-
from arcadepy.types import ExecuteToolResponse, ToolDefinition
|
|
5
|
-
from langchain_core.runnables import RunnableConfig
|
|
6
|
-
from langchain_core.tools import StructuredTool
|
|
7
|
-
from pydantic import BaseModel, Field, create_model
|
|
8
|
-
|
|
9
|
-
# Check if LangGraph is enabled
|
|
10
|
-
LANGGRAPH_ENABLED = True
|
|
11
|
-
try:
|
|
12
|
-
from langgraph.errors import NodeInterrupt
|
|
13
|
-
except ImportError:
|
|
14
|
-
LANGGRAPH_ENABLED = False
|
|
15
|
-
|
|
16
|
-
# Mapping of Arcade value types to Python types
|
|
17
|
-
TYPE_MAPPING = {
|
|
18
|
-
"string": str,
|
|
19
|
-
"number": float,
|
|
20
|
-
"integer": int,
|
|
21
|
-
"boolean": bool,
|
|
22
|
-
"array": list,
|
|
23
|
-
"json": dict,
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def get_python_type(val_type: str) -> Any:
|
|
28
|
-
"""Map Arcade value types to Python types.
|
|
29
|
-
|
|
30
|
-
Args:
|
|
31
|
-
val_type: The value type as a string.
|
|
32
|
-
|
|
33
|
-
Returns:
|
|
34
|
-
Corresponding Python type.
|
|
35
|
-
"""
|
|
36
|
-
_type = TYPE_MAPPING.get(val_type)
|
|
37
|
-
if _type is None:
|
|
38
|
-
raise ValueError(f"Invalid value type: {val_type}")
|
|
39
|
-
return _type
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def tool_definition_to_pydantic_model(tool_def: ToolDefinition) -> type[BaseModel]:
|
|
43
|
-
"""Convert a ToolDefinition's inputs into a Pydantic BaseModel.
|
|
44
|
-
|
|
45
|
-
Args:
|
|
46
|
-
tool_def: The ToolDefinition object to convert.
|
|
47
|
-
|
|
48
|
-
Returns:
|
|
49
|
-
A Pydantic BaseModel class representing the tool's input schema.
|
|
50
|
-
"""
|
|
51
|
-
try:
|
|
52
|
-
fields: dict[str, Any] = {}
|
|
53
|
-
for param in tool_def.input.parameters or []:
|
|
54
|
-
param_type = get_python_type(param.value_schema.val_type)
|
|
55
|
-
if param_type == list and param.value_schema.inner_val_type: # noqa: E721
|
|
56
|
-
inner_type: type[Any] = get_python_type(
|
|
57
|
-
param.value_schema.inner_val_type
|
|
58
|
-
)
|
|
59
|
-
param_type = list[inner_type] # type: ignore[valid-type]
|
|
60
|
-
param_description = param.description or "No description provided."
|
|
61
|
-
default = ... if param.required else None
|
|
62
|
-
fields[param.name] = (
|
|
63
|
-
param_type,
|
|
64
|
-
Field(default=default, description=param_description),
|
|
65
|
-
)
|
|
66
|
-
return create_model(f"{tool_def.name}Args", **fields)
|
|
67
|
-
except ValueError as e:
|
|
68
|
-
raise ValueError(
|
|
69
|
-
f"Error converting {tool_def.name} parameters into pydantic model for langchain: {e}"
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def process_tool_execution_response(
|
|
74
|
-
execute_response: ExecuteToolResponse, tool_name: str, langgraph: bool
|
|
75
|
-
) -> Any:
|
|
76
|
-
"""Process the response from tool execution and handle errors appropriately.
|
|
77
|
-
|
|
78
|
-
Args:
|
|
79
|
-
execute_response: The response from tool execution
|
|
80
|
-
tool_name: The name of the tool that was executed
|
|
81
|
-
langgraph: Whether LangGraph-specific behavior is enabled
|
|
82
|
-
|
|
83
|
-
Returns:
|
|
84
|
-
The output value on success, or error details on failure
|
|
85
|
-
"""
|
|
86
|
-
if execute_response.success and execute_response.output is not None:
|
|
87
|
-
return execute_response.output.value
|
|
88
|
-
|
|
89
|
-
# Extract detailed error information
|
|
90
|
-
error_details = {
|
|
91
|
-
"error": "Unknown error occurred",
|
|
92
|
-
"tool": tool_name,
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (
|
|
96
|
-
execute_response.output is not None
|
|
97
|
-
and execute_response.output.error is not None
|
|
98
|
-
):
|
|
99
|
-
error = execute_response.output.error
|
|
100
|
-
error_message = (
|
|
101
|
-
str(error.message) if hasattr(error, "message") else "Unknown error"
|
|
102
|
-
)
|
|
103
|
-
error_details["error"] = error_message
|
|
104
|
-
|
|
105
|
-
# Add all non-None optional error fields to the details
|
|
106
|
-
if (
|
|
107
|
-
hasattr(error, "additional_prompt_content")
|
|
108
|
-
and error.additional_prompt_content is not None
|
|
109
|
-
):
|
|
110
|
-
error_details["additional_prompt_content"] = error.additional_prompt_content
|
|
111
|
-
if hasattr(error, "can_retry") and error.can_retry is not None:
|
|
112
|
-
error_details["can_retry"] = str(error.can_retry)
|
|
113
|
-
if hasattr(error, "developer_message") and error.developer_message is not None:
|
|
114
|
-
error_details["developer_message"] = str(error.developer_message)
|
|
115
|
-
if hasattr(error, "retry_after_ms") and error.retry_after_ms is not None:
|
|
116
|
-
error_details["retry_after_ms"] = str(error.retry_after_ms)
|
|
117
|
-
|
|
118
|
-
if langgraph:
|
|
119
|
-
raise NodeInterrupt(error_details)
|
|
120
|
-
return error_details
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def create_tool_function(
|
|
124
|
-
client: Arcade,
|
|
125
|
-
tool_name: str,
|
|
126
|
-
tool_def: ToolDefinition,
|
|
127
|
-
args_schema: type[BaseModel],
|
|
128
|
-
langgraph: bool = False,
|
|
129
|
-
) -> Callable:
|
|
130
|
-
"""Create a callable function to execute an Arcade tool.
|
|
131
|
-
|
|
132
|
-
Args:
|
|
133
|
-
client: The Arcade client instance.
|
|
134
|
-
tool_name: The name of the tool to wrap.
|
|
135
|
-
tool_def: The ToolDefinition of the tool to wrap.
|
|
136
|
-
args_schema: The Pydantic model representing the tool's arguments.
|
|
137
|
-
langgraph: Whether to enable LangGraph-specific behavior.
|
|
138
|
-
|
|
139
|
-
Returns:
|
|
140
|
-
A callable function that executes the tool.
|
|
141
|
-
"""
|
|
142
|
-
if langgraph and not LANGGRAPH_ENABLED:
|
|
143
|
-
raise ImportError(
|
|
144
|
-
"LangGraph is not installed. Please install it to use this feature."
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
requires_authorization = (
|
|
148
|
-
tool_def.requirements is not None
|
|
149
|
-
and tool_def.requirements.authorization is not None
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
def tool_function(config: RunnableConfig, **kwargs: Any) -> Any:
|
|
153
|
-
"""Execute the Arcade tool with the given parameters.
|
|
154
|
-
|
|
155
|
-
Args:
|
|
156
|
-
config: RunnableConfig containing execution context.
|
|
157
|
-
**kwargs: Tool input arguments.
|
|
158
|
-
|
|
159
|
-
Returns:
|
|
160
|
-
The output from the tool execution.
|
|
161
|
-
"""
|
|
162
|
-
user_id = config.get("configurable", {}).get("user_id") if config else None
|
|
163
|
-
|
|
164
|
-
if requires_authorization:
|
|
165
|
-
if user_id is None:
|
|
166
|
-
error_message = f"user_id is required to run {tool_name}"
|
|
167
|
-
if langgraph:
|
|
168
|
-
raise NodeInterrupt(error_message)
|
|
169
|
-
return {"error": error_message}
|
|
170
|
-
|
|
171
|
-
# Authorize the user for the tool
|
|
172
|
-
auth_response = client.tools.authorize(tool_name=tool_name, user_id=user_id)
|
|
173
|
-
if auth_response.status != "completed":
|
|
174
|
-
auth_message = (
|
|
175
|
-
f"Please use the following link to authorize: {auth_response.url}"
|
|
176
|
-
)
|
|
177
|
-
if langgraph:
|
|
178
|
-
raise NodeInterrupt(auth_message)
|
|
179
|
-
return {"error": auth_message}
|
|
180
|
-
|
|
181
|
-
# Execute the tool with provided inputs
|
|
182
|
-
execute_response = client.tools.execute(
|
|
183
|
-
tool_name=tool_name,
|
|
184
|
-
input=kwargs,
|
|
185
|
-
user_id=user_id if user_id is not None else NOT_GIVEN,
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
return process_tool_execution_response(execute_response, tool_name, langgraph)
|
|
189
|
-
|
|
190
|
-
return tool_function
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
def wrap_arcade_tool(
|
|
194
|
-
client: Union[Arcade, AsyncArcade],
|
|
195
|
-
tool_name: str,
|
|
196
|
-
tool_def: ToolDefinition,
|
|
197
|
-
langgraph: bool = False,
|
|
198
|
-
) -> StructuredTool:
|
|
199
|
-
"""Wrap an Arcade `ToolDefinition` as a LangChain `StructuredTool`.
|
|
200
|
-
|
|
201
|
-
Args:
|
|
202
|
-
client: The Arcade client instance.
|
|
203
|
-
tool_name: The name of the tool to wrap.
|
|
204
|
-
tool_def: The ToolDefinition object to wrap.
|
|
205
|
-
langgraph: Whether to enable LangGraph-specific behavior.
|
|
206
|
-
|
|
207
|
-
Returns:
|
|
208
|
-
A StructuredTool instance representing the Arcade tool.
|
|
209
|
-
"""
|
|
210
|
-
description = tool_def.description or "No description provided."
|
|
211
|
-
|
|
212
|
-
# Create a Pydantic model for the tool's input arguments
|
|
213
|
-
args_schema = tool_definition_to_pydantic_model(tool_def)
|
|
214
|
-
|
|
215
|
-
# Create the action function
|
|
216
|
-
if isinstance(client, Arcade):
|
|
217
|
-
action_func = create_tool_function(
|
|
218
|
-
client=client,
|
|
219
|
-
tool_name=tool_name,
|
|
220
|
-
tool_def=tool_def,
|
|
221
|
-
args_schema=args_schema,
|
|
222
|
-
langgraph=langgraph,
|
|
223
|
-
)
|
|
224
|
-
else:
|
|
225
|
-
# Use async tool function for AsyncArcade client
|
|
226
|
-
action_func = create_async_tool_function(
|
|
227
|
-
client=client,
|
|
228
|
-
tool_name=tool_name,
|
|
229
|
-
tool_def=tool_def,
|
|
230
|
-
args_schema=args_schema,
|
|
231
|
-
langgraph=langgraph,
|
|
232
|
-
)
|
|
233
|
-
|
|
234
|
-
# Create the StructuredTool instance
|
|
235
|
-
return StructuredTool.from_function(
|
|
236
|
-
func=action_func,
|
|
237
|
-
name=tool_name,
|
|
238
|
-
description=description,
|
|
239
|
-
args_schema=args_schema,
|
|
240
|
-
inject_kwargs={"user_id"},
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
def create_async_tool_function(
|
|
245
|
-
client: AsyncArcade,
|
|
246
|
-
tool_name: str,
|
|
247
|
-
tool_def: ToolDefinition,
|
|
248
|
-
args_schema: type[BaseModel],
|
|
249
|
-
langgraph: bool = False,
|
|
250
|
-
) -> Callable:
|
|
251
|
-
"""Create an async callable function to execute an Arcade tool.
|
|
252
|
-
|
|
253
|
-
Args:
|
|
254
|
-
client: The AsyncArcade client instance.
|
|
255
|
-
tool_name: The name of the tool to wrap.
|
|
256
|
-
tool_def: The ToolDefinition of the tool to wrap.
|
|
257
|
-
args_schema: The Pydantic model representing the tool's arguments.
|
|
258
|
-
langgraph: Whether to enable LangGraph-specific behavior.
|
|
259
|
-
|
|
260
|
-
Returns:
|
|
261
|
-
An async callable function that executes the tool.
|
|
262
|
-
"""
|
|
263
|
-
if langgraph and not LANGGRAPH_ENABLED:
|
|
264
|
-
raise ImportError(
|
|
265
|
-
"LangGraph is not installed. Please install it to use this feature."
|
|
266
|
-
)
|
|
267
|
-
|
|
268
|
-
requires_authorization = (
|
|
269
|
-
tool_def.requirements is not None
|
|
270
|
-
and tool_def.requirements.authorization is not None
|
|
271
|
-
)
|
|
272
|
-
|
|
273
|
-
async def tool_function(config: RunnableConfig, **kwargs: Any) -> Any:
|
|
274
|
-
"""Run the Arcade tool with the given parameters.
|
|
275
|
-
|
|
276
|
-
Args:
|
|
277
|
-
config: RunnableConfig containing execution context.
|
|
278
|
-
**kwargs: Tool input arguments.
|
|
279
|
-
|
|
280
|
-
Returns:
|
|
281
|
-
The output from the tool execution.
|
|
282
|
-
"""
|
|
283
|
-
user_id = config.get("configurable", {}).get("user_id") if config else None
|
|
284
|
-
|
|
285
|
-
if requires_authorization:
|
|
286
|
-
if user_id is None:
|
|
287
|
-
error_message = f"user_id is required to run {tool_name}"
|
|
288
|
-
if langgraph:
|
|
289
|
-
raise NodeInterrupt(error_message)
|
|
290
|
-
return {"error": error_message}
|
|
291
|
-
|
|
292
|
-
# Authorize the user for the tool
|
|
293
|
-
auth_response = await client.tools.authorize(
|
|
294
|
-
tool_name=tool_name, user_id=user_id
|
|
295
|
-
)
|
|
296
|
-
if auth_response.status != "completed":
|
|
297
|
-
auth_message = (
|
|
298
|
-
f"Please use the following link to authorize: {auth_response.url}"
|
|
299
|
-
)
|
|
300
|
-
if langgraph:
|
|
301
|
-
raise NodeInterrupt(auth_message)
|
|
302
|
-
return {"error": auth_message}
|
|
303
|
-
|
|
304
|
-
# Execute the tool with provided inputs
|
|
305
|
-
execute_response = await client.tools.execute(
|
|
306
|
-
tool_name=tool_name,
|
|
307
|
-
input=kwargs,
|
|
308
|
-
user_id=user_id if user_id is not None else NOT_GIVEN,
|
|
309
|
-
)
|
|
310
|
-
|
|
311
|
-
return process_tool_execution_response(execute_response, tool_name, langgraph)
|
|
312
|
-
|
|
313
|
-
return tool_function
|