dominusnode-camel 1.1.0__tar.gz → 1.2.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.
Potentially problematic release.
This version of dominusnode-camel might be problematic. Click here for more details.
- {dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/PKG-INFO +2 -2
- {dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/README.md +1 -1
- {dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/dominusnode_camel/tools.py +881 -12
- {dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/dominusnode_camel.egg-info/PKG-INFO +2 -2
- {dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/pyproject.toml +1 -1
- {dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/tests/test_tools.py +32 -3
- {dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/LICENSE +0 -0
- {dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/dominusnode_camel/__init__.py +0 -0
- {dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/dominusnode_camel.egg-info/SOURCES.txt +0 -0
- {dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/dominusnode_camel.egg-info/dependency_links.txt +0 -0
- {dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/dominusnode_camel.egg-info/requires.txt +0 -0
- {dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/dominusnode_camel.egg-info/top_level.txt +0 -0
- {dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dominusnode-camel
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Dominus Node rotating proxy tools for CAMEL-AI agents
|
|
5
5
|
License: MIT
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -15,7 +15,7 @@ Dynamic: license-file
|
|
|
15
15
|
|
|
16
16
|
# dominusnode-camel
|
|
17
17
|
|
|
18
|
-
CAMEL-AI toolkit for the [Dominus Node](https://dominusnode.com) rotating proxy-as-a-service platform. Provides
|
|
18
|
+
CAMEL-AI toolkit for the [Dominus Node](https://dominusnode.com) rotating proxy-as-a-service platform. Provides 53 tools as CAMEL `FunctionTool` objects for proxy management, wallet operations, team administration, account management, API key management, plan management, and payment processing.
|
|
19
19
|
|
|
20
20
|
## Installation
|
|
21
21
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dominusnode-camel
|
|
2
2
|
|
|
3
|
-
CAMEL-AI toolkit for the [Dominus Node](https://dominusnode.com) rotating proxy-as-a-service platform. Provides
|
|
3
|
+
CAMEL-AI toolkit for the [Dominus Node](https://dominusnode.com) rotating proxy-as-a-service platform. Provides 53 tools as CAMEL `FunctionTool` objects for proxy management, wallet operations, team administration, account management, API key management, plan management, and payment processing.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
"""Dominus Node CAMEL-AI toolkit --
|
|
1
|
+
"""Dominus Node CAMEL-AI toolkit -- 53 proxy, wallet, team, and payment tools.
|
|
2
2
|
|
|
3
|
-
Provides a CAMEL-AI compatible toolkit class that exposes
|
|
3
|
+
Provides a CAMEL-AI compatible toolkit class that exposes 53 tools as
|
|
4
4
|
``FunctionTool`` objects for use with CAMEL agents.
|
|
5
5
|
|
|
6
6
|
Tools cover:
|
|
7
7
|
- Proxied HTTP fetching through rotating proxies
|
|
8
|
-
- Wallet balance and usage monitoring
|
|
9
|
-
- Proxy configuration and session listing
|
|
8
|
+
- Wallet balance, transactions, forecast, and usage monitoring
|
|
9
|
+
- Proxy configuration, status, and session listing
|
|
10
10
|
- Agentic wallet management (create, fund, freeze, unfreeze, delete)
|
|
11
|
-
- Team management (create, list, fund, keys, usage, update, role changes
|
|
12
|
-
|
|
11
|
+
- Team management (create, list, fund, keys, usage, update, role changes,
|
|
12
|
+
members, invites, delete)
|
|
13
|
+
- Account management (register, login, info, email verification, password)
|
|
14
|
+
- API key management (list, create, revoke)
|
|
15
|
+
- Plan management (get, list, change)
|
|
16
|
+
- PayPal, Stripe, and crypto top-up
|
|
13
17
|
- x402 micropayment info
|
|
14
18
|
|
|
15
19
|
Security:
|
|
@@ -495,6 +499,53 @@ def _validate_domains(domains: Any) -> Optional[str]:
|
|
|
495
499
|
return None
|
|
496
500
|
|
|
497
501
|
|
|
502
|
+
_EMAIL_RE = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$")
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
def _validate_email(value: Any, field_name: str = "email") -> Optional[str]:
|
|
506
|
+
"""Validate an email string, returning an error message or None."""
|
|
507
|
+
if not value or not isinstance(value, str):
|
|
508
|
+
return f"{field_name} is required and must be a string"
|
|
509
|
+
if len(value) > 254:
|
|
510
|
+
return f"{field_name} must be 254 characters or fewer"
|
|
511
|
+
if not _EMAIL_RE.match(value):
|
|
512
|
+
return f"{field_name} must be a valid email address"
|
|
513
|
+
return None
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
def _validate_password(value: Any, field_name: str = "password") -> Optional[str]:
|
|
517
|
+
"""Validate a password string, returning an error message or None."""
|
|
518
|
+
if not value or not isinstance(value, str):
|
|
519
|
+
return f"{field_name} is required and must be a string"
|
|
520
|
+
if len(value) < 8:
|
|
521
|
+
return f"{field_name} must be at least 8 characters"
|
|
522
|
+
if len(value) > 128:
|
|
523
|
+
return f"{field_name} must be 128 characters or fewer"
|
|
524
|
+
return None
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
def _validate_finite_int(
|
|
528
|
+
value: Any,
|
|
529
|
+
field_name: str,
|
|
530
|
+
min_value: int = 1,
|
|
531
|
+
max_value: int = 2_147_483_647,
|
|
532
|
+
) -> Optional[str]:
|
|
533
|
+
"""Validate integer with NaN/Infinity guards (Python: float('nan') etc.)."""
|
|
534
|
+
if isinstance(value, bool):
|
|
535
|
+
return f"{field_name} must be an integer"
|
|
536
|
+
if isinstance(value, float):
|
|
537
|
+
if not math.isfinite(value):
|
|
538
|
+
return f"{field_name} must be a finite number"
|
|
539
|
+
if value != int(value):
|
|
540
|
+
return f"{field_name} must be an integer"
|
|
541
|
+
value = int(value)
|
|
542
|
+
if not isinstance(value, int):
|
|
543
|
+
return f"{field_name} must be an integer"
|
|
544
|
+
if value < min_value or value > max_value:
|
|
545
|
+
return f"{field_name} must be between {min_value} and {max_value}"
|
|
546
|
+
return None
|
|
547
|
+
|
|
548
|
+
|
|
498
549
|
# ===========================================================================
|
|
499
550
|
# DominusNodeToolkit -- main toolkit class
|
|
500
551
|
# ===========================================================================
|
|
@@ -503,9 +554,10 @@ def _validate_domains(domains: Any) -> Optional[str]:
|
|
|
503
554
|
class DominusNodeToolkit:
|
|
504
555
|
"""CAMEL-AI toolkit providing Dominus Node rotating proxy tools.
|
|
505
556
|
|
|
506
|
-
Authenticates using a Dominus Node API key and exposes
|
|
507
|
-
``FunctionTool`` objects for proxy, wallet, team,
|
|
508
|
-
All tool methods return dicts suitable for JSON
|
|
557
|
+
Authenticates using a Dominus Node API key and exposes 53 tools as CAMEL
|
|
558
|
+
``FunctionTool`` objects for proxy, wallet, team, account, key, plan,
|
|
559
|
+
and payment management. All tool methods return dicts suitable for JSON
|
|
560
|
+
serialization.
|
|
509
561
|
|
|
510
562
|
Args:
|
|
511
563
|
api_key: Dominus Node API key (``dn_live_...`` or ``dn_test_...``).
|
|
@@ -596,7 +648,69 @@ class DominusNodeToolkit:
|
|
|
596
648
|
self._authenticate()
|
|
597
649
|
|
|
598
650
|
# ------------------------------------------------------------------
|
|
599
|
-
# API request helper
|
|
651
|
+
# Unauthenticated API request helper
|
|
652
|
+
# ------------------------------------------------------------------
|
|
653
|
+
|
|
654
|
+
def _unauthenticated_request(
|
|
655
|
+
self,
|
|
656
|
+
method: str,
|
|
657
|
+
path: str,
|
|
658
|
+
body: Optional[Dict[str, Any]] = None,
|
|
659
|
+
) -> Any:
|
|
660
|
+
"""Make an unauthenticated API request (for register, login, verify-email).
|
|
661
|
+
|
|
662
|
+
Args:
|
|
663
|
+
method: HTTP method (GET, POST).
|
|
664
|
+
path: API path (e.g., ``/api/auth/register``).
|
|
665
|
+
body: Optional JSON body.
|
|
666
|
+
|
|
667
|
+
Returns:
|
|
668
|
+
Parsed JSON response (with dangerous keys stripped).
|
|
669
|
+
|
|
670
|
+
Raises:
|
|
671
|
+
RuntimeError: On API errors or oversized responses.
|
|
672
|
+
"""
|
|
673
|
+
with httpx.Client(
|
|
674
|
+
timeout=self.timeout,
|
|
675
|
+
follow_redirects=False,
|
|
676
|
+
) as client:
|
|
677
|
+
headers: Dict[str, str] = {
|
|
678
|
+
"User-Agent": "dominusnode-camel/1.0.0",
|
|
679
|
+
"Content-Type": "application/json",
|
|
680
|
+
}
|
|
681
|
+
if self.agent_secret:
|
|
682
|
+
headers["X-DominusNode-Agent"] = "mcp"
|
|
683
|
+
headers["X-DominusNode-Agent-Secret"] = self.agent_secret
|
|
684
|
+
|
|
685
|
+
kwargs: Dict[str, Any] = {"headers": headers}
|
|
686
|
+
|
|
687
|
+
if body is not None and method.upper() not in ("GET", "HEAD", "OPTIONS"):
|
|
688
|
+
kwargs["json"] = body
|
|
689
|
+
|
|
690
|
+
resp = client.request(method, f"{self.base_url}{path}", **kwargs)
|
|
691
|
+
|
|
692
|
+
if len(resp.content) > MAX_RESPONSE_BYTES:
|
|
693
|
+
raise RuntimeError("Response body too large")
|
|
694
|
+
|
|
695
|
+
if resp.status_code >= 400:
|
|
696
|
+
try:
|
|
697
|
+
err_data = resp.json()
|
|
698
|
+
msg = err_data.get("error", resp.text)
|
|
699
|
+
except Exception:
|
|
700
|
+
msg = resp.text
|
|
701
|
+
msg = str(msg)[:500]
|
|
702
|
+
raise RuntimeError(
|
|
703
|
+
f"API error {resp.status_code}: {_sanitize_error(msg)}"
|
|
704
|
+
)
|
|
705
|
+
|
|
706
|
+
if resp.text:
|
|
707
|
+
data = resp.json()
|
|
708
|
+
_strip_dangerous_keys(data)
|
|
709
|
+
return data
|
|
710
|
+
return {}
|
|
711
|
+
|
|
712
|
+
# ------------------------------------------------------------------
|
|
713
|
+
# Authenticated API request helper
|
|
600
714
|
# ------------------------------------------------------------------
|
|
601
715
|
|
|
602
716
|
def _api_request(
|
|
@@ -1546,27 +1660,746 @@ class DominusNodeToolkit:
|
|
|
1546
1660
|
except Exception as e:
|
|
1547
1661
|
return {"error": _sanitize_error(str(e))}
|
|
1548
1662
|
|
|
1663
|
+
# ==================================================================
|
|
1664
|
+
# Tool 27: get_proxy_status
|
|
1665
|
+
# ==================================================================
|
|
1666
|
+
|
|
1667
|
+
def get_proxy_status(self) -> Dict[str, Any]:
|
|
1668
|
+
"""Get the current status of the proxy gateway.
|
|
1669
|
+
|
|
1670
|
+
Returns:
|
|
1671
|
+
Dict with proxy gateway status information including uptime,
|
|
1672
|
+
active connections, and health metrics.
|
|
1673
|
+
"""
|
|
1674
|
+
try:
|
|
1675
|
+
result = self._request_with_retry("GET", "/api/proxy/status")
|
|
1676
|
+
return result
|
|
1677
|
+
except Exception as e:
|
|
1678
|
+
return {"error": _sanitize_error(str(e))}
|
|
1679
|
+
|
|
1680
|
+
# ==================================================================
|
|
1681
|
+
# Tool 28: get_transactions
|
|
1682
|
+
# ==================================================================
|
|
1683
|
+
|
|
1684
|
+
def get_transactions(self, limit: int = 20) -> Dict[str, Any]:
|
|
1685
|
+
"""Get wallet transaction history.
|
|
1686
|
+
|
|
1687
|
+
Args:
|
|
1688
|
+
limit: Maximum number of transactions to return (1 to 100,
|
|
1689
|
+
default 20).
|
|
1690
|
+
|
|
1691
|
+
Returns:
|
|
1692
|
+
Dict with wallet transaction history.
|
|
1693
|
+
"""
|
|
1694
|
+
err = _validate_finite_int(limit, "limit", min_value=1, max_value=100)
|
|
1695
|
+
if err:
|
|
1696
|
+
return {"error": err}
|
|
1697
|
+
limit = int(limit)
|
|
1698
|
+
|
|
1699
|
+
qs = f"?limit={limit}" if limit != 20 else ""
|
|
1700
|
+
|
|
1701
|
+
try:
|
|
1702
|
+
result = self._request_with_retry("GET", f"/api/wallet/transactions{qs}")
|
|
1703
|
+
return result
|
|
1704
|
+
except Exception as e:
|
|
1705
|
+
return {"error": _sanitize_error(str(e))}
|
|
1706
|
+
|
|
1707
|
+
# ==================================================================
|
|
1708
|
+
# Tool 29: get_forecast
|
|
1709
|
+
# ==================================================================
|
|
1710
|
+
|
|
1711
|
+
def get_forecast(self) -> Dict[str, Any]:
|
|
1712
|
+
"""Get wallet balance forecast based on current usage patterns.
|
|
1713
|
+
|
|
1714
|
+
Returns:
|
|
1715
|
+
Dict with forecast data including estimated depletion date
|
|
1716
|
+
and projected daily spend.
|
|
1717
|
+
"""
|
|
1718
|
+
try:
|
|
1719
|
+
result = self._request_with_retry("GET", "/api/wallet/forecast")
|
|
1720
|
+
return result
|
|
1721
|
+
except Exception as e:
|
|
1722
|
+
return {"error": _sanitize_error(str(e))}
|
|
1723
|
+
|
|
1724
|
+
# ==================================================================
|
|
1725
|
+
# Tool 30: check_payment
|
|
1726
|
+
# ==================================================================
|
|
1727
|
+
|
|
1728
|
+
def check_payment(self, invoice_id: str) -> Dict[str, Any]:
|
|
1729
|
+
"""Check the status of a crypto payment invoice.
|
|
1730
|
+
|
|
1731
|
+
Args:
|
|
1732
|
+
invoice_id: The invoice ID returned from topup_crypto.
|
|
1733
|
+
|
|
1734
|
+
Returns:
|
|
1735
|
+
Dict with the payment status and details.
|
|
1736
|
+
"""
|
|
1737
|
+
if not invoice_id or not isinstance(invoice_id, str):
|
|
1738
|
+
return {"error": "invoice_id is required and must be a string"}
|
|
1739
|
+
if len(invoice_id) > 200:
|
|
1740
|
+
return {"error": "invoice_id must be 200 characters or fewer"}
|
|
1741
|
+
|
|
1742
|
+
try:
|
|
1743
|
+
result = self._request_with_retry(
|
|
1744
|
+
"GET",
|
|
1745
|
+
f"/api/wallet/topup/crypto/{quote(invoice_id, safe='')}/status",
|
|
1746
|
+
)
|
|
1747
|
+
return result
|
|
1748
|
+
except Exception as e:
|
|
1749
|
+
return {"error": _sanitize_error(str(e))}
|
|
1750
|
+
|
|
1751
|
+
# ==================================================================
|
|
1752
|
+
# Tool 31: get_daily_usage
|
|
1753
|
+
# ==================================================================
|
|
1754
|
+
|
|
1755
|
+
def get_daily_usage(self, days: int = 30) -> Dict[str, Any]:
|
|
1756
|
+
"""Get daily usage breakdown for recent days.
|
|
1757
|
+
|
|
1758
|
+
Args:
|
|
1759
|
+
days: Number of days to retrieve (1 to 90, default 30).
|
|
1760
|
+
|
|
1761
|
+
Returns:
|
|
1762
|
+
Dict with per-day usage statistics.
|
|
1763
|
+
"""
|
|
1764
|
+
err = _validate_finite_int(days, "days", min_value=1, max_value=90)
|
|
1765
|
+
if err:
|
|
1766
|
+
return {"error": err}
|
|
1767
|
+
days = int(days)
|
|
1768
|
+
|
|
1769
|
+
try:
|
|
1770
|
+
result = self._request_with_retry(
|
|
1771
|
+
"GET", f"/api/usage/daily?days={days}"
|
|
1772
|
+
)
|
|
1773
|
+
return result
|
|
1774
|
+
except Exception as e:
|
|
1775
|
+
return {"error": _sanitize_error(str(e))}
|
|
1776
|
+
|
|
1777
|
+
# ==================================================================
|
|
1778
|
+
# Tool 32: get_top_hosts
|
|
1779
|
+
# ==================================================================
|
|
1780
|
+
|
|
1781
|
+
def get_top_hosts(self, limit: int = 10) -> Dict[str, Any]:
|
|
1782
|
+
"""Get top destination hosts by bandwidth usage.
|
|
1783
|
+
|
|
1784
|
+
Args:
|
|
1785
|
+
limit: Maximum number of hosts to return (1 to 50, default 10).
|
|
1786
|
+
|
|
1787
|
+
Returns:
|
|
1788
|
+
Dict with top hosts and their bandwidth consumption.
|
|
1789
|
+
"""
|
|
1790
|
+
err = _validate_finite_int(limit, "limit", min_value=1, max_value=50)
|
|
1791
|
+
if err:
|
|
1792
|
+
return {"error": err}
|
|
1793
|
+
limit = int(limit)
|
|
1794
|
+
|
|
1795
|
+
try:
|
|
1796
|
+
result = self._request_with_retry(
|
|
1797
|
+
"GET", f"/api/usage/top-hosts?limit={limit}"
|
|
1798
|
+
)
|
|
1799
|
+
return result
|
|
1800
|
+
except Exception as e:
|
|
1801
|
+
return {"error": _sanitize_error(str(e))}
|
|
1802
|
+
|
|
1803
|
+
# ==================================================================
|
|
1804
|
+
# Tool 33: register_account (unauthenticated)
|
|
1805
|
+
# ==================================================================
|
|
1806
|
+
|
|
1807
|
+
def register_account(self, email: str, password: str) -> Dict[str, Any]:
|
|
1808
|
+
"""Register a new Dominus Node account.
|
|
1809
|
+
|
|
1810
|
+
This is an unauthenticated operation. After registration, verify
|
|
1811
|
+
the email address to activate the account.
|
|
1812
|
+
|
|
1813
|
+
Args:
|
|
1814
|
+
email: Email address for the new account (max 254 characters).
|
|
1815
|
+
password: Password (8 to 128 characters).
|
|
1816
|
+
|
|
1817
|
+
Returns:
|
|
1818
|
+
Dict with the registered account details.
|
|
1819
|
+
"""
|
|
1820
|
+
err = _validate_email(email, "email")
|
|
1821
|
+
if err:
|
|
1822
|
+
return {"error": err}
|
|
1823
|
+
|
|
1824
|
+
err = _validate_password(password, "password")
|
|
1825
|
+
if err:
|
|
1826
|
+
return {"error": err}
|
|
1827
|
+
|
|
1828
|
+
try:
|
|
1829
|
+
result = self._unauthenticated_request(
|
|
1830
|
+
"POST",
|
|
1831
|
+
"/api/auth/register",
|
|
1832
|
+
{"email": email, "password": password},
|
|
1833
|
+
)
|
|
1834
|
+
return result
|
|
1835
|
+
except Exception as e:
|
|
1836
|
+
return {"error": _sanitize_error(str(e))}
|
|
1837
|
+
|
|
1838
|
+
# ==================================================================
|
|
1839
|
+
# Tool 34: login_account (unauthenticated)
|
|
1840
|
+
# ==================================================================
|
|
1841
|
+
|
|
1842
|
+
def login_account(self, email: str, password: str) -> Dict[str, Any]:
|
|
1843
|
+
"""Log in to an existing Dominus Node account.
|
|
1844
|
+
|
|
1845
|
+
This is an unauthenticated operation. Returns JWT tokens on success.
|
|
1846
|
+
|
|
1847
|
+
Args:
|
|
1848
|
+
email: Account email address.
|
|
1849
|
+
password: Account password.
|
|
1850
|
+
|
|
1851
|
+
Returns:
|
|
1852
|
+
Dict with ``accessToken`` and ``refreshToken`` on success,
|
|
1853
|
+
or ``mfaRequired`` if MFA is enabled.
|
|
1854
|
+
"""
|
|
1855
|
+
err = _validate_email(email, "email")
|
|
1856
|
+
if err:
|
|
1857
|
+
return {"error": err}
|
|
1858
|
+
|
|
1859
|
+
err = _validate_password(password, "password")
|
|
1860
|
+
if err:
|
|
1861
|
+
return {"error": err}
|
|
1862
|
+
|
|
1863
|
+
try:
|
|
1864
|
+
result = self._unauthenticated_request(
|
|
1865
|
+
"POST",
|
|
1866
|
+
"/api/auth/login",
|
|
1867
|
+
{"email": email, "password": password},
|
|
1868
|
+
)
|
|
1869
|
+
# Surface MFA requirement if present
|
|
1870
|
+
if isinstance(result, dict) and result.get("mfaRequired"):
|
|
1871
|
+
return {"mfaRequired": True, "message": "MFA verification required"}
|
|
1872
|
+
return result
|
|
1873
|
+
except Exception as e:
|
|
1874
|
+
return {"error": _sanitize_error(str(e))}
|
|
1875
|
+
|
|
1876
|
+
# ==================================================================
|
|
1877
|
+
# Tool 35: get_account_info
|
|
1878
|
+
# ==================================================================
|
|
1879
|
+
|
|
1880
|
+
def get_account_info(self) -> Dict[str, Any]:
|
|
1881
|
+
"""Get current account information.
|
|
1882
|
+
|
|
1883
|
+
Returns:
|
|
1884
|
+
Dict with account details including email, plan, and
|
|
1885
|
+
verification status.
|
|
1886
|
+
"""
|
|
1887
|
+
try:
|
|
1888
|
+
result = self._request_with_retry("GET", "/api/auth/me")
|
|
1889
|
+
return result
|
|
1890
|
+
except Exception as e:
|
|
1891
|
+
return {"error": _sanitize_error(str(e))}
|
|
1892
|
+
|
|
1893
|
+
# ==================================================================
|
|
1894
|
+
# Tool 36: verify_email (unauthenticated)
|
|
1895
|
+
# ==================================================================
|
|
1896
|
+
|
|
1897
|
+
def verify_email(self, token: str) -> Dict[str, Any]:
|
|
1898
|
+
"""Verify an email address using the verification token.
|
|
1899
|
+
|
|
1900
|
+
This is an unauthenticated operation. The token is sent to the
|
|
1901
|
+
registered email address.
|
|
1902
|
+
|
|
1903
|
+
Args:
|
|
1904
|
+
token: Email verification token from the verification email.
|
|
1905
|
+
|
|
1906
|
+
Returns:
|
|
1907
|
+
Dict confirming email verification.
|
|
1908
|
+
"""
|
|
1909
|
+
if not token or not isinstance(token, str):
|
|
1910
|
+
return {"error": "token is required and must be a string"}
|
|
1911
|
+
if len(token) > 500:
|
|
1912
|
+
return {"error": "token must be 500 characters or fewer"}
|
|
1913
|
+
|
|
1914
|
+
try:
|
|
1915
|
+
result = self._unauthenticated_request(
|
|
1916
|
+
"POST",
|
|
1917
|
+
"/api/auth/verify-email",
|
|
1918
|
+
{"token": token},
|
|
1919
|
+
)
|
|
1920
|
+
return result
|
|
1921
|
+
except Exception as e:
|
|
1922
|
+
return {"error": _sanitize_error(str(e))}
|
|
1923
|
+
|
|
1924
|
+
# ==================================================================
|
|
1925
|
+
# Tool 37: resend_verification
|
|
1926
|
+
# ==================================================================
|
|
1927
|
+
|
|
1928
|
+
def resend_verification(self) -> Dict[str, Any]:
|
|
1929
|
+
"""Resend the email verification message.
|
|
1930
|
+
|
|
1931
|
+
Returns:
|
|
1932
|
+
Dict confirming the verification email was resent.
|
|
1933
|
+
"""
|
|
1934
|
+
try:
|
|
1935
|
+
result = self._request_with_retry(
|
|
1936
|
+
"POST", "/api/auth/resend-verification"
|
|
1937
|
+
)
|
|
1938
|
+
return result
|
|
1939
|
+
except Exception as e:
|
|
1940
|
+
return {"error": _sanitize_error(str(e))}
|
|
1941
|
+
|
|
1942
|
+
# ==================================================================
|
|
1943
|
+
# Tool 38: update_password
|
|
1944
|
+
# ==================================================================
|
|
1945
|
+
|
|
1946
|
+
def update_password(
|
|
1947
|
+
self, current_password: str, new_password: str
|
|
1948
|
+
) -> Dict[str, Any]:
|
|
1949
|
+
"""Update the account password.
|
|
1950
|
+
|
|
1951
|
+
Args:
|
|
1952
|
+
current_password: The current account password.
|
|
1953
|
+
new_password: The new password (8 to 128 characters).
|
|
1954
|
+
|
|
1955
|
+
Returns:
|
|
1956
|
+
Dict confirming the password was updated.
|
|
1957
|
+
"""
|
|
1958
|
+
err = _validate_password(current_password, "current_password")
|
|
1959
|
+
if err:
|
|
1960
|
+
return {"error": err}
|
|
1961
|
+
|
|
1962
|
+
err = _validate_password(new_password, "new_password")
|
|
1963
|
+
if err:
|
|
1964
|
+
return {"error": err}
|
|
1965
|
+
|
|
1966
|
+
try:
|
|
1967
|
+
result = self._request_with_retry(
|
|
1968
|
+
"POST",
|
|
1969
|
+
"/api/auth/change-password",
|
|
1970
|
+
{
|
|
1971
|
+
"currentPassword": current_password,
|
|
1972
|
+
"newPassword": new_password,
|
|
1973
|
+
},
|
|
1974
|
+
)
|
|
1975
|
+
return result
|
|
1976
|
+
except Exception as e:
|
|
1977
|
+
return {"error": _sanitize_error(str(e))}
|
|
1978
|
+
|
|
1979
|
+
# ==================================================================
|
|
1980
|
+
# Tool 39: list_keys
|
|
1981
|
+
# ==================================================================
|
|
1982
|
+
|
|
1983
|
+
def list_keys(self) -> Dict[str, Any]:
|
|
1984
|
+
"""List all API keys for the current account.
|
|
1985
|
+
|
|
1986
|
+
Returns:
|
|
1987
|
+
Dict with a list of API keys and their metadata (labels,
|
|
1988
|
+
creation dates, last used).
|
|
1989
|
+
"""
|
|
1990
|
+
try:
|
|
1991
|
+
result = self._request_with_retry("GET", "/api/keys")
|
|
1992
|
+
return result
|
|
1993
|
+
except Exception as e:
|
|
1994
|
+
return {"error": _sanitize_error(str(e))}
|
|
1995
|
+
|
|
1996
|
+
# ==================================================================
|
|
1997
|
+
# Tool 40: create_key
|
|
1998
|
+
# ==================================================================
|
|
1999
|
+
|
|
2000
|
+
def create_key(self, label: str) -> Dict[str, Any]:
|
|
2001
|
+
"""Create a new API key for the current account.
|
|
2002
|
+
|
|
2003
|
+
Args:
|
|
2004
|
+
label: Human-readable label for the key (max 100 characters).
|
|
2005
|
+
|
|
2006
|
+
Returns:
|
|
2007
|
+
Dict with the created API key (shown once -- save it).
|
|
2008
|
+
"""
|
|
2009
|
+
err = _validate_label(label, "label")
|
|
2010
|
+
if err:
|
|
2011
|
+
return {"error": err}
|
|
2012
|
+
|
|
2013
|
+
try:
|
|
2014
|
+
result = self._request_with_retry(
|
|
2015
|
+
"POST", "/api/keys", {"label": label}
|
|
2016
|
+
)
|
|
2017
|
+
return result
|
|
2018
|
+
except Exception as e:
|
|
2019
|
+
return {"error": _sanitize_error(str(e))}
|
|
2020
|
+
|
|
2021
|
+
# ==================================================================
|
|
2022
|
+
# Tool 41: revoke_key
|
|
2023
|
+
# ==================================================================
|
|
2024
|
+
|
|
2025
|
+
def revoke_key(self, key_id: str) -> Dict[str, Any]:
|
|
2026
|
+
"""Revoke (delete) an API key.
|
|
2027
|
+
|
|
2028
|
+
Args:
|
|
2029
|
+
key_id: UUID of the API key to revoke.
|
|
2030
|
+
|
|
2031
|
+
Returns:
|
|
2032
|
+
Dict confirming the key has been revoked.
|
|
2033
|
+
"""
|
|
2034
|
+
err = _validate_uuid(key_id, "key_id")
|
|
2035
|
+
if err:
|
|
2036
|
+
return {"error": err}
|
|
2037
|
+
|
|
2038
|
+
try:
|
|
2039
|
+
result = self._request_with_retry(
|
|
2040
|
+
"DELETE", f"/api/keys/{quote(key_id, safe='')}"
|
|
2041
|
+
)
|
|
2042
|
+
return result
|
|
2043
|
+
except Exception as e:
|
|
2044
|
+
return {"error": _sanitize_error(str(e))}
|
|
2045
|
+
|
|
2046
|
+
# ==================================================================
|
|
2047
|
+
# Tool 42: get_plan
|
|
2048
|
+
# ==================================================================
|
|
2049
|
+
|
|
2050
|
+
def get_plan(self) -> Dict[str, Any]:
|
|
2051
|
+
"""Get the current user's active plan.
|
|
2052
|
+
|
|
2053
|
+
Returns:
|
|
2054
|
+
Dict with the user's current plan details including tier,
|
|
2055
|
+
limits, and pricing.
|
|
2056
|
+
"""
|
|
2057
|
+
try:
|
|
2058
|
+
result = self._request_with_retry("GET", "/api/plans/user/plan")
|
|
2059
|
+
return result
|
|
2060
|
+
except Exception as e:
|
|
2061
|
+
return {"error": _sanitize_error(str(e))}
|
|
2062
|
+
|
|
2063
|
+
# ==================================================================
|
|
2064
|
+
# Tool 43: list_plans
|
|
2065
|
+
# ==================================================================
|
|
2066
|
+
|
|
2067
|
+
def list_plans(self) -> Dict[str, Any]:
|
|
2068
|
+
"""List all available subscription plans.
|
|
2069
|
+
|
|
2070
|
+
Returns:
|
|
2071
|
+
Dict with a list of available plans and their features.
|
|
2072
|
+
"""
|
|
2073
|
+
try:
|
|
2074
|
+
result = self._request_with_retry("GET", "/api/plans")
|
|
2075
|
+
return result
|
|
2076
|
+
except Exception as e:
|
|
2077
|
+
return {"error": _sanitize_error(str(e))}
|
|
2078
|
+
|
|
2079
|
+
# ==================================================================
|
|
2080
|
+
# Tool 44: change_plan
|
|
2081
|
+
# ==================================================================
|
|
2082
|
+
|
|
2083
|
+
def change_plan(self, plan_id: str) -> Dict[str, Any]:
|
|
2084
|
+
"""Change the user's subscription plan.
|
|
2085
|
+
|
|
2086
|
+
Args:
|
|
2087
|
+
plan_id: UUID of the plan to switch to.
|
|
2088
|
+
|
|
2089
|
+
Returns:
|
|
2090
|
+
Dict with the updated plan details.
|
|
2091
|
+
"""
|
|
2092
|
+
err = _validate_uuid(plan_id, "plan_id")
|
|
2093
|
+
if err:
|
|
2094
|
+
return {"error": err}
|
|
2095
|
+
|
|
2096
|
+
try:
|
|
2097
|
+
result = self._request_with_retry(
|
|
2098
|
+
"PUT",
|
|
2099
|
+
"/api/plans/user/plan",
|
|
2100
|
+
{"planId": plan_id},
|
|
2101
|
+
)
|
|
2102
|
+
return result
|
|
2103
|
+
except Exception as e:
|
|
2104
|
+
return {"error": _sanitize_error(str(e))}
|
|
2105
|
+
|
|
2106
|
+
# ==================================================================
|
|
2107
|
+
# Tool 45: team_delete
|
|
2108
|
+
# ==================================================================
|
|
2109
|
+
|
|
2110
|
+
def team_delete(self, team_id: str) -> Dict[str, Any]:
|
|
2111
|
+
"""Delete a team.
|
|
2112
|
+
|
|
2113
|
+
Args:
|
|
2114
|
+
team_id: UUID of the team to delete.
|
|
2115
|
+
|
|
2116
|
+
Returns:
|
|
2117
|
+
Dict confirming the team has been deleted.
|
|
2118
|
+
"""
|
|
2119
|
+
err = _validate_uuid(team_id, "team_id")
|
|
2120
|
+
if err:
|
|
2121
|
+
return {"error": err}
|
|
2122
|
+
|
|
2123
|
+
try:
|
|
2124
|
+
result = self._request_with_retry(
|
|
2125
|
+
"DELETE", f"/api/teams/{quote(team_id, safe='')}"
|
|
2126
|
+
)
|
|
2127
|
+
return result
|
|
2128
|
+
except Exception as e:
|
|
2129
|
+
return {"error": _sanitize_error(str(e))}
|
|
2130
|
+
|
|
2131
|
+
# ==================================================================
|
|
2132
|
+
# Tool 46: team_revoke_key
|
|
2133
|
+
# ==================================================================
|
|
2134
|
+
|
|
2135
|
+
def team_revoke_key(self, team_id: str, key_id: str) -> Dict[str, Any]:
|
|
2136
|
+
"""Revoke (delete) an API key from a team.
|
|
2137
|
+
|
|
2138
|
+
Args:
|
|
2139
|
+
team_id: UUID of the team.
|
|
2140
|
+
key_id: UUID of the API key to revoke.
|
|
2141
|
+
|
|
2142
|
+
Returns:
|
|
2143
|
+
Dict confirming the team API key has been revoked.
|
|
2144
|
+
"""
|
|
2145
|
+
err = _validate_uuid(team_id, "team_id")
|
|
2146
|
+
if err:
|
|
2147
|
+
return {"error": err}
|
|
2148
|
+
|
|
2149
|
+
err = _validate_uuid(key_id, "key_id")
|
|
2150
|
+
if err:
|
|
2151
|
+
return {"error": err}
|
|
2152
|
+
|
|
2153
|
+
try:
|
|
2154
|
+
result = self._request_with_retry(
|
|
2155
|
+
"DELETE",
|
|
2156
|
+
f"/api/teams/{quote(team_id, safe='')}/keys/{quote(key_id, safe='')}",
|
|
2157
|
+
)
|
|
2158
|
+
return result
|
|
2159
|
+
except Exception as e:
|
|
2160
|
+
return {"error": _sanitize_error(str(e))}
|
|
2161
|
+
|
|
2162
|
+
# ==================================================================
|
|
2163
|
+
# Tool 47: team_list_keys
|
|
2164
|
+
# ==================================================================
|
|
2165
|
+
|
|
2166
|
+
def team_list_keys(self, team_id: str) -> Dict[str, Any]:
|
|
2167
|
+
"""List all API keys for a team.
|
|
2168
|
+
|
|
2169
|
+
Args:
|
|
2170
|
+
team_id: UUID of the team.
|
|
2171
|
+
|
|
2172
|
+
Returns:
|
|
2173
|
+
Dict with a list of the team's API keys and their metadata.
|
|
2174
|
+
"""
|
|
2175
|
+
err = _validate_uuid(team_id, "team_id")
|
|
2176
|
+
if err:
|
|
2177
|
+
return {"error": err}
|
|
2178
|
+
|
|
2179
|
+
try:
|
|
2180
|
+
result = self._request_with_retry(
|
|
2181
|
+
"GET", f"/api/teams/{quote(team_id, safe='')}/keys"
|
|
2182
|
+
)
|
|
2183
|
+
return result
|
|
2184
|
+
except Exception as e:
|
|
2185
|
+
return {"error": _sanitize_error(str(e))}
|
|
2186
|
+
|
|
2187
|
+
# ==================================================================
|
|
2188
|
+
# Tool 48: team_list_members
|
|
2189
|
+
# ==================================================================
|
|
2190
|
+
|
|
2191
|
+
def team_list_members(self, team_id: str) -> Dict[str, Any]:
|
|
2192
|
+
"""List all members of a team.
|
|
2193
|
+
|
|
2194
|
+
Args:
|
|
2195
|
+
team_id: UUID of the team.
|
|
2196
|
+
|
|
2197
|
+
Returns:
|
|
2198
|
+
Dict with a list of team members and their roles.
|
|
2199
|
+
"""
|
|
2200
|
+
err = _validate_uuid(team_id, "team_id")
|
|
2201
|
+
if err:
|
|
2202
|
+
return {"error": err}
|
|
2203
|
+
|
|
2204
|
+
try:
|
|
2205
|
+
result = self._request_with_retry(
|
|
2206
|
+
"GET", f"/api/teams/{quote(team_id, safe='')}/members"
|
|
2207
|
+
)
|
|
2208
|
+
return result
|
|
2209
|
+
except Exception as e:
|
|
2210
|
+
return {"error": _sanitize_error(str(e))}
|
|
2211
|
+
|
|
2212
|
+
# ==================================================================
|
|
2213
|
+
# Tool 49: team_add_member
|
|
2214
|
+
# ==================================================================
|
|
2215
|
+
|
|
2216
|
+
def team_add_member(
|
|
2217
|
+
self, team_id: str, user_id: str, role: str = "member"
|
|
2218
|
+
) -> Dict[str, Any]:
|
|
2219
|
+
"""Add a member to a team.
|
|
2220
|
+
|
|
2221
|
+
Args:
|
|
2222
|
+
team_id: UUID of the team.
|
|
2223
|
+
user_id: UUID of the user to add.
|
|
2224
|
+
role: Role to assign -- ``member`` or ``admin`` (default ``member``).
|
|
2225
|
+
|
|
2226
|
+
Returns:
|
|
2227
|
+
Dict confirming the member was added.
|
|
2228
|
+
"""
|
|
2229
|
+
err = _validate_uuid(team_id, "team_id")
|
|
2230
|
+
if err:
|
|
2231
|
+
return {"error": err}
|
|
2232
|
+
|
|
2233
|
+
err = _validate_uuid(user_id, "user_id")
|
|
2234
|
+
if err:
|
|
2235
|
+
return {"error": err}
|
|
2236
|
+
|
|
2237
|
+
if not role or not isinstance(role, str):
|
|
2238
|
+
return {"error": "role is required and must be a string"}
|
|
2239
|
+
if role not in ("member", "admin"):
|
|
2240
|
+
return {"error": "role must be 'member' or 'admin'"}
|
|
2241
|
+
|
|
2242
|
+
try:
|
|
2243
|
+
result = self._request_with_retry(
|
|
2244
|
+
"POST",
|
|
2245
|
+
f"/api/teams/{quote(team_id, safe='')}/members",
|
|
2246
|
+
{"userId": user_id, "role": role},
|
|
2247
|
+
)
|
|
2248
|
+
return result
|
|
2249
|
+
except Exception as e:
|
|
2250
|
+
return {"error": _sanitize_error(str(e))}
|
|
2251
|
+
|
|
2252
|
+
# ==================================================================
|
|
2253
|
+
# Tool 50: team_remove_member
|
|
2254
|
+
# ==================================================================
|
|
2255
|
+
|
|
2256
|
+
def team_remove_member(self, team_id: str, user_id: str) -> Dict[str, Any]:
|
|
2257
|
+
"""Remove a member from a team.
|
|
2258
|
+
|
|
2259
|
+
Args:
|
|
2260
|
+
team_id: UUID of the team.
|
|
2261
|
+
user_id: UUID of the user to remove.
|
|
2262
|
+
|
|
2263
|
+
Returns:
|
|
2264
|
+
Dict confirming the member was removed.
|
|
2265
|
+
"""
|
|
2266
|
+
err = _validate_uuid(team_id, "team_id")
|
|
2267
|
+
if err:
|
|
2268
|
+
return {"error": err}
|
|
2269
|
+
|
|
2270
|
+
err = _validate_uuid(user_id, "user_id")
|
|
2271
|
+
if err:
|
|
2272
|
+
return {"error": err}
|
|
2273
|
+
|
|
2274
|
+
try:
|
|
2275
|
+
result = self._request_with_retry(
|
|
2276
|
+
"DELETE",
|
|
2277
|
+
f"/api/teams/{quote(team_id, safe='')}/members/{quote(user_id, safe='')}",
|
|
2278
|
+
)
|
|
2279
|
+
return result
|
|
2280
|
+
except Exception as e:
|
|
2281
|
+
return {"error": _sanitize_error(str(e))}
|
|
2282
|
+
|
|
2283
|
+
# ==================================================================
|
|
2284
|
+
# Tool 51: team_invite_member
|
|
2285
|
+
# ==================================================================
|
|
2286
|
+
|
|
2287
|
+
def team_invite_member(
|
|
2288
|
+
self, team_id: str, email: str, role: str = "member"
|
|
2289
|
+
) -> Dict[str, Any]:
|
|
2290
|
+
"""Invite a user to a team by email.
|
|
2291
|
+
|
|
2292
|
+
Args:
|
|
2293
|
+
team_id: UUID of the team.
|
|
2294
|
+
email: Email address of the user to invite.
|
|
2295
|
+
role: Role to assign on acceptance -- ``member`` or ``admin``
|
|
2296
|
+
(default ``member``).
|
|
2297
|
+
|
|
2298
|
+
Returns:
|
|
2299
|
+
Dict with the invite details.
|
|
2300
|
+
"""
|
|
2301
|
+
err = _validate_uuid(team_id, "team_id")
|
|
2302
|
+
if err:
|
|
2303
|
+
return {"error": err}
|
|
2304
|
+
|
|
2305
|
+
err = _validate_email(email, "email")
|
|
2306
|
+
if err:
|
|
2307
|
+
return {"error": err}
|
|
2308
|
+
|
|
2309
|
+
if not role or not isinstance(role, str):
|
|
2310
|
+
return {"error": "role is required and must be a string"}
|
|
2311
|
+
if role not in ("member", "admin"):
|
|
2312
|
+
return {"error": "role must be 'member' or 'admin'"}
|
|
2313
|
+
|
|
2314
|
+
try:
|
|
2315
|
+
result = self._request_with_retry(
|
|
2316
|
+
"POST",
|
|
2317
|
+
f"/api/teams/{quote(team_id, safe='')}/invites",
|
|
2318
|
+
{"email": email, "role": role},
|
|
2319
|
+
)
|
|
2320
|
+
return result
|
|
2321
|
+
except Exception as e:
|
|
2322
|
+
return {"error": _sanitize_error(str(e))}
|
|
2323
|
+
|
|
2324
|
+
# ==================================================================
|
|
2325
|
+
# Tool 52: team_list_invites
|
|
2326
|
+
# ==================================================================
|
|
2327
|
+
|
|
2328
|
+
def team_list_invites(self, team_id: str) -> Dict[str, Any]:
|
|
2329
|
+
"""List pending invites for a team.
|
|
2330
|
+
|
|
2331
|
+
Args:
|
|
2332
|
+
team_id: UUID of the team.
|
|
2333
|
+
|
|
2334
|
+
Returns:
|
|
2335
|
+
Dict with a list of pending team invites.
|
|
2336
|
+
"""
|
|
2337
|
+
err = _validate_uuid(team_id, "team_id")
|
|
2338
|
+
if err:
|
|
2339
|
+
return {"error": err}
|
|
2340
|
+
|
|
2341
|
+
try:
|
|
2342
|
+
result = self._request_with_retry(
|
|
2343
|
+
"GET", f"/api/teams/{quote(team_id, safe='')}/invites"
|
|
2344
|
+
)
|
|
2345
|
+
return result
|
|
2346
|
+
except Exception as e:
|
|
2347
|
+
return {"error": _sanitize_error(str(e))}
|
|
2348
|
+
|
|
2349
|
+
# ==================================================================
|
|
2350
|
+
# Tool 53: team_cancel_invite
|
|
2351
|
+
# ==================================================================
|
|
2352
|
+
|
|
2353
|
+
def team_cancel_invite(self, team_id: str, invite_id: str) -> Dict[str, Any]:
|
|
2354
|
+
"""Cancel a pending team invite.
|
|
2355
|
+
|
|
2356
|
+
Args:
|
|
2357
|
+
team_id: UUID of the team.
|
|
2358
|
+
invite_id: UUID of the invite to cancel.
|
|
2359
|
+
|
|
2360
|
+
Returns:
|
|
2361
|
+
Dict confirming the invite has been cancelled.
|
|
2362
|
+
"""
|
|
2363
|
+
err = _validate_uuid(team_id, "team_id")
|
|
2364
|
+
if err:
|
|
2365
|
+
return {"error": err}
|
|
2366
|
+
|
|
2367
|
+
err = _validate_uuid(invite_id, "invite_id")
|
|
2368
|
+
if err:
|
|
2369
|
+
return {"error": err}
|
|
2370
|
+
|
|
2371
|
+
try:
|
|
2372
|
+
result = self._request_with_retry(
|
|
2373
|
+
"DELETE",
|
|
2374
|
+
f"/api/teams/{quote(team_id, safe='')}/invites/{quote(invite_id, safe='')}",
|
|
2375
|
+
)
|
|
2376
|
+
return result
|
|
2377
|
+
except Exception as e:
|
|
2378
|
+
return {"error": _sanitize_error(str(e))}
|
|
2379
|
+
|
|
1549
2380
|
# ==================================================================
|
|
1550
2381
|
# get_tools -- return CAMEL FunctionTool objects
|
|
1551
2382
|
# ==================================================================
|
|
1552
2383
|
|
|
1553
2384
|
def get_tools(self) -> list:
|
|
1554
|
-
"""Return CAMEL FunctionTool objects for all
|
|
2385
|
+
"""Return CAMEL FunctionTool objects for all 53 Dominus Node operations.
|
|
1555
2386
|
|
|
1556
2387
|
Each method is wrapped in a ``camel.toolkits.FunctionTool`` so that
|
|
1557
2388
|
CAMEL agents can discover and invoke them automatically.
|
|
1558
2389
|
|
|
1559
2390
|
Returns:
|
|
1560
|
-
A list of
|
|
2391
|
+
A list of 53 ``FunctionTool`` instances.
|
|
1561
2392
|
"""
|
|
1562
2393
|
from camel.toolkits import FunctionTool
|
|
1563
2394
|
|
|
1564
2395
|
return [
|
|
2396
|
+
# Proxy tools (1-5)
|
|
1565
2397
|
FunctionTool(self.proxied_fetch),
|
|
1566
2398
|
FunctionTool(self.check_balance),
|
|
1567
2399
|
FunctionTool(self.check_usage),
|
|
1568
2400
|
FunctionTool(self.get_proxy_config),
|
|
1569
2401
|
FunctionTool(self.list_sessions),
|
|
2402
|
+
# Agentic wallet tools (6-13)
|
|
1570
2403
|
FunctionTool(self.create_agentic_wallet),
|
|
1571
2404
|
FunctionTool(self.fund_agentic_wallet),
|
|
1572
2405
|
FunctionTool(self.agentic_wallet_balance),
|
|
@@ -1575,6 +2408,7 @@ class DominusNodeToolkit:
|
|
|
1575
2408
|
FunctionTool(self.freeze_agentic_wallet),
|
|
1576
2409
|
FunctionTool(self.unfreeze_agentic_wallet),
|
|
1577
2410
|
FunctionTool(self.delete_agentic_wallet),
|
|
2411
|
+
# Team tools (14-21)
|
|
1578
2412
|
FunctionTool(self.create_team),
|
|
1579
2413
|
FunctionTool(self.list_teams),
|
|
1580
2414
|
FunctionTool(self.team_details),
|
|
@@ -1583,9 +2417,44 @@ class DominusNodeToolkit:
|
|
|
1583
2417
|
FunctionTool(self.team_usage),
|
|
1584
2418
|
FunctionTool(self.update_team),
|
|
1585
2419
|
FunctionTool(self.update_team_member_role),
|
|
2420
|
+
# Payment tools (22-26)
|
|
1586
2421
|
FunctionTool(self.x402_info),
|
|
1587
2422
|
FunctionTool(self.topup_paypal),
|
|
1588
2423
|
FunctionTool(self.topup_stripe),
|
|
1589
2424
|
FunctionTool(self.topup_crypto),
|
|
1590
2425
|
FunctionTool(self.update_wallet_policy),
|
|
2426
|
+
# Proxy status (27)
|
|
2427
|
+
FunctionTool(self.get_proxy_status),
|
|
2428
|
+
# Wallet extras (28-30)
|
|
2429
|
+
FunctionTool(self.get_transactions),
|
|
2430
|
+
FunctionTool(self.get_forecast),
|
|
2431
|
+
FunctionTool(self.check_payment),
|
|
2432
|
+
# Usage extras (31-32)
|
|
2433
|
+
FunctionTool(self.get_daily_usage),
|
|
2434
|
+
FunctionTool(self.get_top_hosts),
|
|
2435
|
+
# Account management (33-38)
|
|
2436
|
+
FunctionTool(self.register_account),
|
|
2437
|
+
FunctionTool(self.login_account),
|
|
2438
|
+
FunctionTool(self.get_account_info),
|
|
2439
|
+
FunctionTool(self.verify_email),
|
|
2440
|
+
FunctionTool(self.resend_verification),
|
|
2441
|
+
FunctionTool(self.update_password),
|
|
2442
|
+
# API key management (39-41)
|
|
2443
|
+
FunctionTool(self.list_keys),
|
|
2444
|
+
FunctionTool(self.create_key),
|
|
2445
|
+
FunctionTool(self.revoke_key),
|
|
2446
|
+
# Plan management (42-44)
|
|
2447
|
+
FunctionTool(self.get_plan),
|
|
2448
|
+
FunctionTool(self.list_plans),
|
|
2449
|
+
FunctionTool(self.change_plan),
|
|
2450
|
+
# Extended team management (45-53)
|
|
2451
|
+
FunctionTool(self.team_delete),
|
|
2452
|
+
FunctionTool(self.team_revoke_key),
|
|
2453
|
+
FunctionTool(self.team_list_keys),
|
|
2454
|
+
FunctionTool(self.team_list_members),
|
|
2455
|
+
FunctionTool(self.team_add_member),
|
|
2456
|
+
FunctionTool(self.team_remove_member),
|
|
2457
|
+
FunctionTool(self.team_invite_member),
|
|
2458
|
+
FunctionTool(self.team_list_invites),
|
|
2459
|
+
FunctionTool(self.team_cancel_invite),
|
|
1591
2460
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dominusnode-camel
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Dominus Node rotating proxy tools for CAMEL-AI agents
|
|
5
5
|
License: MIT
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -15,7 +15,7 @@ Dynamic: license-file
|
|
|
15
15
|
|
|
16
16
|
# dominusnode-camel
|
|
17
17
|
|
|
18
|
-
CAMEL-AI toolkit for the [Dominus Node](https://dominusnode.com) rotating proxy-as-a-service platform. Provides
|
|
18
|
+
CAMEL-AI toolkit for the [Dominus Node](https://dominusnode.com) rotating proxy-as-a-service platform. Provides 53 tools as CAMEL `FunctionTool` objects for proxy management, wallet operations, team administration, account management, API key management, plan management, and payment processing.
|
|
19
19
|
|
|
20
20
|
## Installation
|
|
21
21
|
|
|
@@ -979,8 +979,8 @@ class TestToolMethods:
|
|
|
979
979
|
class TestGetTools:
|
|
980
980
|
"""Test the get_tools method returns correct FunctionTool objects."""
|
|
981
981
|
|
|
982
|
-
def
|
|
983
|
-
"""get_tools should return
|
|
982
|
+
def test_get_tools_returns_53_tools(self):
|
|
983
|
+
"""get_tools should return 53 FunctionTool objects."""
|
|
984
984
|
toolkit = DominusNodeToolkit(api_key="dn_test_key123")
|
|
985
985
|
|
|
986
986
|
# Mock FunctionTool since camel-ai may not be installed in test env
|
|
@@ -996,8 +996,9 @@ class TestGetTools:
|
|
|
996
996
|
with patch("camel.toolkits.FunctionTool", side_effect=mock_function_tool):
|
|
997
997
|
tools = toolkit.get_tools()
|
|
998
998
|
|
|
999
|
-
assert len(tools) ==
|
|
999
|
+
assert len(tools) == 53
|
|
1000
1000
|
tool_names = [t.name for t in tools]
|
|
1001
|
+
# Original 26 tools
|
|
1001
1002
|
assert "proxied_fetch" in tool_names
|
|
1002
1003
|
assert "check_balance" in tool_names
|
|
1003
1004
|
assert "check_usage" in tool_names
|
|
@@ -1024,6 +1025,34 @@ class TestGetTools:
|
|
|
1024
1025
|
assert "topup_stripe" in tool_names
|
|
1025
1026
|
assert "topup_crypto" in tool_names
|
|
1026
1027
|
assert "update_wallet_policy" in tool_names
|
|
1028
|
+
# New 27 tools
|
|
1029
|
+
assert "get_proxy_status" in tool_names
|
|
1030
|
+
assert "get_transactions" in tool_names
|
|
1031
|
+
assert "get_forecast" in tool_names
|
|
1032
|
+
assert "check_payment" in tool_names
|
|
1033
|
+
assert "get_daily_usage" in tool_names
|
|
1034
|
+
assert "get_top_hosts" in tool_names
|
|
1035
|
+
assert "register_account" in tool_names
|
|
1036
|
+
assert "login_account" in tool_names
|
|
1037
|
+
assert "get_account_info" in tool_names
|
|
1038
|
+
assert "verify_email" in tool_names
|
|
1039
|
+
assert "resend_verification" in tool_names
|
|
1040
|
+
assert "update_password" in tool_names
|
|
1041
|
+
assert "list_keys" in tool_names
|
|
1042
|
+
assert "create_key" in tool_names
|
|
1043
|
+
assert "revoke_key" in tool_names
|
|
1044
|
+
assert "get_plan" in tool_names
|
|
1045
|
+
assert "list_plans" in tool_names
|
|
1046
|
+
assert "change_plan" in tool_names
|
|
1047
|
+
assert "team_delete" in tool_names
|
|
1048
|
+
assert "team_revoke_key" in tool_names
|
|
1049
|
+
assert "team_list_keys" in tool_names
|
|
1050
|
+
assert "team_list_members" in tool_names
|
|
1051
|
+
assert "team_add_member" in tool_names
|
|
1052
|
+
assert "team_remove_member" in tool_names
|
|
1053
|
+
assert "team_invite_member" in tool_names
|
|
1054
|
+
assert "team_list_invites" in tool_names
|
|
1055
|
+
assert "team_cancel_invite" in tool_names
|
|
1027
1056
|
|
|
1028
1057
|
|
|
1029
1058
|
# ===========================================================================
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/dominusnode_camel.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{dominusnode_camel-1.1.0 → dominusnode_camel-1.2.0}/dominusnode_camel.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|