dominusnode-langchain 1.0.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.
- dominusnode_langchain-1.0.0/.gitignore +16 -0
- dominusnode_langchain-1.0.0/CHANGELOG.md +8 -0
- dominusnode_langchain-1.0.0/LICENSE +21 -0
- dominusnode_langchain-1.0.0/PKG-INFO +220 -0
- dominusnode_langchain-1.0.0/README.md +205 -0
- dominusnode_langchain-1.0.0/conftest.py +105 -0
- dominusnode_langchain-1.0.0/dominusnode_langchain/__init__.py +55 -0
- dominusnode_langchain-1.0.0/dominusnode_langchain/toolkit.py +195 -0
- dominusnode_langchain-1.0.0/dominusnode_langchain/tools.py +1706 -0
- dominusnode_langchain-1.0.0/pyproject.toml +22 -0
- dominusnode_langchain-1.0.0/tests/__init__.py +0 -0
- dominusnode_langchain-1.0.0/tests/test_tools.py +945 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dominus Node
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dominusnode-langchain
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: LangChain tools for DomiNode rotating proxy service
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Requires-Dist: dominusnode>=0.1.0
|
|
9
|
+
Requires-Dist: httpx>=0.24.0
|
|
10
|
+
Requires-Dist: langchain-core>=0.2.0
|
|
11
|
+
Provides-Extra: dev
|
|
12
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
13
|
+
Requires-Dist: pytest-asyncio; extra == 'dev'
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# DomiNode LangChain Integration
|
|
17
|
+
|
|
18
|
+
LangChain tools for the [DomiNode](https://dominusnode.com) rotating proxy-as-a-service platform. Enables LangChain agents to make proxied HTTP requests, check wallet balances, monitor usage, and query proxy configuration through the DomiNode network.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install dominusnode-langchain
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or install from source:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd integrations/langchain
|
|
30
|
+
pip install -e ".[dev]"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Dependencies
|
|
34
|
+
|
|
35
|
+
- `langchain-core >= 0.2.0`
|
|
36
|
+
- `dominusnode >= 0.1.0` (DomiNode Python SDK)
|
|
37
|
+
- `httpx >= 0.24.0`
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
### Environment Variables
|
|
42
|
+
|
|
43
|
+
Set up your DomiNode credentials:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
export DOMINUSNODE_API_KEY="dn_live_your_api_key_here"
|
|
47
|
+
export DOMINUSNODE_BASE_URL="https://api.dominusnode.com" # optional, this is the default
|
|
48
|
+
export DOMINUSNODE_PROXY_HOST="proxy.dominusnode.com" # optional, this is the default
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Basic Usage with a LangChain Agent
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from langchain_openai import ChatOpenAI
|
|
55
|
+
from langchain.agents import AgentExecutor, create_tool_calling_agent
|
|
56
|
+
from langchain_core.prompts import ChatPromptTemplate
|
|
57
|
+
|
|
58
|
+
from dominusnode_langchain import DominusNodeToolkit
|
|
59
|
+
|
|
60
|
+
# Initialize the toolkit (reads DOMINUSNODE_API_KEY from env)
|
|
61
|
+
toolkit = DominusNodeToolkit()
|
|
62
|
+
tools = toolkit.get_tools()
|
|
63
|
+
|
|
64
|
+
# Set up a LangChain agent
|
|
65
|
+
llm = ChatOpenAI(model="gpt-4o")
|
|
66
|
+
prompt = ChatPromptTemplate.from_messages([
|
|
67
|
+
("system", "You are a helpful assistant with access to a proxy network."),
|
|
68
|
+
("human", "{input}"),
|
|
69
|
+
("placeholder", "{agent_scratchpad}"),
|
|
70
|
+
])
|
|
71
|
+
|
|
72
|
+
agent = create_tool_calling_agent(llm, tools, prompt)
|
|
73
|
+
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
|
|
74
|
+
|
|
75
|
+
# Run the agent
|
|
76
|
+
result = executor.invoke({
|
|
77
|
+
"input": "Check my proxy balance, then fetch https://httpbin.org/ip through a US proxy"
|
|
78
|
+
})
|
|
79
|
+
print(result["output"])
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Direct Tool Usage
|
|
83
|
+
|
|
84
|
+
You can also use the tools directly without an agent:
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from dominusnode_langchain import (
|
|
88
|
+
DominusNodeToolkit,
|
|
89
|
+
DominusNodeProxiedFetchTool,
|
|
90
|
+
DominusNodeBalanceTool,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
toolkit = DominusNodeToolkit(api_key="dn_live_your_key")
|
|
94
|
+
tools = toolkit.get_tools()
|
|
95
|
+
|
|
96
|
+
# Get tools by name
|
|
97
|
+
fetch_tool = next(t for t in tools if t.name == "dominusnode_proxied_fetch")
|
|
98
|
+
balance_tool = next(t for t in tools if t.name == "dominusnode_balance")
|
|
99
|
+
|
|
100
|
+
# Check balance
|
|
101
|
+
print(balance_tool.run({}))
|
|
102
|
+
# Output: Balance: $50.00 (5000 cents)
|
|
103
|
+
# Currency: usd
|
|
104
|
+
|
|
105
|
+
# Fetch a URL through a US proxy
|
|
106
|
+
print(fetch_tool.run({
|
|
107
|
+
"url": "https://httpbin.org/ip",
|
|
108
|
+
"country": "US",
|
|
109
|
+
"proxy_type": "dc",
|
|
110
|
+
}))
|
|
111
|
+
# Output: Status: 200
|
|
112
|
+
# Content-Type: application/json
|
|
113
|
+
# Body:
|
|
114
|
+
# { "origin": "203.0.113.42" }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Tools
|
|
118
|
+
|
|
119
|
+
### `dominusnode_proxied_fetch`
|
|
120
|
+
|
|
121
|
+
Makes HTTP requests through the DomiNode rotating proxy network.
|
|
122
|
+
|
|
123
|
+
| Parameter | Type | Default | Description |
|
|
124
|
+
|-----------|------|---------|-------------|
|
|
125
|
+
| `url` | str | *required* | The URL to fetch |
|
|
126
|
+
| `method` | str | `"GET"` | HTTP method (`GET`, `HEAD`, or `OPTIONS`) |
|
|
127
|
+
| `country` | str | `None` | ISO 3166-1 alpha-2 country code (e.g. `"US"`, `"GB"`, `"DE"`) |
|
|
128
|
+
| `proxy_type` | str | `"dc"` | `"dc"` for datacenter ($3/GB) or `"residential"` ($5/GB) |
|
|
129
|
+
|
|
130
|
+
**Security:**
|
|
131
|
+
- Only read-only HTTP methods (GET, HEAD, OPTIONS) are allowed
|
|
132
|
+
- SSRF protection blocks private IPs, localhost, and reserved ranges
|
|
133
|
+
- Response bodies are truncated to 4,000 characters
|
|
134
|
+
- `file://`, `ftp://`, and other non-HTTP schemes are rejected
|
|
135
|
+
- URLs with embedded credentials are rejected
|
|
136
|
+
|
|
137
|
+
### `dominusnode_balance`
|
|
138
|
+
|
|
139
|
+
Check your DomiNode wallet balance. No input required.
|
|
140
|
+
|
|
141
|
+
Returns the balance in both USD and cents.
|
|
142
|
+
|
|
143
|
+
### `dominusnode_usage`
|
|
144
|
+
|
|
145
|
+
Check your DomiNode proxy usage statistics. No input required.
|
|
146
|
+
|
|
147
|
+
Returns total bandwidth used (GB), total cost, and request count.
|
|
148
|
+
|
|
149
|
+
### `dominusnode_proxy_config`
|
|
150
|
+
|
|
151
|
+
Get the DomiNode proxy configuration. No input required.
|
|
152
|
+
|
|
153
|
+
Returns proxy endpoints, supported countries for geo-targeting, blocked countries, rotation intervals, and available geo-targeting features (state, city, ASN).
|
|
154
|
+
|
|
155
|
+
## Async Usage
|
|
156
|
+
|
|
157
|
+
All tools support async execution for use with async LangChain agents:
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
import asyncio
|
|
161
|
+
from dominusnode_langchain import DominusNodeToolkit
|
|
162
|
+
|
|
163
|
+
async def main():
|
|
164
|
+
toolkit = DominusNodeToolkit(api_key="dn_live_your_key")
|
|
165
|
+
tools = toolkit.get_tools()
|
|
166
|
+
|
|
167
|
+
balance_tool = next(t for t in tools if t.name == "dominusnode_balance")
|
|
168
|
+
fetch_tool = next(t for t in tools if t.name == "dominusnode_proxied_fetch")
|
|
169
|
+
|
|
170
|
+
# Async balance check
|
|
171
|
+
balance = await balance_tool.arun({})
|
|
172
|
+
print(balance)
|
|
173
|
+
|
|
174
|
+
# Async proxied fetch
|
|
175
|
+
result = await fetch_tool.arun({
|
|
176
|
+
"url": "https://httpbin.org/headers",
|
|
177
|
+
"country": "GB",
|
|
178
|
+
})
|
|
179
|
+
print(result)
|
|
180
|
+
|
|
181
|
+
toolkit.close()
|
|
182
|
+
|
|
183
|
+
asyncio.run(main())
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Explicit Credentials
|
|
187
|
+
|
|
188
|
+
If you prefer not to use environment variables:
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
from dominusnode_langchain import DominusNodeToolkit
|
|
192
|
+
|
|
193
|
+
toolkit = DominusNodeToolkit(
|
|
194
|
+
api_key="dn_live_abc123",
|
|
195
|
+
base_url="http://localhost:3000",
|
|
196
|
+
proxy_host="localhost",
|
|
197
|
+
http_proxy_port=8080,
|
|
198
|
+
socks5_proxy_port=1080,
|
|
199
|
+
)
|
|
200
|
+
tools = toolkit.get_tools()
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Running Tests
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
cd integrations/langchain
|
|
207
|
+
pip install -e ".[dev]"
|
|
208
|
+
pytest tests/ -v
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Pricing Reference
|
|
212
|
+
|
|
213
|
+
| Proxy Type | Cost to You | Sell Price | Margin |
|
|
214
|
+
|-----------|-------------|------------|--------|
|
|
215
|
+
| Datacenter | $0.012/GB | $3.00/GB | 99.6% |
|
|
216
|
+
| Residential | $4.00/GB | $5.00/GB | 20% |
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# DomiNode LangChain Integration
|
|
2
|
+
|
|
3
|
+
LangChain tools for the [DomiNode](https://dominusnode.com) rotating proxy-as-a-service platform. Enables LangChain agents to make proxied HTTP requests, check wallet balances, monitor usage, and query proxy configuration through the DomiNode network.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install dominusnode-langchain
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or install from source:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
cd integrations/langchain
|
|
15
|
+
pip install -e ".[dev]"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Dependencies
|
|
19
|
+
|
|
20
|
+
- `langchain-core >= 0.2.0`
|
|
21
|
+
- `dominusnode >= 0.1.0` (DomiNode Python SDK)
|
|
22
|
+
- `httpx >= 0.24.0`
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
### Environment Variables
|
|
27
|
+
|
|
28
|
+
Set up your DomiNode credentials:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
export DOMINUSNODE_API_KEY="dn_live_your_api_key_here"
|
|
32
|
+
export DOMINUSNODE_BASE_URL="https://api.dominusnode.com" # optional, this is the default
|
|
33
|
+
export DOMINUSNODE_PROXY_HOST="proxy.dominusnode.com" # optional, this is the default
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Basic Usage with a LangChain Agent
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from langchain_openai import ChatOpenAI
|
|
40
|
+
from langchain.agents import AgentExecutor, create_tool_calling_agent
|
|
41
|
+
from langchain_core.prompts import ChatPromptTemplate
|
|
42
|
+
|
|
43
|
+
from dominusnode_langchain import DominusNodeToolkit
|
|
44
|
+
|
|
45
|
+
# Initialize the toolkit (reads DOMINUSNODE_API_KEY from env)
|
|
46
|
+
toolkit = DominusNodeToolkit()
|
|
47
|
+
tools = toolkit.get_tools()
|
|
48
|
+
|
|
49
|
+
# Set up a LangChain agent
|
|
50
|
+
llm = ChatOpenAI(model="gpt-4o")
|
|
51
|
+
prompt = ChatPromptTemplate.from_messages([
|
|
52
|
+
("system", "You are a helpful assistant with access to a proxy network."),
|
|
53
|
+
("human", "{input}"),
|
|
54
|
+
("placeholder", "{agent_scratchpad}"),
|
|
55
|
+
])
|
|
56
|
+
|
|
57
|
+
agent = create_tool_calling_agent(llm, tools, prompt)
|
|
58
|
+
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
|
|
59
|
+
|
|
60
|
+
# Run the agent
|
|
61
|
+
result = executor.invoke({
|
|
62
|
+
"input": "Check my proxy balance, then fetch https://httpbin.org/ip through a US proxy"
|
|
63
|
+
})
|
|
64
|
+
print(result["output"])
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Direct Tool Usage
|
|
68
|
+
|
|
69
|
+
You can also use the tools directly without an agent:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from dominusnode_langchain import (
|
|
73
|
+
DominusNodeToolkit,
|
|
74
|
+
DominusNodeProxiedFetchTool,
|
|
75
|
+
DominusNodeBalanceTool,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
toolkit = DominusNodeToolkit(api_key="dn_live_your_key")
|
|
79
|
+
tools = toolkit.get_tools()
|
|
80
|
+
|
|
81
|
+
# Get tools by name
|
|
82
|
+
fetch_tool = next(t for t in tools if t.name == "dominusnode_proxied_fetch")
|
|
83
|
+
balance_tool = next(t for t in tools if t.name == "dominusnode_balance")
|
|
84
|
+
|
|
85
|
+
# Check balance
|
|
86
|
+
print(balance_tool.run({}))
|
|
87
|
+
# Output: Balance: $50.00 (5000 cents)
|
|
88
|
+
# Currency: usd
|
|
89
|
+
|
|
90
|
+
# Fetch a URL through a US proxy
|
|
91
|
+
print(fetch_tool.run({
|
|
92
|
+
"url": "https://httpbin.org/ip",
|
|
93
|
+
"country": "US",
|
|
94
|
+
"proxy_type": "dc",
|
|
95
|
+
}))
|
|
96
|
+
# Output: Status: 200
|
|
97
|
+
# Content-Type: application/json
|
|
98
|
+
# Body:
|
|
99
|
+
# { "origin": "203.0.113.42" }
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Tools
|
|
103
|
+
|
|
104
|
+
### `dominusnode_proxied_fetch`
|
|
105
|
+
|
|
106
|
+
Makes HTTP requests through the DomiNode rotating proxy network.
|
|
107
|
+
|
|
108
|
+
| Parameter | Type | Default | Description |
|
|
109
|
+
|-----------|------|---------|-------------|
|
|
110
|
+
| `url` | str | *required* | The URL to fetch |
|
|
111
|
+
| `method` | str | `"GET"` | HTTP method (`GET`, `HEAD`, or `OPTIONS`) |
|
|
112
|
+
| `country` | str | `None` | ISO 3166-1 alpha-2 country code (e.g. `"US"`, `"GB"`, `"DE"`) |
|
|
113
|
+
| `proxy_type` | str | `"dc"` | `"dc"` for datacenter ($3/GB) or `"residential"` ($5/GB) |
|
|
114
|
+
|
|
115
|
+
**Security:**
|
|
116
|
+
- Only read-only HTTP methods (GET, HEAD, OPTIONS) are allowed
|
|
117
|
+
- SSRF protection blocks private IPs, localhost, and reserved ranges
|
|
118
|
+
- Response bodies are truncated to 4,000 characters
|
|
119
|
+
- `file://`, `ftp://`, and other non-HTTP schemes are rejected
|
|
120
|
+
- URLs with embedded credentials are rejected
|
|
121
|
+
|
|
122
|
+
### `dominusnode_balance`
|
|
123
|
+
|
|
124
|
+
Check your DomiNode wallet balance. No input required.
|
|
125
|
+
|
|
126
|
+
Returns the balance in both USD and cents.
|
|
127
|
+
|
|
128
|
+
### `dominusnode_usage`
|
|
129
|
+
|
|
130
|
+
Check your DomiNode proxy usage statistics. No input required.
|
|
131
|
+
|
|
132
|
+
Returns total bandwidth used (GB), total cost, and request count.
|
|
133
|
+
|
|
134
|
+
### `dominusnode_proxy_config`
|
|
135
|
+
|
|
136
|
+
Get the DomiNode proxy configuration. No input required.
|
|
137
|
+
|
|
138
|
+
Returns proxy endpoints, supported countries for geo-targeting, blocked countries, rotation intervals, and available geo-targeting features (state, city, ASN).
|
|
139
|
+
|
|
140
|
+
## Async Usage
|
|
141
|
+
|
|
142
|
+
All tools support async execution for use with async LangChain agents:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
import asyncio
|
|
146
|
+
from dominusnode_langchain import DominusNodeToolkit
|
|
147
|
+
|
|
148
|
+
async def main():
|
|
149
|
+
toolkit = DominusNodeToolkit(api_key="dn_live_your_key")
|
|
150
|
+
tools = toolkit.get_tools()
|
|
151
|
+
|
|
152
|
+
balance_tool = next(t for t in tools if t.name == "dominusnode_balance")
|
|
153
|
+
fetch_tool = next(t for t in tools if t.name == "dominusnode_proxied_fetch")
|
|
154
|
+
|
|
155
|
+
# Async balance check
|
|
156
|
+
balance = await balance_tool.arun({})
|
|
157
|
+
print(balance)
|
|
158
|
+
|
|
159
|
+
# Async proxied fetch
|
|
160
|
+
result = await fetch_tool.arun({
|
|
161
|
+
"url": "https://httpbin.org/headers",
|
|
162
|
+
"country": "GB",
|
|
163
|
+
})
|
|
164
|
+
print(result)
|
|
165
|
+
|
|
166
|
+
toolkit.close()
|
|
167
|
+
|
|
168
|
+
asyncio.run(main())
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Explicit Credentials
|
|
172
|
+
|
|
173
|
+
If you prefer not to use environment variables:
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
from dominusnode_langchain import DominusNodeToolkit
|
|
177
|
+
|
|
178
|
+
toolkit = DominusNodeToolkit(
|
|
179
|
+
api_key="dn_live_abc123",
|
|
180
|
+
base_url="http://localhost:3000",
|
|
181
|
+
proxy_host="localhost",
|
|
182
|
+
http_proxy_port=8080,
|
|
183
|
+
socks5_proxy_port=1080,
|
|
184
|
+
)
|
|
185
|
+
tools = toolkit.get_tools()
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Running Tests
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
cd integrations/langchain
|
|
192
|
+
pip install -e ".[dev]"
|
|
193
|
+
pytest tests/ -v
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Pricing Reference
|
|
197
|
+
|
|
198
|
+
| Proxy Type | Cost to You | Sell Price | Margin |
|
|
199
|
+
|-----------|-------------|------------|--------|
|
|
200
|
+
| Datacenter | $0.012/GB | $3.00/GB | 99.6% |
|
|
201
|
+
| Residential | $4.00/GB | $5.00/GB | 20% |
|
|
202
|
+
|
|
203
|
+
## License
|
|
204
|
+
|
|
205
|
+
MIT
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Mock dominusnode SDK and langchain_core modules before any test imports."""
|
|
2
|
+
import sys
|
|
3
|
+
from typing import Any
|
|
4
|
+
from unittest.mock import MagicMock
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# ── Flexible mock types that accept any kwargs ──────────────────────────
|
|
10
|
+
|
|
11
|
+
class _FlexType:
|
|
12
|
+
"""Base that accepts any keyword arguments."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, **kwargs):
|
|
15
|
+
for k, v in kwargs.items():
|
|
16
|
+
setattr(self, k, v)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Wallet(_FlexType):
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class GeoTargeting(_FlexType):
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ProxyEndpointConfig(_FlexType):
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ProxyConfig(_FlexType):
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class UsageSummary(_FlexType):
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class UsagePagination(_FlexType):
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class UsagePeriod(_FlexType):
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class UsageResponse(_FlexType):
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ProxyUrlOptions(_FlexType):
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# Create mock dominusnode module hierarchy
|
|
56
|
+
dominusnode_mock = MagicMock()
|
|
57
|
+
dominusnode_types_mock = MagicMock()
|
|
58
|
+
|
|
59
|
+
# Wire up types
|
|
60
|
+
dominusnode_types_mock.Wallet = Wallet
|
|
61
|
+
dominusnode_types_mock.GeoTargeting = GeoTargeting
|
|
62
|
+
dominusnode_types_mock.ProxyConfig = ProxyConfig
|
|
63
|
+
dominusnode_types_mock.ProxyEndpointConfig = ProxyEndpointConfig
|
|
64
|
+
dominusnode_types_mock.UsageSummary = UsageSummary
|
|
65
|
+
dominusnode_types_mock.UsagePagination = UsagePagination
|
|
66
|
+
dominusnode_types_mock.UsagePeriod = UsagePeriod
|
|
67
|
+
dominusnode_types_mock.UsageResponse = UsageResponse
|
|
68
|
+
dominusnode_types_mock.ProxyUrlOptions = ProxyUrlOptions
|
|
69
|
+
|
|
70
|
+
# Wire DominusNodeClient and AsyncDominusNodeClient as MagicMock classes
|
|
71
|
+
dominusnode_mock.DominusNodeClient = MagicMock
|
|
72
|
+
dominusnode_mock.AsyncDominusNodeClient = MagicMock
|
|
73
|
+
dominusnode_mock.types = dominusnode_types_mock
|
|
74
|
+
|
|
75
|
+
sys.modules.setdefault("dominusnode", dominusnode_mock)
|
|
76
|
+
sys.modules.setdefault("dominusnode.types", dominusnode_types_mock)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# ── Mock langchain_core ─────────────────────────────────────────────────
|
|
80
|
+
|
|
81
|
+
lc_mock = MagicMock()
|
|
82
|
+
lc_tools_mock = MagicMock()
|
|
83
|
+
lc_callbacks_mock = MagicMock()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class BaseTool(BaseModel):
|
|
87
|
+
"""Mock langchain_core BaseTool using Pydantic (like real LangChain)."""
|
|
88
|
+
|
|
89
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
90
|
+
|
|
91
|
+
name: str = ""
|
|
92
|
+
description: str = ""
|
|
93
|
+
args_schema: Any = None
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
lc_tools_mock.BaseTool = BaseTool
|
|
97
|
+
lc_callbacks_mock.CallbackManagerForToolRun = MagicMock
|
|
98
|
+
lc_callbacks_mock.AsyncCallbackManagerForToolRun = MagicMock
|
|
99
|
+
|
|
100
|
+
lc_mock.tools = lc_tools_mock
|
|
101
|
+
lc_mock.callbacks = lc_callbacks_mock
|
|
102
|
+
|
|
103
|
+
sys.modules.setdefault("langchain_core", lc_mock)
|
|
104
|
+
sys.modules.setdefault("langchain_core.tools", lc_tools_mock)
|
|
105
|
+
sys.modules.setdefault("langchain_core.callbacks", lc_callbacks_mock)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""LangChain tools for DomiNode rotating proxy service.
|
|
2
|
+
|
|
3
|
+
Provides LangChain-compatible tools for making proxied HTTP requests,
|
|
4
|
+
checking wallet balance, viewing usage statistics, and querying proxy
|
|
5
|
+
configuration through the DomiNode platform.
|
|
6
|
+
|
|
7
|
+
Example::
|
|
8
|
+
|
|
9
|
+
from dominusnode_langchain import DominusNodeToolkit
|
|
10
|
+
|
|
11
|
+
toolkit = DominusNodeToolkit(api_key="dn_live_...", base_url="http://localhost:3000")
|
|
12
|
+
tools = toolkit.get_tools()
|
|
13
|
+
|
|
14
|
+
# Use with a LangChain agent
|
|
15
|
+
from langchain.agents import AgentExecutor, create_tool_calling_agent
|
|
16
|
+
agent = create_tool_calling_agent(llm, tools, prompt)
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from .tools import (
|
|
20
|
+
DominusNodeAgenticTransactionsTool,
|
|
21
|
+
DominusNodeAgenticWalletBalanceTool,
|
|
22
|
+
DominusNodeBalanceTool,
|
|
23
|
+
DominusNodeCreateAgenticWalletTool,
|
|
24
|
+
DominusNodeDeleteAgenticWalletTool,
|
|
25
|
+
DominusNodeFreezeAgenticWalletTool,
|
|
26
|
+
DominusNodeFundAgenticWalletTool,
|
|
27
|
+
DominusNodeListAgenticWalletsTool,
|
|
28
|
+
DominusNodeProxiedFetchTool,
|
|
29
|
+
DominusNodeProxyConfigTool,
|
|
30
|
+
DominusNodeTopupPaypalTool,
|
|
31
|
+
DominusNodeUnfreezeAgenticWalletTool,
|
|
32
|
+
DominusNodeUpdateWalletPolicyTool,
|
|
33
|
+
DominusNodeUsageTool,
|
|
34
|
+
DominusNodeX402InfoTool,
|
|
35
|
+
)
|
|
36
|
+
from .toolkit import DominusNodeToolkit
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"DominusNodeToolkit",
|
|
40
|
+
"DominusNodeProxiedFetchTool",
|
|
41
|
+
"DominusNodeBalanceTool",
|
|
42
|
+
"DominusNodeUsageTool",
|
|
43
|
+
"DominusNodeProxyConfigTool",
|
|
44
|
+
"DominusNodeTopupPaypalTool",
|
|
45
|
+
"DominusNodeX402InfoTool",
|
|
46
|
+
"DominusNodeCreateAgenticWalletTool",
|
|
47
|
+
"DominusNodeFundAgenticWalletTool",
|
|
48
|
+
"DominusNodeAgenticWalletBalanceTool",
|
|
49
|
+
"DominusNodeListAgenticWalletsTool",
|
|
50
|
+
"DominusNodeAgenticTransactionsTool",
|
|
51
|
+
"DominusNodeFreezeAgenticWalletTool",
|
|
52
|
+
"DominusNodeUnfreezeAgenticWalletTool",
|
|
53
|
+
"DominusNodeDeleteAgenticWalletTool",
|
|
54
|
+
"DominusNodeUpdateWalletPolicyTool",
|
|
55
|
+
]
|