dominusnode-langchain 1.2.2__tar.gz → 1.2.4__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.2.2 → dominusnode_langchain-1.2.4}/PKG-INFO +6 -6
- {dominusnode_langchain-1.2.2 → dominusnode_langchain-1.2.4}/README.md +5 -5
- {dominusnode_langchain-1.2.2 → dominusnode_langchain-1.2.4}/dominusnode_langchain/tools.py +61 -14
- {dominusnode_langchain-1.2.2 → dominusnode_langchain-1.2.4}/pyproject.toml +1 -1
- {dominusnode_langchain-1.2.2 → dominusnode_langchain-1.2.4}/.gitignore +0 -0
- {dominusnode_langchain-1.2.2 → dominusnode_langchain-1.2.4}/CHANGELOG.md +0 -0
- {dominusnode_langchain-1.2.2 → dominusnode_langchain-1.2.4}/LICENSE +0 -0
- {dominusnode_langchain-1.2.2 → dominusnode_langchain-1.2.4}/conftest.py +0 -0
- {dominusnode_langchain-1.2.2 → dominusnode_langchain-1.2.4}/dominusnode_langchain/__init__.py +0 -0
- {dominusnode_langchain-1.2.2 → dominusnode_langchain-1.2.4}/dominusnode_langchain/toolkit.py +0 -0
- {dominusnode_langchain-1.2.2 → dominusnode_langchain-1.2.4}/tests/__init__.py +0 -0
- {dominusnode_langchain-1.2.2 → dominusnode_langchain-1.2.4}/tests/test_tools.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dominusnode-langchain
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.4
|
|
4
4
|
Summary: LangChain tools for Dominus Node rotating proxy service
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -95,7 +95,7 @@ tools = toolkit.get_tools()
|
|
|
95
95
|
|
|
96
96
|
# Get tools by name
|
|
97
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 == "
|
|
98
|
+
balance_tool = next(t for t in tools if t.name == "dominusnode_check_balance")
|
|
99
99
|
|
|
100
100
|
# Check balance
|
|
101
101
|
print(balance_tool.run({}))
|
|
@@ -134,19 +134,19 @@ Makes HTTP requests through the Dominus Node rotating proxy network.
|
|
|
134
134
|
- `file://`, `ftp://`, and other non-HTTP schemes are rejected
|
|
135
135
|
- URLs with embedded credentials are rejected
|
|
136
136
|
|
|
137
|
-
### `
|
|
137
|
+
### `dominusnode_check_balance`
|
|
138
138
|
|
|
139
139
|
Check your Dominus Node wallet balance. No input required.
|
|
140
140
|
|
|
141
141
|
Returns the balance in both USD and cents.
|
|
142
142
|
|
|
143
|
-
### `
|
|
143
|
+
### `dominusnode_check_usage`
|
|
144
144
|
|
|
145
145
|
Check your Dominus Node proxy usage statistics. No input required.
|
|
146
146
|
|
|
147
147
|
Returns total bandwidth used (GB), total cost, and request count.
|
|
148
148
|
|
|
149
|
-
### `
|
|
149
|
+
### `dominusnode_get_proxy_config`
|
|
150
150
|
|
|
151
151
|
Get the Dominus Node proxy configuration. No input required.
|
|
152
152
|
|
|
@@ -164,7 +164,7 @@ async def main():
|
|
|
164
164
|
toolkit = DominusNodeToolkit(api_key="dn_live_your_key")
|
|
165
165
|
tools = toolkit.get_tools()
|
|
166
166
|
|
|
167
|
-
balance_tool = next(t for t in tools if t.name == "
|
|
167
|
+
balance_tool = next(t for t in tools if t.name == "dominusnode_check_balance")
|
|
168
168
|
fetch_tool = next(t for t in tools if t.name == "dominusnode_proxied_fetch")
|
|
169
169
|
|
|
170
170
|
# Async balance check
|
|
@@ -80,7 +80,7 @@ tools = toolkit.get_tools()
|
|
|
80
80
|
|
|
81
81
|
# Get tools by name
|
|
82
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 == "
|
|
83
|
+
balance_tool = next(t for t in tools if t.name == "dominusnode_check_balance")
|
|
84
84
|
|
|
85
85
|
# Check balance
|
|
86
86
|
print(balance_tool.run({}))
|
|
@@ -119,19 +119,19 @@ Makes HTTP requests through the Dominus Node rotating proxy network.
|
|
|
119
119
|
- `file://`, `ftp://`, and other non-HTTP schemes are rejected
|
|
120
120
|
- URLs with embedded credentials are rejected
|
|
121
121
|
|
|
122
|
-
### `
|
|
122
|
+
### `dominusnode_check_balance`
|
|
123
123
|
|
|
124
124
|
Check your Dominus Node wallet balance. No input required.
|
|
125
125
|
|
|
126
126
|
Returns the balance in both USD and cents.
|
|
127
127
|
|
|
128
|
-
### `
|
|
128
|
+
### `dominusnode_check_usage`
|
|
129
129
|
|
|
130
130
|
Check your Dominus Node proxy usage statistics. No input required.
|
|
131
131
|
|
|
132
132
|
Returns total bandwidth used (GB), total cost, and request count.
|
|
133
133
|
|
|
134
|
-
### `
|
|
134
|
+
### `dominusnode_get_proxy_config`
|
|
135
135
|
|
|
136
136
|
Get the Dominus Node proxy configuration. No input required.
|
|
137
137
|
|
|
@@ -149,7 +149,7 @@ async def main():
|
|
|
149
149
|
toolkit = DominusNodeToolkit(api_key="dn_live_your_key")
|
|
150
150
|
tools = toolkit.get_tools()
|
|
151
151
|
|
|
152
|
-
balance_tool = next(t for t in tools if t.name == "
|
|
152
|
+
balance_tool = next(t for t in tools if t.name == "dominusnode_check_balance")
|
|
153
153
|
fetch_tool = next(t for t in tools if t.name == "dominusnode_proxied_fetch")
|
|
154
154
|
|
|
155
155
|
# Async balance check
|
|
@@ -15,6 +15,7 @@ Security:
|
|
|
15
15
|
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
|
|
18
|
+
import hashlib
|
|
18
19
|
import ipaddress
|
|
19
20
|
import math
|
|
20
21
|
import os
|
|
@@ -63,6 +64,46 @@ def _sanitize_error(message: str) -> str:
|
|
|
63
64
|
return _CREDENTIAL_RE.sub("***", message)
|
|
64
65
|
|
|
65
66
|
|
|
67
|
+
def _count_leading_zero_bits(data: bytes) -> int:
|
|
68
|
+
"""Count leading zero bits in a byte array."""
|
|
69
|
+
count = 0
|
|
70
|
+
for byte in data:
|
|
71
|
+
if byte == 0:
|
|
72
|
+
count += 8
|
|
73
|
+
else:
|
|
74
|
+
mask = 0x80
|
|
75
|
+
while mask and not (byte & mask):
|
|
76
|
+
count += 1
|
|
77
|
+
mask >>= 1
|
|
78
|
+
break
|
|
79
|
+
return count
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _solve_pow(base_url: str) -> Optional[dict]:
|
|
83
|
+
"""Solve a Proof-of-Work challenge for CAPTCHA-free registration."""
|
|
84
|
+
try:
|
|
85
|
+
pow_url = f"{base_url.rstrip('/')}/api/auth/pow/challenge"
|
|
86
|
+
with httpx.Client(timeout=30.0, follow_redirects=False) as client:
|
|
87
|
+
resp = client.post(pow_url, headers={"Content-Type": "application/json"})
|
|
88
|
+
if resp.status_code >= 400:
|
|
89
|
+
return None
|
|
90
|
+
challenge = resp.json()
|
|
91
|
+
prefix = challenge.get("prefix", "")
|
|
92
|
+
difficulty = challenge.get("difficulty", 20)
|
|
93
|
+
challenge_id = challenge.get("challengeId", "")
|
|
94
|
+
if not prefix or not challenge_id:
|
|
95
|
+
return None
|
|
96
|
+
nonce = 0
|
|
97
|
+
while nonce < 100_000_000:
|
|
98
|
+
h = hashlib.sha256((prefix + str(nonce)).encode()).digest()
|
|
99
|
+
if _count_leading_zero_bits(h) >= difficulty:
|
|
100
|
+
return {"challengeId": challenge_id, "nonce": str(nonce)}
|
|
101
|
+
nonce += 1
|
|
102
|
+
return None
|
|
103
|
+
except Exception:
|
|
104
|
+
return None
|
|
105
|
+
|
|
106
|
+
|
|
66
107
|
# ──────────────────────────────────────────────────────────────────────
|
|
67
108
|
# Prototype pollution prevention
|
|
68
109
|
# ──────────────────────────────────────────────────────────────────────
|
|
@@ -439,7 +480,7 @@ class DominusNodeBalanceTool(BaseTool):
|
|
|
439
480
|
spend before making proxied requests.
|
|
440
481
|
"""
|
|
441
482
|
|
|
442
|
-
name: str = "
|
|
483
|
+
name: str = "dominusnode_check_balance"
|
|
443
484
|
description: str = (
|
|
444
485
|
"Check your Dominus Node wallet balance. Returns the current balance "
|
|
445
486
|
"in dollars and cents. No input required."
|
|
@@ -494,7 +535,7 @@ class DominusNodeUsageTool(BaseTool):
|
|
|
494
535
|
cost, and request count.
|
|
495
536
|
"""
|
|
496
537
|
|
|
497
|
-
name: str = "
|
|
538
|
+
name: str = "dominusnode_check_usage"
|
|
498
539
|
description: str = (
|
|
499
540
|
"Check your Dominus Node proxy usage statistics. Returns total bandwidth "
|
|
500
541
|
"used (in GB), total cost, and request count. No input required."
|
|
@@ -608,8 +649,6 @@ class TopupStripeInput(BaseModel):
|
|
|
608
649
|
"""Input schema for the Dominus Node Stripe top-up tool."""
|
|
609
650
|
|
|
610
651
|
amount_cents: int = Field(
|
|
611
|
-
ge=500,
|
|
612
|
-
le=100000,
|
|
613
652
|
description="Amount in cents to top up via Stripe (min 500 = $5, max 100000 = $1,000).",
|
|
614
653
|
)
|
|
615
654
|
|
|
@@ -664,8 +703,6 @@ class TopupCryptoInput(BaseModel):
|
|
|
664
703
|
"""Input schema for the Dominus Node crypto top-up tool."""
|
|
665
704
|
|
|
666
705
|
amount_usd: float = Field(
|
|
667
|
-
ge=5,
|
|
668
|
-
le=1000,
|
|
669
706
|
description="Amount in USD to top up with cryptocurrency (min 5, max 1000).",
|
|
670
707
|
)
|
|
671
708
|
currency: str = Field(
|
|
@@ -750,7 +787,7 @@ class DominusNodeProxyConfigTool(BaseTool):
|
|
|
750
787
|
and available geo-targeting features.
|
|
751
788
|
"""
|
|
752
789
|
|
|
753
|
-
name: str = "
|
|
790
|
+
name: str = "dominusnode_get_proxy_config"
|
|
754
791
|
description: str = (
|
|
755
792
|
"Get the Dominus Node proxy configuration including supported countries, "
|
|
756
793
|
"proxy endpoints, and geo-targeting capabilities. No input required."
|
|
@@ -2003,7 +2040,7 @@ def _validate_team_id(team_id: Any) -> Optional[str]:
|
|
|
2003
2040
|
class DominusNodeProxyStatusTool(BaseTool):
|
|
2004
2041
|
"""Get live proxy network status."""
|
|
2005
2042
|
|
|
2006
|
-
name: str = "
|
|
2043
|
+
name: str = "dominusnode_get_proxy_status"
|
|
2007
2044
|
description: str = (
|
|
2008
2045
|
"Get live proxy network status including latency, active session count, "
|
|
2009
2046
|
"and uptime. No input required."
|
|
@@ -2227,7 +2264,7 @@ class DominusNodeCheckPaymentTool(BaseTool):
|
|
|
2227
2264
|
class DominusNodeDailyUsageTool(BaseTool):
|
|
2228
2265
|
"""Get daily bandwidth breakdown."""
|
|
2229
2266
|
|
|
2230
|
-
name: str = "
|
|
2267
|
+
name: str = "dominusnode_get_daily_usage"
|
|
2231
2268
|
description: str = "Get daily bandwidth breakdown. Input: optional days (1-90, default 7)."
|
|
2232
2269
|
args_schema: Type[BaseModel] = GetDailyUsageInput
|
|
2233
2270
|
api_key: Optional[str] = None
|
|
@@ -2285,7 +2322,7 @@ class DominusNodeDailyUsageTool(BaseTool):
|
|
|
2285
2322
|
class DominusNodeTopHostsTool(BaseTool):
|
|
2286
2323
|
"""Get top target hosts by bandwidth."""
|
|
2287
2324
|
|
|
2288
|
-
name: str = "
|
|
2325
|
+
name: str = "dominusnode_get_top_hosts"
|
|
2289
2326
|
description: str = "Get top target hosts by bandwidth usage. Input: optional limit (1-50), days (1-365)."
|
|
2290
2327
|
args_schema: Type[BaseModel] = GetTopHostsInput
|
|
2291
2328
|
api_key: Optional[str] = None
|
|
@@ -2367,9 +2404,14 @@ class DominusNodeRegisterTool(BaseTool):
|
|
|
2367
2404
|
if not password or len(password) < 8 or len(password) > 128:
|
|
2368
2405
|
return "Error: Password must be between 8 and 128 characters."
|
|
2369
2406
|
try:
|
|
2370
|
-
|
|
2407
|
+
body: dict = {"email": email, "password": password}
|
|
2408
|
+
pow_result = _solve_pow(self.base_url)
|
|
2409
|
+
if pow_result:
|
|
2410
|
+
body["pow"] = pow_result
|
|
2411
|
+
data = _api_request_unauth_sync(self.base_url, "POST", "/api/auth/register", body, agent_secret=self.agent_secret)
|
|
2371
2412
|
user = data.get("user", {})
|
|
2372
|
-
|
|
2413
|
+
pow_msg = "Email auto-verified via Proof-of-Work." if pow_result else "Email auto-verified (MCP agent)"
|
|
2414
|
+
return f"Account Created\n Email: {user.get('email', email)}\n User ID: {user.get('id', '?')}\n {pow_msg}"
|
|
2373
2415
|
except Exception as exc:
|
|
2374
2416
|
return f"Error: {_sanitize_error(str(exc))}"
|
|
2375
2417
|
|
|
@@ -2381,9 +2423,14 @@ class DominusNodeRegisterTool(BaseTool):
|
|
|
2381
2423
|
if not password or len(password) < 8 or len(password) > 128:
|
|
2382
2424
|
return "Error: Password must be between 8 and 128 characters."
|
|
2383
2425
|
try:
|
|
2384
|
-
|
|
2426
|
+
body: dict = {"email": email, "password": password}
|
|
2427
|
+
pow_result = _solve_pow(self.base_url)
|
|
2428
|
+
if pow_result:
|
|
2429
|
+
body["pow"] = pow_result
|
|
2430
|
+
data = await _api_request_unauth_async(self.base_url, "POST", "/api/auth/register", body, agent_secret=self.agent_secret)
|
|
2385
2431
|
user = data.get("user", {})
|
|
2386
|
-
|
|
2432
|
+
pow_msg = "Email auto-verified via Proof-of-Work." if pow_result else "Email auto-verified (MCP agent)"
|
|
2433
|
+
return f"Account Created\n Email: {user.get('email', email)}\n User ID: {user.get('id', '?')}\n {pow_msg}"
|
|
2387
2434
|
except Exception as exc:
|
|
2388
2435
|
return f"Error: {_sanitize_error(str(exc))}"
|
|
2389
2436
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dominusnode_langchain-1.2.2 → dominusnode_langchain-1.2.4}/dominusnode_langchain/__init__.py
RENAMED
|
File without changes
|
{dominusnode_langchain-1.2.2 → dominusnode_langchain-1.2.4}/dominusnode_langchain/toolkit.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|