langchain-agent-toolbox 0.1.0__tar.gz
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_agent_toolbox-0.1.0/PKG-INFO +251 -0
- langchain_agent_toolbox-0.1.0/README.md +225 -0
- langchain_agent_toolbox-0.1.0/langchain_agent_toolbox/__init__.py +23 -0
- langchain_agent_toolbox-0.1.0/langchain_agent_toolbox/client.py +48 -0
- langchain_agent_toolbox-0.1.0/langchain_agent_toolbox/py.typed +0 -0
- langchain_agent_toolbox-0.1.0/langchain_agent_toolbox/tools.py +364 -0
- langchain_agent_toolbox-0.1.0/langchain_agent_toolbox.egg-info/PKG-INFO +251 -0
- langchain_agent_toolbox-0.1.0/langchain_agent_toolbox.egg-info/SOURCES.txt +12 -0
- langchain_agent_toolbox-0.1.0/langchain_agent_toolbox.egg-info/dependency_links.txt +1 -0
- langchain_agent_toolbox-0.1.0/langchain_agent_toolbox.egg-info/requires.txt +2 -0
- langchain_agent_toolbox-0.1.0/langchain_agent_toolbox.egg-info/top_level.txt +1 -0
- langchain_agent_toolbox-0.1.0/pyproject.toml +40 -0
- langchain_agent_toolbox-0.1.0/setup.cfg +4 -0
- langchain_agent_toolbox-0.1.0/tests/test_tools.py +42 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: langchain-agent-toolbox
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: LangChain integration for Agent Toolbox API — search, extract, screenshot, weather, finance, email validation, and translation tools for AI agents
|
|
5
|
+
Author-email: Agent Toolbox <hello@agenttoolbox.dev>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Vincentwei1021/agent-toolbox
|
|
8
|
+
Project-URL: Repository, https://github.com/Vincentwei1021/agent-toolbox/tree/master/integrations/langchain
|
|
9
|
+
Project-URL: Documentation, https://github.com/Vincentwei1021/agent-toolbox#readme
|
|
10
|
+
Project-URL: Issues, https://github.com/Vincentwei1021/agent-toolbox/issues
|
|
11
|
+
Keywords: langchain,ai-agent,tools,mcp,search,web-scraping,screenshot,weather,finance,email-validation,translation
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
Requires-Dist: langchain-core>=0.2.0
|
|
25
|
+
Requires-Dist: httpx>=0.25.0
|
|
26
|
+
|
|
27
|
+
# 🧰 langchain-agent-toolbox
|
|
28
|
+
|
|
29
|
+
[](https://pypi.org/project/langchain-agent-toolbox/)
|
|
30
|
+
[](https://github.com/Vincentwei1021/agent-toolbox/blob/master/LICENSE)
|
|
31
|
+
|
|
32
|
+
**LangChain integration for [Agent Toolbox API](https://github.com/Vincentwei1021/agent-toolbox)** — 7 tools giving your LangChain agents real-world superpowers.
|
|
33
|
+
|
|
34
|
+
| Tool | Endpoint | Description |
|
|
35
|
+
|------|----------|-------------|
|
|
36
|
+
| `AgentToolboxSearchTool` | `/v1/search` | Web search via DuckDuckGo |
|
|
37
|
+
| `AgentToolboxExtractTool` | `/v1/extract` | Extract content from any URL |
|
|
38
|
+
| `AgentToolboxScreenshotTool` | `/v1/screenshot` | Capture web page screenshots |
|
|
39
|
+
| `AgentToolboxWeatherTool` | `/v1/weather` | Current weather & forecasts |
|
|
40
|
+
| `AgentToolboxFinanceTool` | `/v1/finance` | Stock quotes & exchange rates |
|
|
41
|
+
| `AgentToolboxEmailValidatorTool` | `/v1/validate-email` | Email validation (MX + SMTP + disposable) |
|
|
42
|
+
| `AgentToolboxTranslateTool` | `/v1/translate` | Translation with auto-detect & glossary |
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install langchain-agent-toolbox
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
### Get an API Key
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
curl -X POST https://api.sendtoclaw.com/v1/auth/register \
|
|
56
|
+
-H "Content-Type: application/json" \
|
|
57
|
+
-d '{"email": "you@example.com"}'
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Set Environment Variable
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
export AGENT_TOOLBOX_API_KEY="atb_your_key_here"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Use with LangChain
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from langchain_agent_toolbox import AgentToolboxSearchTool, AgentToolboxWeatherTool
|
|
70
|
+
|
|
71
|
+
# Initialize tools
|
|
72
|
+
search = AgentToolboxSearchTool()
|
|
73
|
+
weather = AgentToolboxWeatherTool()
|
|
74
|
+
|
|
75
|
+
# Use directly
|
|
76
|
+
results = search.invoke({"query": "latest AI news", "count": 3})
|
|
77
|
+
print(results)
|
|
78
|
+
|
|
79
|
+
forecast = weather.invoke({"location": "Tokyo"})
|
|
80
|
+
print(forecast)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Use with a LangChain Agent
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from langchain_openai import ChatOpenAI
|
|
87
|
+
from langchain.agents import AgentExecutor, create_tool_calling_agent
|
|
88
|
+
from langchain_core.prompts import ChatPromptTemplate
|
|
89
|
+
from langchain_agent_toolbox import (
|
|
90
|
+
AgentToolboxSearchTool,
|
|
91
|
+
AgentToolboxExtractTool,
|
|
92
|
+
AgentToolboxWeatherTool,
|
|
93
|
+
AgentToolboxTranslateTool,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Initialize tools
|
|
97
|
+
tools = [
|
|
98
|
+
AgentToolboxSearchTool(),
|
|
99
|
+
AgentToolboxExtractTool(),
|
|
100
|
+
AgentToolboxWeatherTool(),
|
|
101
|
+
AgentToolboxTranslateTool(),
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
# Create agent
|
|
105
|
+
llm = ChatOpenAI(model="gpt-4o")
|
|
106
|
+
prompt = ChatPromptTemplate.from_messages([
|
|
107
|
+
("system", "You are a helpful assistant with access to web tools."),
|
|
108
|
+
("human", "{input}"),
|
|
109
|
+
("placeholder", "{agent_scratchpad}"),
|
|
110
|
+
])
|
|
111
|
+
|
|
112
|
+
agent = create_tool_calling_agent(llm, tools, prompt)
|
|
113
|
+
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
|
|
114
|
+
|
|
115
|
+
# Run
|
|
116
|
+
result = executor.invoke({
|
|
117
|
+
"input": "What's the weather in Paris? Also search for top restaurants there."
|
|
118
|
+
})
|
|
119
|
+
print(result["output"])
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Translation with Glossary
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from langchain_agent_toolbox import AgentToolboxTranslateTool
|
|
126
|
+
|
|
127
|
+
translate = AgentToolboxTranslateTool()
|
|
128
|
+
|
|
129
|
+
# Simple translation
|
|
130
|
+
result = translate.invoke({
|
|
131
|
+
"text": "Hello, how are you?",
|
|
132
|
+
"target": "zh",
|
|
133
|
+
})
|
|
134
|
+
print(result) # 你好,你好吗?
|
|
135
|
+
|
|
136
|
+
# With glossary (preserve technical terms)
|
|
137
|
+
result = translate.invoke({
|
|
138
|
+
"text": "The API endpoint returns JSON data.",
|
|
139
|
+
"target": "zh",
|
|
140
|
+
"glossary": {"API": "API", "JSON": "JSON", "endpoint": "端点"},
|
|
141
|
+
})
|
|
142
|
+
print(result) # API 端点 返回 JSON 数据。
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Email Validation
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from langchain_agent_toolbox import AgentToolboxEmailValidatorTool
|
|
149
|
+
|
|
150
|
+
validator = AgentToolboxEmailValidatorTool()
|
|
151
|
+
|
|
152
|
+
result = validator.invoke({"email": "test@gmail.com"})
|
|
153
|
+
print(result)
|
|
154
|
+
# {
|
|
155
|
+
# "email": "test@gmail.com",
|
|
156
|
+
# "valid_syntax": true,
|
|
157
|
+
# "mx_found": true,
|
|
158
|
+
# "is_disposable": false,
|
|
159
|
+
# "verdict": "deliverable",
|
|
160
|
+
# "score": 0.95
|
|
161
|
+
# }
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Finance: Stocks & Exchange Rates
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
from langchain_agent_toolbox import AgentToolboxFinanceTool
|
|
168
|
+
|
|
169
|
+
finance = AgentToolboxFinanceTool()
|
|
170
|
+
|
|
171
|
+
# Stock quote
|
|
172
|
+
quote = finance.invoke({"symbol": "AAPL"})
|
|
173
|
+
print(quote)
|
|
174
|
+
|
|
175
|
+
# Currency exchange
|
|
176
|
+
rate = finance.invoke({
|
|
177
|
+
"from_currency": "USD",
|
|
178
|
+
"to_currency": "EUR",
|
|
179
|
+
"amount": 100,
|
|
180
|
+
"type": "exchange",
|
|
181
|
+
})
|
|
182
|
+
print(rate)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Configuration
|
|
186
|
+
|
|
187
|
+
### API Key
|
|
188
|
+
|
|
189
|
+
Set via environment variable (recommended):
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
export AGENT_TOOLBOX_API_KEY="atb_your_key_here"
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Or pass directly:
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
tool = AgentToolboxSearchTool(api_key="atb_your_key_here")
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Custom Base URL
|
|
202
|
+
|
|
203
|
+
For self-hosted instances:
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
tool = AgentToolboxSearchTool(
|
|
207
|
+
api_key="your-key",
|
|
208
|
+
base_url="http://localhost:3100",
|
|
209
|
+
)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Or via environment variable:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
export AGENT_TOOLBOX_BASE_URL="http://localhost:3100"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Async Support
|
|
219
|
+
|
|
220
|
+
All tools support async out of the box:
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
import asyncio
|
|
224
|
+
from langchain_agent_toolbox import AgentToolboxSearchTool
|
|
225
|
+
|
|
226
|
+
async def main():
|
|
227
|
+
search = AgentToolboxSearchTool()
|
|
228
|
+
result = await search.ainvoke({"query": "async python", "count": 3})
|
|
229
|
+
print(result)
|
|
230
|
+
|
|
231
|
+
asyncio.run(main())
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## API Reference
|
|
235
|
+
|
|
236
|
+
All tools accept these common parameters:
|
|
237
|
+
|
|
238
|
+
| Parameter | Type | Default | Description |
|
|
239
|
+
|-----------|------|---------|-------------|
|
|
240
|
+
| `api_key` | `str` | `$AGENT_TOOLBOX_API_KEY` | API key for authentication |
|
|
241
|
+
| `base_url` | `str` | `https://api.sendtoclaw.com` | API base URL |
|
|
242
|
+
|
|
243
|
+
## Links
|
|
244
|
+
|
|
245
|
+
- [Agent Toolbox API](https://github.com/Vincentwei1021/agent-toolbox) — main project
|
|
246
|
+
- [OpenAPI Spec](https://api.sendtoclaw.com/v1/docs) — full API documentation
|
|
247
|
+
- [LangChain](https://python.langchain.com/) — LangChain framework
|
|
248
|
+
|
|
249
|
+
## License
|
|
250
|
+
|
|
251
|
+
MIT
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# 🧰 langchain-agent-toolbox
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/langchain-agent-toolbox/)
|
|
4
|
+
[](https://github.com/Vincentwei1021/agent-toolbox/blob/master/LICENSE)
|
|
5
|
+
|
|
6
|
+
**LangChain integration for [Agent Toolbox API](https://github.com/Vincentwei1021/agent-toolbox)** — 7 tools giving your LangChain agents real-world superpowers.
|
|
7
|
+
|
|
8
|
+
| Tool | Endpoint | Description |
|
|
9
|
+
|------|----------|-------------|
|
|
10
|
+
| `AgentToolboxSearchTool` | `/v1/search` | Web search via DuckDuckGo |
|
|
11
|
+
| `AgentToolboxExtractTool` | `/v1/extract` | Extract content from any URL |
|
|
12
|
+
| `AgentToolboxScreenshotTool` | `/v1/screenshot` | Capture web page screenshots |
|
|
13
|
+
| `AgentToolboxWeatherTool` | `/v1/weather` | Current weather & forecasts |
|
|
14
|
+
| `AgentToolboxFinanceTool` | `/v1/finance` | Stock quotes & exchange rates |
|
|
15
|
+
| `AgentToolboxEmailValidatorTool` | `/v1/validate-email` | Email validation (MX + SMTP + disposable) |
|
|
16
|
+
| `AgentToolboxTranslateTool` | `/v1/translate` | Translation with auto-detect & glossary |
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install langchain-agent-toolbox
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
### Get an API Key
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
curl -X POST https://api.sendtoclaw.com/v1/auth/register \
|
|
30
|
+
-H "Content-Type: application/json" \
|
|
31
|
+
-d '{"email": "you@example.com"}'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Set Environment Variable
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
export AGENT_TOOLBOX_API_KEY="atb_your_key_here"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Use with LangChain
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from langchain_agent_toolbox import AgentToolboxSearchTool, AgentToolboxWeatherTool
|
|
44
|
+
|
|
45
|
+
# Initialize tools
|
|
46
|
+
search = AgentToolboxSearchTool()
|
|
47
|
+
weather = AgentToolboxWeatherTool()
|
|
48
|
+
|
|
49
|
+
# Use directly
|
|
50
|
+
results = search.invoke({"query": "latest AI news", "count": 3})
|
|
51
|
+
print(results)
|
|
52
|
+
|
|
53
|
+
forecast = weather.invoke({"location": "Tokyo"})
|
|
54
|
+
print(forecast)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Use with a LangChain Agent
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from langchain_openai import ChatOpenAI
|
|
61
|
+
from langchain.agents import AgentExecutor, create_tool_calling_agent
|
|
62
|
+
from langchain_core.prompts import ChatPromptTemplate
|
|
63
|
+
from langchain_agent_toolbox import (
|
|
64
|
+
AgentToolboxSearchTool,
|
|
65
|
+
AgentToolboxExtractTool,
|
|
66
|
+
AgentToolboxWeatherTool,
|
|
67
|
+
AgentToolboxTranslateTool,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# Initialize tools
|
|
71
|
+
tools = [
|
|
72
|
+
AgentToolboxSearchTool(),
|
|
73
|
+
AgentToolboxExtractTool(),
|
|
74
|
+
AgentToolboxWeatherTool(),
|
|
75
|
+
AgentToolboxTranslateTool(),
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
# Create agent
|
|
79
|
+
llm = ChatOpenAI(model="gpt-4o")
|
|
80
|
+
prompt = ChatPromptTemplate.from_messages([
|
|
81
|
+
("system", "You are a helpful assistant with access to web tools."),
|
|
82
|
+
("human", "{input}"),
|
|
83
|
+
("placeholder", "{agent_scratchpad}"),
|
|
84
|
+
])
|
|
85
|
+
|
|
86
|
+
agent = create_tool_calling_agent(llm, tools, prompt)
|
|
87
|
+
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
|
|
88
|
+
|
|
89
|
+
# Run
|
|
90
|
+
result = executor.invoke({
|
|
91
|
+
"input": "What's the weather in Paris? Also search for top restaurants there."
|
|
92
|
+
})
|
|
93
|
+
print(result["output"])
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Translation with Glossary
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from langchain_agent_toolbox import AgentToolboxTranslateTool
|
|
100
|
+
|
|
101
|
+
translate = AgentToolboxTranslateTool()
|
|
102
|
+
|
|
103
|
+
# Simple translation
|
|
104
|
+
result = translate.invoke({
|
|
105
|
+
"text": "Hello, how are you?",
|
|
106
|
+
"target": "zh",
|
|
107
|
+
})
|
|
108
|
+
print(result) # 你好,你好吗?
|
|
109
|
+
|
|
110
|
+
# With glossary (preserve technical terms)
|
|
111
|
+
result = translate.invoke({
|
|
112
|
+
"text": "The API endpoint returns JSON data.",
|
|
113
|
+
"target": "zh",
|
|
114
|
+
"glossary": {"API": "API", "JSON": "JSON", "endpoint": "端点"},
|
|
115
|
+
})
|
|
116
|
+
print(result) # API 端点 返回 JSON 数据。
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Email Validation
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from langchain_agent_toolbox import AgentToolboxEmailValidatorTool
|
|
123
|
+
|
|
124
|
+
validator = AgentToolboxEmailValidatorTool()
|
|
125
|
+
|
|
126
|
+
result = validator.invoke({"email": "test@gmail.com"})
|
|
127
|
+
print(result)
|
|
128
|
+
# {
|
|
129
|
+
# "email": "test@gmail.com",
|
|
130
|
+
# "valid_syntax": true,
|
|
131
|
+
# "mx_found": true,
|
|
132
|
+
# "is_disposable": false,
|
|
133
|
+
# "verdict": "deliverable",
|
|
134
|
+
# "score": 0.95
|
|
135
|
+
# }
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Finance: Stocks & Exchange Rates
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from langchain_agent_toolbox import AgentToolboxFinanceTool
|
|
142
|
+
|
|
143
|
+
finance = AgentToolboxFinanceTool()
|
|
144
|
+
|
|
145
|
+
# Stock quote
|
|
146
|
+
quote = finance.invoke({"symbol": "AAPL"})
|
|
147
|
+
print(quote)
|
|
148
|
+
|
|
149
|
+
# Currency exchange
|
|
150
|
+
rate = finance.invoke({
|
|
151
|
+
"from_currency": "USD",
|
|
152
|
+
"to_currency": "EUR",
|
|
153
|
+
"amount": 100,
|
|
154
|
+
"type": "exchange",
|
|
155
|
+
})
|
|
156
|
+
print(rate)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Configuration
|
|
160
|
+
|
|
161
|
+
### API Key
|
|
162
|
+
|
|
163
|
+
Set via environment variable (recommended):
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
export AGENT_TOOLBOX_API_KEY="atb_your_key_here"
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Or pass directly:
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
tool = AgentToolboxSearchTool(api_key="atb_your_key_here")
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Custom Base URL
|
|
176
|
+
|
|
177
|
+
For self-hosted instances:
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
tool = AgentToolboxSearchTool(
|
|
181
|
+
api_key="your-key",
|
|
182
|
+
base_url="http://localhost:3100",
|
|
183
|
+
)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Or via environment variable:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
export AGENT_TOOLBOX_BASE_URL="http://localhost:3100"
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Async Support
|
|
193
|
+
|
|
194
|
+
All tools support async out of the box:
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
import asyncio
|
|
198
|
+
from langchain_agent_toolbox import AgentToolboxSearchTool
|
|
199
|
+
|
|
200
|
+
async def main():
|
|
201
|
+
search = AgentToolboxSearchTool()
|
|
202
|
+
result = await search.ainvoke({"query": "async python", "count": 3})
|
|
203
|
+
print(result)
|
|
204
|
+
|
|
205
|
+
asyncio.run(main())
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## API Reference
|
|
209
|
+
|
|
210
|
+
All tools accept these common parameters:
|
|
211
|
+
|
|
212
|
+
| Parameter | Type | Default | Description |
|
|
213
|
+
|-----------|------|---------|-------------|
|
|
214
|
+
| `api_key` | `str` | `$AGENT_TOOLBOX_API_KEY` | API key for authentication |
|
|
215
|
+
| `base_url` | `str` | `https://api.sendtoclaw.com` | API base URL |
|
|
216
|
+
|
|
217
|
+
## Links
|
|
218
|
+
|
|
219
|
+
- [Agent Toolbox API](https://github.com/Vincentwei1021/agent-toolbox) — main project
|
|
220
|
+
- [OpenAPI Spec](https://api.sendtoclaw.com/v1/docs) — full API documentation
|
|
221
|
+
- [LangChain](https://python.langchain.com/) — LangChain framework
|
|
222
|
+
|
|
223
|
+
## License
|
|
224
|
+
|
|
225
|
+
MIT
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""LangChain integration for Agent Toolbox API."""
|
|
2
|
+
|
|
3
|
+
from langchain_agent_toolbox.tools import (
|
|
4
|
+
AgentToolboxSearchTool,
|
|
5
|
+
AgentToolboxExtractTool,
|
|
6
|
+
AgentToolboxScreenshotTool,
|
|
7
|
+
AgentToolboxWeatherTool,
|
|
8
|
+
AgentToolboxFinanceTool,
|
|
9
|
+
AgentToolboxEmailValidatorTool,
|
|
10
|
+
AgentToolboxTranslateTool,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"AgentToolboxSearchTool",
|
|
15
|
+
"AgentToolboxExtractTool",
|
|
16
|
+
"AgentToolboxScreenshotTool",
|
|
17
|
+
"AgentToolboxWeatherTool",
|
|
18
|
+
"AgentToolboxFinanceTool",
|
|
19
|
+
"AgentToolboxEmailValidatorTool",
|
|
20
|
+
"AgentToolboxTranslateTool",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""HTTP client for Agent Toolbox API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Dict, Optional
|
|
6
|
+
|
|
7
|
+
import httpx
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
DEFAULT_BASE_URL = "https://api.sendtoclaw.com"
|
|
11
|
+
DEFAULT_TIMEOUT = 30.0
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AgentToolboxClient:
|
|
15
|
+
"""Thin HTTP client for the Agent Toolbox REST API."""
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
api_key: str,
|
|
20
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
21
|
+
timeout: float = DEFAULT_TIMEOUT,
|
|
22
|
+
) -> None:
|
|
23
|
+
self.api_key = api_key
|
|
24
|
+
self.base_url = base_url.rstrip("/")
|
|
25
|
+
self.timeout = timeout
|
|
26
|
+
|
|
27
|
+
def _headers(self) -> Dict[str, str]:
|
|
28
|
+
return {
|
|
29
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
30
|
+
"x-api-key": self.api_key,
|
|
31
|
+
"Content-Type": "application/json",
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
def post(self, endpoint: str, payload: Dict[str, Any]) -> Dict[str, Any]:
|
|
35
|
+
"""Synchronous POST request."""
|
|
36
|
+
url = f"{self.base_url}{endpoint}"
|
|
37
|
+
with httpx.Client(timeout=self.timeout) as client:
|
|
38
|
+
resp = client.post(url, json=payload, headers=self._headers())
|
|
39
|
+
resp.raise_for_status()
|
|
40
|
+
return resp.json()
|
|
41
|
+
|
|
42
|
+
async def apost(self, endpoint: str, payload: Dict[str, Any]) -> Dict[str, Any]:
|
|
43
|
+
"""Async POST request."""
|
|
44
|
+
url = f"{self.base_url}{endpoint}"
|
|
45
|
+
async with httpx.AsyncClient(timeout=self.timeout) as client:
|
|
46
|
+
resp = await client.post(url, json=payload, headers=self._headers())
|
|
47
|
+
resp.raise_for_status()
|
|
48
|
+
return resp.json()
|
|
File without changes
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"""LangChain tools for Agent Toolbox API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
from typing import Any, Dict, List, Optional, Type
|
|
8
|
+
|
|
9
|
+
from langchain_core.callbacks import (
|
|
10
|
+
AsyncCallbackManagerForToolRun,
|
|
11
|
+
CallbackManagerForToolRun,
|
|
12
|
+
)
|
|
13
|
+
from langchain_core.tools import BaseTool
|
|
14
|
+
from pydantic import BaseModel, Field
|
|
15
|
+
|
|
16
|
+
from langchain_agent_toolbox.client import AgentToolboxClient, DEFAULT_BASE_URL
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _get_client(
|
|
20
|
+
api_key: Optional[str] = None,
|
|
21
|
+
base_url: Optional[str] = None,
|
|
22
|
+
) -> AgentToolboxClient:
|
|
23
|
+
key = api_key or os.environ.get("AGENT_TOOLBOX_API_KEY", "")
|
|
24
|
+
if not key:
|
|
25
|
+
raise ValueError(
|
|
26
|
+
"Agent Toolbox API key is required. "
|
|
27
|
+
"Pass api_key= or set AGENT_TOOLBOX_API_KEY env var."
|
|
28
|
+
)
|
|
29
|
+
url = base_url or os.environ.get("AGENT_TOOLBOX_BASE_URL", DEFAULT_BASE_URL)
|
|
30
|
+
return AgentToolboxClient(api_key=key, base_url=url)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# ---------------------------------------------------------------------------
|
|
34
|
+
# Search
|
|
35
|
+
# ---------------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
class SearchInput(BaseModel):
|
|
38
|
+
query: str = Field(description="Search query string")
|
|
39
|
+
count: int = Field(default=5, description="Number of results (1-10)")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class AgentToolboxSearchTool(BaseTool):
|
|
43
|
+
"""Search the web using Agent Toolbox API (DuckDuckGo backend)."""
|
|
44
|
+
|
|
45
|
+
name: str = "agent_toolbox_search"
|
|
46
|
+
description: str = (
|
|
47
|
+
"Search the web and get titles, URLs, and snippets. "
|
|
48
|
+
"Useful for finding up-to-date information on any topic."
|
|
49
|
+
)
|
|
50
|
+
args_schema: Type[BaseModel] = SearchInput
|
|
51
|
+
api_key: Optional[str] = None
|
|
52
|
+
base_url: Optional[str] = None
|
|
53
|
+
|
|
54
|
+
def _run(
|
|
55
|
+
self,
|
|
56
|
+
query: str,
|
|
57
|
+
count: int = 5,
|
|
58
|
+
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
59
|
+
) -> str:
|
|
60
|
+
client = _get_client(self.api_key, self.base_url)
|
|
61
|
+
result = client.post("/v1/search", {"query": query, "count": count})
|
|
62
|
+
return json.dumps(result.get("data", []), indent=2)
|
|
63
|
+
|
|
64
|
+
async def _arun(
|
|
65
|
+
self,
|
|
66
|
+
query: str,
|
|
67
|
+
count: int = 5,
|
|
68
|
+
run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
|
|
69
|
+
) -> str:
|
|
70
|
+
client = _get_client(self.api_key, self.base_url)
|
|
71
|
+
result = await client.apost("/v1/search", {"query": query, "count": count})
|
|
72
|
+
return json.dumps(result.get("data", []), indent=2)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# ---------------------------------------------------------------------------
|
|
76
|
+
# Extract
|
|
77
|
+
# ---------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
class ExtractInput(BaseModel):
|
|
80
|
+
url: str = Field(description="URL to extract content from")
|
|
81
|
+
format: str = Field(default="markdown", description="Output format: markdown, text, or json")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class AgentToolboxExtractTool(BaseTool):
|
|
85
|
+
"""Extract readable content from a web page."""
|
|
86
|
+
|
|
87
|
+
name: str = "agent_toolbox_extract"
|
|
88
|
+
description: str = (
|
|
89
|
+
"Extract the main readable content from a web page URL. "
|
|
90
|
+
"Returns clean text/markdown, removing ads and navigation."
|
|
91
|
+
)
|
|
92
|
+
args_schema: Type[BaseModel] = ExtractInput
|
|
93
|
+
api_key: Optional[str] = None
|
|
94
|
+
base_url: Optional[str] = None
|
|
95
|
+
|
|
96
|
+
def _run(
|
|
97
|
+
self,
|
|
98
|
+
url: str,
|
|
99
|
+
format: str = "markdown",
|
|
100
|
+
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
101
|
+
) -> str:
|
|
102
|
+
client = _get_client(self.api_key, self.base_url)
|
|
103
|
+
result = client.post("/v1/extract", {"url": url, "format": format})
|
|
104
|
+
data = result.get("data", {})
|
|
105
|
+
return data.get("content", json.dumps(data, indent=2))
|
|
106
|
+
|
|
107
|
+
async def _arun(
|
|
108
|
+
self,
|
|
109
|
+
url: str,
|
|
110
|
+
format: str = "markdown",
|
|
111
|
+
run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
|
|
112
|
+
) -> str:
|
|
113
|
+
client = _get_client(self.api_key, self.base_url)
|
|
114
|
+
result = await client.apost("/v1/extract", {"url": url, "format": format})
|
|
115
|
+
data = result.get("data", {})
|
|
116
|
+
return data.get("content", json.dumps(data, indent=2))
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
# ---------------------------------------------------------------------------
|
|
120
|
+
# Screenshot
|
|
121
|
+
# ---------------------------------------------------------------------------
|
|
122
|
+
|
|
123
|
+
class ScreenshotInput(BaseModel):
|
|
124
|
+
url: str = Field(description="URL to screenshot")
|
|
125
|
+
width: int = Field(default=1280, description="Viewport width in pixels")
|
|
126
|
+
height: int = Field(default=720, description="Viewport height in pixels")
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class AgentToolboxScreenshotTool(BaseTool):
|
|
130
|
+
"""Take a screenshot of a web page."""
|
|
131
|
+
|
|
132
|
+
name: str = "agent_toolbox_screenshot"
|
|
133
|
+
description: str = (
|
|
134
|
+
"Capture a screenshot of a web page. "
|
|
135
|
+
"Returns base64-encoded PNG image data."
|
|
136
|
+
)
|
|
137
|
+
args_schema: Type[BaseModel] = ScreenshotInput
|
|
138
|
+
api_key: Optional[str] = None
|
|
139
|
+
base_url: Optional[str] = None
|
|
140
|
+
|
|
141
|
+
def _run(
|
|
142
|
+
self,
|
|
143
|
+
url: str,
|
|
144
|
+
width: int = 1280,
|
|
145
|
+
height: int = 720,
|
|
146
|
+
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
147
|
+
) -> str:
|
|
148
|
+
client = _get_client(self.api_key, self.base_url)
|
|
149
|
+
result = client.post("/v1/screenshot", {"url": url, "width": width, "height": height})
|
|
150
|
+
return json.dumps(result.get("data", {}), indent=2)
|
|
151
|
+
|
|
152
|
+
async def _arun(
|
|
153
|
+
self,
|
|
154
|
+
url: str,
|
|
155
|
+
width: int = 1280,
|
|
156
|
+
height: int = 720,
|
|
157
|
+
run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
|
|
158
|
+
) -> str:
|
|
159
|
+
client = _get_client(self.api_key, self.base_url)
|
|
160
|
+
result = await client.apost("/v1/screenshot", {"url": url, "width": width, "height": height})
|
|
161
|
+
return json.dumps(result.get("data", {}), indent=2)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
# ---------------------------------------------------------------------------
|
|
165
|
+
# Weather
|
|
166
|
+
# ---------------------------------------------------------------------------
|
|
167
|
+
|
|
168
|
+
class WeatherInput(BaseModel):
|
|
169
|
+
location: str = Field(description="City name or location")
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class AgentToolboxWeatherTool(BaseTool):
|
|
173
|
+
"""Get current weather and forecast for a location."""
|
|
174
|
+
|
|
175
|
+
name: str = "agent_toolbox_weather"
|
|
176
|
+
description: str = (
|
|
177
|
+
"Get current weather conditions and forecast for any location. "
|
|
178
|
+
"Returns temperature, humidity, wind, and multi-day forecast."
|
|
179
|
+
)
|
|
180
|
+
args_schema: Type[BaseModel] = WeatherInput
|
|
181
|
+
api_key: Optional[str] = None
|
|
182
|
+
base_url: Optional[str] = None
|
|
183
|
+
|
|
184
|
+
def _run(
|
|
185
|
+
self,
|
|
186
|
+
location: str,
|
|
187
|
+
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
188
|
+
) -> str:
|
|
189
|
+
client = _get_client(self.api_key, self.base_url)
|
|
190
|
+
result = client.post("/v1/weather", {"location": location})
|
|
191
|
+
return json.dumps(result.get("data", {}), indent=2)
|
|
192
|
+
|
|
193
|
+
async def _arun(
|
|
194
|
+
self,
|
|
195
|
+
location: str,
|
|
196
|
+
run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
|
|
197
|
+
) -> str:
|
|
198
|
+
client = _get_client(self.api_key, self.base_url)
|
|
199
|
+
result = await client.apost("/v1/weather", {"location": location})
|
|
200
|
+
return json.dumps(result.get("data", {}), indent=2)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
# ---------------------------------------------------------------------------
|
|
204
|
+
# Finance
|
|
205
|
+
# ---------------------------------------------------------------------------
|
|
206
|
+
|
|
207
|
+
class FinanceInput(BaseModel):
|
|
208
|
+
symbol: Optional[str] = Field(default=None, description="Stock ticker symbol (e.g. AAPL)")
|
|
209
|
+
type: Optional[str] = Field(default="quote", description="Request type: quote or exchange")
|
|
210
|
+
from_currency: Optional[str] = Field(default=None, description="Source currency code (for exchange)", alias="from")
|
|
211
|
+
to_currency: Optional[str] = Field(default=None, description="Target currency code (for exchange)", alias="to")
|
|
212
|
+
amount: Optional[float] = Field(default=None, description="Amount to convert (for exchange)")
|
|
213
|
+
|
|
214
|
+
class Config:
|
|
215
|
+
populate_by_name = True
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class AgentToolboxFinanceTool(BaseTool):
|
|
219
|
+
"""Get stock quotes or currency exchange rates."""
|
|
220
|
+
|
|
221
|
+
name: str = "agent_toolbox_finance"
|
|
222
|
+
description: str = (
|
|
223
|
+
"Get real-time stock quotes or currency exchange rates. "
|
|
224
|
+
"For stocks: provide symbol (e.g. 'AAPL'). "
|
|
225
|
+
"For exchange rates: provide from, to, and amount."
|
|
226
|
+
)
|
|
227
|
+
args_schema: Type[BaseModel] = FinanceInput
|
|
228
|
+
api_key: Optional[str] = None
|
|
229
|
+
base_url: Optional[str] = None
|
|
230
|
+
|
|
231
|
+
def _run(
|
|
232
|
+
self,
|
|
233
|
+
symbol: Optional[str] = None,
|
|
234
|
+
type: Optional[str] = "quote",
|
|
235
|
+
from_currency: Optional[str] = None,
|
|
236
|
+
to_currency: Optional[str] = None,
|
|
237
|
+
amount: Optional[float] = None,
|
|
238
|
+
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
239
|
+
**kwargs: Any,
|
|
240
|
+
) -> str:
|
|
241
|
+
client = _get_client(self.api_key, self.base_url)
|
|
242
|
+
payload: Dict[str, Any] = {}
|
|
243
|
+
if symbol:
|
|
244
|
+
payload = {"symbol": symbol, "type": type or "quote"}
|
|
245
|
+
elif from_currency and to_currency:
|
|
246
|
+
payload = {"from": from_currency, "to": to_currency, "amount": amount or 1}
|
|
247
|
+
result = client.post("/v1/finance", payload)
|
|
248
|
+
return json.dumps(result.get("data", {}), indent=2)
|
|
249
|
+
|
|
250
|
+
async def _arun(
|
|
251
|
+
self,
|
|
252
|
+
symbol: Optional[str] = None,
|
|
253
|
+
type: Optional[str] = "quote",
|
|
254
|
+
from_currency: Optional[str] = None,
|
|
255
|
+
to_currency: Optional[str] = None,
|
|
256
|
+
amount: Optional[float] = None,
|
|
257
|
+
run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
|
|
258
|
+
**kwargs: Any,
|
|
259
|
+
) -> str:
|
|
260
|
+
client = _get_client(self.api_key, self.base_url)
|
|
261
|
+
payload: Dict[str, Any] = {}
|
|
262
|
+
if symbol:
|
|
263
|
+
payload = {"symbol": symbol, "type": type or "quote"}
|
|
264
|
+
elif from_currency and to_currency:
|
|
265
|
+
payload = {"from": from_currency, "to": to_currency, "amount": amount or 1}
|
|
266
|
+
result = await client.apost("/v1/finance", payload)
|
|
267
|
+
return json.dumps(result.get("data", {}), indent=2)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
# ---------------------------------------------------------------------------
|
|
271
|
+
# Email Validator
|
|
272
|
+
# ---------------------------------------------------------------------------
|
|
273
|
+
|
|
274
|
+
class EmailValidatorInput(BaseModel):
|
|
275
|
+
email: str = Field(description="Email address to validate")
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
class AgentToolboxEmailValidatorTool(BaseTool):
|
|
279
|
+
"""Validate an email address (syntax, MX, SMTP, disposable check)."""
|
|
280
|
+
|
|
281
|
+
name: str = "agent_toolbox_email_validator"
|
|
282
|
+
description: str = (
|
|
283
|
+
"Validate an email address by checking syntax, MX records, "
|
|
284
|
+
"SMTP reachability, and disposable domain detection. "
|
|
285
|
+
"Returns a verdict: deliverable, risky, undeliverable, or invalid."
|
|
286
|
+
)
|
|
287
|
+
args_schema: Type[BaseModel] = EmailValidatorInput
|
|
288
|
+
api_key: Optional[str] = None
|
|
289
|
+
base_url: Optional[str] = None
|
|
290
|
+
|
|
291
|
+
def _run(
|
|
292
|
+
self,
|
|
293
|
+
email: str,
|
|
294
|
+
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
295
|
+
) -> str:
|
|
296
|
+
client = _get_client(self.api_key, self.base_url)
|
|
297
|
+
result = client.post("/v1/validate-email", {"email": email})
|
|
298
|
+
return json.dumps(result.get("data", {}), indent=2)
|
|
299
|
+
|
|
300
|
+
async def _arun(
|
|
301
|
+
self,
|
|
302
|
+
email: str,
|
|
303
|
+
run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
|
|
304
|
+
) -> str:
|
|
305
|
+
client = _get_client(self.api_key, self.base_url)
|
|
306
|
+
result = await client.apost("/v1/validate-email", {"email": email})
|
|
307
|
+
return json.dumps(result.get("data", {}), indent=2)
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
# ---------------------------------------------------------------------------
|
|
311
|
+
# Translate
|
|
312
|
+
# ---------------------------------------------------------------------------
|
|
313
|
+
|
|
314
|
+
class TranslateInput(BaseModel):
|
|
315
|
+
text: str = Field(description="Text to translate")
|
|
316
|
+
target: str = Field(description="Target language code (e.g. zh, ja, es, fr)")
|
|
317
|
+
source: str = Field(default="auto", description="Source language code or 'auto'")
|
|
318
|
+
glossary: Optional[Dict[str, str]] = Field(default=None, description="Optional glossary: {term: translation}")
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
class AgentToolboxTranslateTool(BaseTool):
|
|
322
|
+
"""Translate text between 100+ languages."""
|
|
323
|
+
|
|
324
|
+
name: str = "agent_toolbox_translate"
|
|
325
|
+
description: str = (
|
|
326
|
+
"Translate text between languages with automatic language detection. "
|
|
327
|
+
"Supports glossary for preserving specific terms. "
|
|
328
|
+
"Provide target language code (e.g. 'zh' for Chinese, 'ja' for Japanese)."
|
|
329
|
+
)
|
|
330
|
+
args_schema: Type[BaseModel] = TranslateInput
|
|
331
|
+
api_key: Optional[str] = None
|
|
332
|
+
base_url: Optional[str] = None
|
|
333
|
+
|
|
334
|
+
def _run(
|
|
335
|
+
self,
|
|
336
|
+
text: str,
|
|
337
|
+
target: str,
|
|
338
|
+
source: str = "auto",
|
|
339
|
+
glossary: Optional[Dict[str, str]] = None,
|
|
340
|
+
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
341
|
+
) -> str:
|
|
342
|
+
client = _get_client(self.api_key, self.base_url)
|
|
343
|
+
payload: Dict[str, Any] = {"text": text, "target": target, "source": source}
|
|
344
|
+
if glossary:
|
|
345
|
+
payload["glossary"] = glossary
|
|
346
|
+
result = client.post("/v1/translate", payload)
|
|
347
|
+
data = result.get("data", {})
|
|
348
|
+
return data.get("translation", json.dumps(data, indent=2))
|
|
349
|
+
|
|
350
|
+
async def _arun(
|
|
351
|
+
self,
|
|
352
|
+
text: str,
|
|
353
|
+
target: str,
|
|
354
|
+
source: str = "auto",
|
|
355
|
+
glossary: Optional[Dict[str, str]] = None,
|
|
356
|
+
run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
|
|
357
|
+
) -> str:
|
|
358
|
+
client = _get_client(self.api_key, self.base_url)
|
|
359
|
+
payload: Dict[str, Any] = {"text": text, "target": target, "source": source}
|
|
360
|
+
if glossary:
|
|
361
|
+
payload["glossary"] = glossary
|
|
362
|
+
result = await client.apost("/v1/translate", payload)
|
|
363
|
+
data = result.get("data", {})
|
|
364
|
+
return data.get("translation", json.dumps(data, indent=2))
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: langchain-agent-toolbox
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: LangChain integration for Agent Toolbox API — search, extract, screenshot, weather, finance, email validation, and translation tools for AI agents
|
|
5
|
+
Author-email: Agent Toolbox <hello@agenttoolbox.dev>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Vincentwei1021/agent-toolbox
|
|
8
|
+
Project-URL: Repository, https://github.com/Vincentwei1021/agent-toolbox/tree/master/integrations/langchain
|
|
9
|
+
Project-URL: Documentation, https://github.com/Vincentwei1021/agent-toolbox#readme
|
|
10
|
+
Project-URL: Issues, https://github.com/Vincentwei1021/agent-toolbox/issues
|
|
11
|
+
Keywords: langchain,ai-agent,tools,mcp,search,web-scraping,screenshot,weather,finance,email-validation,translation
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
Requires-Dist: langchain-core>=0.2.0
|
|
25
|
+
Requires-Dist: httpx>=0.25.0
|
|
26
|
+
|
|
27
|
+
# 🧰 langchain-agent-toolbox
|
|
28
|
+
|
|
29
|
+
[](https://pypi.org/project/langchain-agent-toolbox/)
|
|
30
|
+
[](https://github.com/Vincentwei1021/agent-toolbox/blob/master/LICENSE)
|
|
31
|
+
|
|
32
|
+
**LangChain integration for [Agent Toolbox API](https://github.com/Vincentwei1021/agent-toolbox)** — 7 tools giving your LangChain agents real-world superpowers.
|
|
33
|
+
|
|
34
|
+
| Tool | Endpoint | Description |
|
|
35
|
+
|------|----------|-------------|
|
|
36
|
+
| `AgentToolboxSearchTool` | `/v1/search` | Web search via DuckDuckGo |
|
|
37
|
+
| `AgentToolboxExtractTool` | `/v1/extract` | Extract content from any URL |
|
|
38
|
+
| `AgentToolboxScreenshotTool` | `/v1/screenshot` | Capture web page screenshots |
|
|
39
|
+
| `AgentToolboxWeatherTool` | `/v1/weather` | Current weather & forecasts |
|
|
40
|
+
| `AgentToolboxFinanceTool` | `/v1/finance` | Stock quotes & exchange rates |
|
|
41
|
+
| `AgentToolboxEmailValidatorTool` | `/v1/validate-email` | Email validation (MX + SMTP + disposable) |
|
|
42
|
+
| `AgentToolboxTranslateTool` | `/v1/translate` | Translation with auto-detect & glossary |
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install langchain-agent-toolbox
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
### Get an API Key
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
curl -X POST https://api.sendtoclaw.com/v1/auth/register \
|
|
56
|
+
-H "Content-Type: application/json" \
|
|
57
|
+
-d '{"email": "you@example.com"}'
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Set Environment Variable
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
export AGENT_TOOLBOX_API_KEY="atb_your_key_here"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Use with LangChain
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from langchain_agent_toolbox import AgentToolboxSearchTool, AgentToolboxWeatherTool
|
|
70
|
+
|
|
71
|
+
# Initialize tools
|
|
72
|
+
search = AgentToolboxSearchTool()
|
|
73
|
+
weather = AgentToolboxWeatherTool()
|
|
74
|
+
|
|
75
|
+
# Use directly
|
|
76
|
+
results = search.invoke({"query": "latest AI news", "count": 3})
|
|
77
|
+
print(results)
|
|
78
|
+
|
|
79
|
+
forecast = weather.invoke({"location": "Tokyo"})
|
|
80
|
+
print(forecast)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Use with a LangChain Agent
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from langchain_openai import ChatOpenAI
|
|
87
|
+
from langchain.agents import AgentExecutor, create_tool_calling_agent
|
|
88
|
+
from langchain_core.prompts import ChatPromptTemplate
|
|
89
|
+
from langchain_agent_toolbox import (
|
|
90
|
+
AgentToolboxSearchTool,
|
|
91
|
+
AgentToolboxExtractTool,
|
|
92
|
+
AgentToolboxWeatherTool,
|
|
93
|
+
AgentToolboxTranslateTool,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Initialize tools
|
|
97
|
+
tools = [
|
|
98
|
+
AgentToolboxSearchTool(),
|
|
99
|
+
AgentToolboxExtractTool(),
|
|
100
|
+
AgentToolboxWeatherTool(),
|
|
101
|
+
AgentToolboxTranslateTool(),
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
# Create agent
|
|
105
|
+
llm = ChatOpenAI(model="gpt-4o")
|
|
106
|
+
prompt = ChatPromptTemplate.from_messages([
|
|
107
|
+
("system", "You are a helpful assistant with access to web tools."),
|
|
108
|
+
("human", "{input}"),
|
|
109
|
+
("placeholder", "{agent_scratchpad}"),
|
|
110
|
+
])
|
|
111
|
+
|
|
112
|
+
agent = create_tool_calling_agent(llm, tools, prompt)
|
|
113
|
+
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
|
|
114
|
+
|
|
115
|
+
# Run
|
|
116
|
+
result = executor.invoke({
|
|
117
|
+
"input": "What's the weather in Paris? Also search for top restaurants there."
|
|
118
|
+
})
|
|
119
|
+
print(result["output"])
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Translation with Glossary
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from langchain_agent_toolbox import AgentToolboxTranslateTool
|
|
126
|
+
|
|
127
|
+
translate = AgentToolboxTranslateTool()
|
|
128
|
+
|
|
129
|
+
# Simple translation
|
|
130
|
+
result = translate.invoke({
|
|
131
|
+
"text": "Hello, how are you?",
|
|
132
|
+
"target": "zh",
|
|
133
|
+
})
|
|
134
|
+
print(result) # 你好,你好吗?
|
|
135
|
+
|
|
136
|
+
# With glossary (preserve technical terms)
|
|
137
|
+
result = translate.invoke({
|
|
138
|
+
"text": "The API endpoint returns JSON data.",
|
|
139
|
+
"target": "zh",
|
|
140
|
+
"glossary": {"API": "API", "JSON": "JSON", "endpoint": "端点"},
|
|
141
|
+
})
|
|
142
|
+
print(result) # API 端点 返回 JSON 数据。
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Email Validation
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from langchain_agent_toolbox import AgentToolboxEmailValidatorTool
|
|
149
|
+
|
|
150
|
+
validator = AgentToolboxEmailValidatorTool()
|
|
151
|
+
|
|
152
|
+
result = validator.invoke({"email": "test@gmail.com"})
|
|
153
|
+
print(result)
|
|
154
|
+
# {
|
|
155
|
+
# "email": "test@gmail.com",
|
|
156
|
+
# "valid_syntax": true,
|
|
157
|
+
# "mx_found": true,
|
|
158
|
+
# "is_disposable": false,
|
|
159
|
+
# "verdict": "deliverable",
|
|
160
|
+
# "score": 0.95
|
|
161
|
+
# }
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Finance: Stocks & Exchange Rates
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
from langchain_agent_toolbox import AgentToolboxFinanceTool
|
|
168
|
+
|
|
169
|
+
finance = AgentToolboxFinanceTool()
|
|
170
|
+
|
|
171
|
+
# Stock quote
|
|
172
|
+
quote = finance.invoke({"symbol": "AAPL"})
|
|
173
|
+
print(quote)
|
|
174
|
+
|
|
175
|
+
# Currency exchange
|
|
176
|
+
rate = finance.invoke({
|
|
177
|
+
"from_currency": "USD",
|
|
178
|
+
"to_currency": "EUR",
|
|
179
|
+
"amount": 100,
|
|
180
|
+
"type": "exchange",
|
|
181
|
+
})
|
|
182
|
+
print(rate)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Configuration
|
|
186
|
+
|
|
187
|
+
### API Key
|
|
188
|
+
|
|
189
|
+
Set via environment variable (recommended):
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
export AGENT_TOOLBOX_API_KEY="atb_your_key_here"
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Or pass directly:
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
tool = AgentToolboxSearchTool(api_key="atb_your_key_here")
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Custom Base URL
|
|
202
|
+
|
|
203
|
+
For self-hosted instances:
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
tool = AgentToolboxSearchTool(
|
|
207
|
+
api_key="your-key",
|
|
208
|
+
base_url="http://localhost:3100",
|
|
209
|
+
)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Or via environment variable:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
export AGENT_TOOLBOX_BASE_URL="http://localhost:3100"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Async Support
|
|
219
|
+
|
|
220
|
+
All tools support async out of the box:
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
import asyncio
|
|
224
|
+
from langchain_agent_toolbox import AgentToolboxSearchTool
|
|
225
|
+
|
|
226
|
+
async def main():
|
|
227
|
+
search = AgentToolboxSearchTool()
|
|
228
|
+
result = await search.ainvoke({"query": "async python", "count": 3})
|
|
229
|
+
print(result)
|
|
230
|
+
|
|
231
|
+
asyncio.run(main())
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## API Reference
|
|
235
|
+
|
|
236
|
+
All tools accept these common parameters:
|
|
237
|
+
|
|
238
|
+
| Parameter | Type | Default | Description |
|
|
239
|
+
|-----------|------|---------|-------------|
|
|
240
|
+
| `api_key` | `str` | `$AGENT_TOOLBOX_API_KEY` | API key for authentication |
|
|
241
|
+
| `base_url` | `str` | `https://api.sendtoclaw.com` | API base URL |
|
|
242
|
+
|
|
243
|
+
## Links
|
|
244
|
+
|
|
245
|
+
- [Agent Toolbox API](https://github.com/Vincentwei1021/agent-toolbox) — main project
|
|
246
|
+
- [OpenAPI Spec](https://api.sendtoclaw.com/v1/docs) — full API documentation
|
|
247
|
+
- [LangChain](https://python.langchain.com/) — LangChain framework
|
|
248
|
+
|
|
249
|
+
## License
|
|
250
|
+
|
|
251
|
+
MIT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
langchain_agent_toolbox/__init__.py
|
|
4
|
+
langchain_agent_toolbox/client.py
|
|
5
|
+
langchain_agent_toolbox/py.typed
|
|
6
|
+
langchain_agent_toolbox/tools.py
|
|
7
|
+
langchain_agent_toolbox.egg-info/PKG-INFO
|
|
8
|
+
langchain_agent_toolbox.egg-info/SOURCES.txt
|
|
9
|
+
langchain_agent_toolbox.egg-info/dependency_links.txt
|
|
10
|
+
langchain_agent_toolbox.egg-info/requires.txt
|
|
11
|
+
langchain_agent_toolbox.egg-info/top_level.txt
|
|
12
|
+
tests/test_tools.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
langchain_agent_toolbox
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "langchain-agent-toolbox"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "LangChain integration for Agent Toolbox API — search, extract, screenshot, weather, finance, email validation, and translation tools for AI agents"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Agent Toolbox", email = "hello@agenttoolbox.dev"},
|
|
14
|
+
]
|
|
15
|
+
keywords = ["langchain", "ai-agent", "tools", "mcp", "search", "web-scraping", "screenshot", "weather", "finance", "email-validation", "translation"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.9",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Topic :: Software Development :: Libraries",
|
|
26
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
27
|
+
]
|
|
28
|
+
dependencies = [
|
|
29
|
+
"langchain-core>=0.2.0",
|
|
30
|
+
"httpx>=0.25.0",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://github.com/Vincentwei1021/agent-toolbox"
|
|
35
|
+
Repository = "https://github.com/Vincentwei1021/agent-toolbox/tree/master/integrations/langchain"
|
|
36
|
+
Documentation = "https://github.com/Vincentwei1021/agent-toolbox#readme"
|
|
37
|
+
Issues = "https://github.com/Vincentwei1021/agent-toolbox/issues"
|
|
38
|
+
|
|
39
|
+
[tool.setuptools.packages.find]
|
|
40
|
+
include = ["langchain_agent_toolbox*"]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Basic import and instantiation tests for langchain-agent-toolbox."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_imports():
|
|
8
|
+
from langchain_agent_toolbox import (
|
|
9
|
+
AgentToolboxSearchTool,
|
|
10
|
+
AgentToolboxExtractTool,
|
|
11
|
+
AgentToolboxScreenshotTool,
|
|
12
|
+
AgentToolboxWeatherTool,
|
|
13
|
+
AgentToolboxFinanceTool,
|
|
14
|
+
AgentToolboxEmailValidatorTool,
|
|
15
|
+
AgentToolboxTranslateTool,
|
|
16
|
+
)
|
|
17
|
+
assert AgentToolboxSearchTool is not None
|
|
18
|
+
assert AgentToolboxTranslateTool is not None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_tool_instantiation():
|
|
22
|
+
from langchain_agent_toolbox import AgentToolboxSearchTool
|
|
23
|
+
tool = AgentToolboxSearchTool(api_key="test-key")
|
|
24
|
+
assert tool.name == "agent_toolbox_search"
|
|
25
|
+
assert "search" in tool.description.lower()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_tool_schema():
|
|
29
|
+
from langchain_agent_toolbox import AgentToolboxTranslateTool
|
|
30
|
+
tool = AgentToolboxTranslateTool(api_key="test-key")
|
|
31
|
+
schema = tool.args_schema.model_json_schema()
|
|
32
|
+
assert "text" in schema["properties"]
|
|
33
|
+
assert "target" in schema["properties"]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_missing_api_key():
|
|
37
|
+
from langchain_agent_toolbox import AgentToolboxSearchTool
|
|
38
|
+
# Clear env var if set
|
|
39
|
+
os.environ.pop("AGENT_TOOLBOX_API_KEY", None)
|
|
40
|
+
tool = AgentToolboxSearchTool()
|
|
41
|
+
with pytest.raises(ValueError, match="API key is required"):
|
|
42
|
+
tool._run(query="test")
|