agentic-yp 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
agentic_yp/__init__.py ADDED
@@ -0,0 +1,9 @@
1
+ from .client import (
2
+ AgenticYPClient,
3
+ AgentNode,
4
+ AgenticYPError,
5
+ AgentNotFoundError,
6
+ AgenticYPAPIError
7
+ )
8
+
9
+ __version__ = "1.0.0"
agentic_yp/client.py ADDED
@@ -0,0 +1,161 @@
1
+ import time
2
+ import logging
3
+ from dataclasses import dataclass, field
4
+ from typing import List, Optional
5
+ from importlib.metadata import version, PackageNotFoundError
6
+
7
+ import requests
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+ # ── Custom exceptions ──────────────────────────────────────────────────────────
12
+
13
+ class AgenticYPError(Exception):
14
+ """Base exception for all SDK errors."""
15
+
16
+ class AgentNotFoundError(AgenticYPError):
17
+ """No agent matched the given filters."""
18
+
19
+ class AgenticYPAPIError(AgenticYPError):
20
+ """The API returned an unexpected response."""
21
+ def __init__(self, status_code: int, message: str):
22
+ self.status_code = status_code
23
+ super().__init__(f"API error {status_code}: {message}")
24
+
25
+ # ── Typed agent node ───────────────────────────────────────────────────────────
26
+
27
+ @dataclass
28
+ class AgentNode:
29
+ domain: str
30
+ trust_score: int
31
+ status: str
32
+ tags: List[str] = field(default_factory=list)
33
+ raw: dict = field(default_factory=dict, repr=False)
34
+
35
+ @classmethod
36
+ def from_dict(cls, data: dict) -> "AgentNode":
37
+ return cls(
38
+ domain=data.get("domain", ""),
39
+ trust_score=data.get("trust_score", 0),
40
+ status=data.get("status", "unknown"),
41
+ tags=[str(t).lower() for t in data.get("tags", [])],
42
+ raw=data,
43
+ )
44
+
45
+ def execute(self, prompt: str, **kwargs) -> dict:
46
+ """Route a prompt directly to this agent's endpoint."""
47
+ url = f"https://{self.domain}/run"
48
+ resp = requests.post(url, json={"prompt": prompt, **kwargs}, timeout=30)
49
+ resp.raise_for_status()
50
+ return resp.json()
51
+
52
+ # ── Main client ────────────────────────────────────────────────────────────────
53
+
54
+ try:
55
+ _SDK_VERSION = version("agentic-yp")
56
+ except PackageNotFoundError:
57
+ _SDK_VERSION = "dev"
58
+
59
+ class AgenticYPClient:
60
+ """
61
+ Official Python SDK for Agentic Yellow Pages.
62
+ Discover, filter, and route to trusted A2A endpoints programmatically.
63
+ """
64
+
65
+ DEFAULT_MIN_TRUST = 70
66
+ _cache: Optional[List[dict]] = None
67
+ _cache_ts: float = 0
68
+ CACHE_TTL = 30 # seconds
69
+
70
+ def __init__(
71
+ self,
72
+ base_url: str = "https://agentic-yellow-pages.onrender.com",
73
+ timeout: int = 10,
74
+ cache_ttl: int = 30,
75
+ ):
76
+ self.base_url = base_url.rstrip("/")
77
+ self.timeout = timeout
78
+ self.CACHE_TTL = cache_ttl
79
+ self.session = requests.Session()
80
+ self.session.headers.update({
81
+ "User-Agent": f"AgenticYP-Python-SDK/{_SDK_VERSION}"
82
+ })
83
+
84
+ def _fetch_all(self, force_refresh: bool = False) -> List[dict]:
85
+ """Fetches the global index, with TTL caching."""
86
+ now = time.monotonic()
87
+ if not force_refresh and self._cache and (now - self._cache_ts) < self.CACHE_TTL:
88
+ logger.debug("Returning cached agent list (%d agents)", len(self._cache))
89
+ return self._cache
90
+
91
+ try:
92
+ res = self.session.get(f"{self.base_url}/agents", timeout=self.timeout)
93
+ res.raise_for_status()
94
+ except requests.Timeout:
95
+ raise AgenticYPError(f"Request timed out after {self.timeout}s")
96
+ except requests.HTTPError as e:
97
+ raise AgenticYPAPIError(e.response.status_code, str(e))
98
+ except requests.RequestException as e:
99
+ raise AgenticYPError(f"Network error: {e}")
100
+
101
+ try:
102
+ data = res.json()
103
+ agents = data.get("agents", []) if isinstance(data, dict) else data
104
+ except ValueError:
105
+ raise AgenticYPAPIError(res.status_code, "Response was not valid JSON")
106
+
107
+ self._cache = agents
108
+ self._cache_ts = now
109
+ logger.debug("Fetched %d agents from API", len(agents))
110
+ return agents
111
+
112
+ def discover(
113
+ self,
114
+ skill: Optional[str] = None,
115
+ min_trust_score: int = DEFAULT_MIN_TRUST,
116
+ require_online: bool = True,
117
+ require_a2a_verified: bool = False,
118
+ ) -> List[AgentNode]:
119
+ """
120
+ Find nodes matching your requirements.
121
+
122
+ :param skill: Tag/capability to filter on (e.g. 'search', 'mcp-server').
123
+ :param min_trust_score: Minimum Oracle trust score (0-100). Default: 70.
124
+ :param require_online: Exclude offline nodes.
125
+ :param require_a2a_verified: Only return deeply verified A2A nodes.
126
+ :returns: List of AgentNode, sorted by trust score descending.
127
+ """
128
+ nodes = self._fetch_all()
129
+ results = []
130
+
131
+ for raw in nodes:
132
+ node = AgentNode.from_dict(raw)
133
+
134
+ if require_online and node.status == "offline":
135
+ continue
136
+ if require_a2a_verified and node.status != "a2a_verified":
137
+ continue
138
+ if node.trust_score < min_trust_score:
139
+ continue
140
+ if skill and skill.lower() not in node.tags:
141
+ continue
142
+
143
+ results.append(node)
144
+
145
+ return sorted(results, key=lambda n: n.trust_score, reverse=True)
146
+
147
+ def get_top_node(
148
+ self,
149
+ skill: str,
150
+ min_trust_score: int = DEFAULT_MIN_TRUST,
151
+ ) -> AgentNode:
152
+ """
153
+ Returns the single highest-rated node for a skill.
154
+ Raises AgentNotFoundError if nothing matches.
155
+ """
156
+ nodes = self.discover(skill=skill, min_trust_score=min_trust_score)
157
+ if not nodes:
158
+ raise AgentNotFoundError(
159
+ f"No online agent found for skill='{skill}' with trust >= {min_trust_score}"
160
+ )
161
+ return nodes[0]
@@ -0,0 +1,33 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentic-yp
3
+ Version: 1.0.0
4
+ Summary: Official SDK for the Agentic Yellow Pages A2A routing network.
5
+ Author-email: Agentic YP <admin@agenticyellowpage.com>
6
+ Project-URL: Homepage, https://agenticyellowpage.com
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: requests>=2.25.0
13
+
14
+ # Agentic Yellow Pages SDK 📒🤖
15
+
16
+ The official SDK for the [Agentic Yellow Pages](https://agenticyellowpage.com) — the discovery and trust routing layer for the machine-to-machine (M2M) economy.
17
+
18
+ Stop hardcoding agent endpoints. Use this SDK to dynamically discover, filter, and route data to A2A endpoints based on their cryptographic **Trust Score**, live health metrics, and capabilities.
19
+
20
+ ## Usage (Python)
21
+
22
+ ```python
23
+ from agentic_yp import AgenticYPClient
24
+
25
+ yp = AgenticYPClient()
26
+
27
+ # Automatically discover the safest, highest-rated web scraper
28
+ scraper_node = yp.get_top_node(skill="web-crawler", min_trust_score=90)
29
+
30
+ print(f"Routing to {scraper_node.domain} (Score: {scraper_node.trust_score})")
31
+
32
+ # Execute a payload directly to the node
33
+ response = scraper_node.execute(prompt="Scrape the latest AI news")
@@ -0,0 +1,6 @@
1
+ agentic_yp/__init__.py,sha256=Fa3DKFtBQThv6PNuPTAdetM-s0LSZiSdM5NVKGMfRAk,160
2
+ agentic_yp/client.py,sha256=VN_xw8qwgQzFh1jjEq5NA4D371o1ZqGpL-pgnTml51c,6071
3
+ agentic_yp-1.0.0.dist-info/METADATA,sha256=wBpMJppevqPt4A7vPbC_aA1W3RsZSrPn1yruxQVzHUw,1325
4
+ agentic_yp-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
5
+ agentic_yp-1.0.0.dist-info/top_level.txt,sha256=eRPrj6E2iC5W3cjB1sA1CGb0R5zrqeUkUhSKyWgIGj0,11
6
+ agentic_yp-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ agentic_yp