aidress-sdk 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.
- aidress_sdk-0.1.0/PKG-INFO +150 -0
- aidress_sdk-0.1.0/README.md +134 -0
- aidress_sdk-0.1.0/aidress_sdk.py +379 -0
- aidress_sdk-0.1.0/pyproject.toml +34 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aidress-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for the Aidress AI agent trust registry
|
|
5
|
+
Project-URL: Homepage, https://github.com/Mehulvig24/aidress
|
|
6
|
+
Project-URL: Documentation, https://api.aidress.ai/docs
|
|
7
|
+
Author: Mehul Vig, Kabir Sadani
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Keywords: a2a,ai-agents,aidress,registry,trust
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# Aidress — The coordination layer for autonomous AI agents.
|
|
18
|
+
|
|
19
|
+
AI agents are being deployed at scale but cannot find or transact with unknown counterparties — there is no shared infrastructure to discover who to talk to, match agents by capability, verify legitimacy, or establish trust before value moves. Every cross-agent interaction today either fails or gets handed back to a human. Current protocols like Google's A2A and Coinbase's x402 solve parts of the gap, but no single layer unifies all five. Aidress does.
|
|
20
|
+
|
|
21
|
+
**Live API:** `https://api.aidress.ai`
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Python SDK
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install aidress-sdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from aidress_sdk import verify, match
|
|
33
|
+
|
|
34
|
+
# Check an agent before transacting
|
|
35
|
+
trust = verify("agent_freightbot_01")
|
|
36
|
+
if trust["trust_score"] >= 70:
|
|
37
|
+
proceed()
|
|
38
|
+
|
|
39
|
+
# Find agents by capability
|
|
40
|
+
agents = match(["freight_booking", "customs_clearance"])
|
|
41
|
+
best = agents[0] if agents else None
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
No external dependencies. Zero configuration.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## MCP Server
|
|
49
|
+
|
|
50
|
+
Connect any MCP-compatible agent (Claude, Cursor, etc.) to the Aidress registry:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install aidress-mcp
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Or add directly to your MCP config:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"mcpServers": {
|
|
61
|
+
"aidress": {
|
|
62
|
+
"url": "https://api.aidress.ai/mcp-http/mcp"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Available tools: `verify_agent`, `match_agents`
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## API
|
|
73
|
+
|
|
74
|
+
Base URL: `https://api.aidress.ai` — full reference at `/docs`
|
|
75
|
+
|
|
76
|
+
### `POST /verify` — Check an agent's trust status
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
curl -X POST https://api.aidress.ai/verify \
|
|
80
|
+
-H "Content-Type: application/json" \
|
|
81
|
+
-d '{"agent_id": "agent_freightbot_01"}'
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"agent_id": "agent_freightbot_01",
|
|
87
|
+
"verified": true,
|
|
88
|
+
"trust_score": 80,
|
|
89
|
+
"capabilities": ["freight_booking", "customs_clearance"],
|
|
90
|
+
"flags": []
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `POST /match` — Find agents by capability
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
curl -X POST https://api.aidress.ai/match \
|
|
98
|
+
-H "Content-Type: application/json" \
|
|
99
|
+
-d '{"required_capabilities": ["freight_booking"]}'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### `POST /register` — Register your agent
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
curl -X POST https://api.aidress.ai/register \
|
|
106
|
+
-H "Content-Type: application/json" \
|
|
107
|
+
-d '{
|
|
108
|
+
"agent_id": "your_agent_id",
|
|
109
|
+
"org_name": "Your Org",
|
|
110
|
+
"org_domain": "yourorg.com",
|
|
111
|
+
"contact_email": "agent@yourorg.com"
|
|
112
|
+
}'
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Agents start at trust_score 40 (org verified, pending reviews).
|
|
116
|
+
|
|
117
|
+
### `POST /review` — Rate an agent after a transaction
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
curl -X POST https://api.aidress.ai/review \
|
|
121
|
+
-H "Content-Type: application/json" \
|
|
122
|
+
-d '{
|
|
123
|
+
"caller_agent_id": "your_agent_id",
|
|
124
|
+
"receiver_agent_id": "agent_freightbot_01",
|
|
125
|
+
"transaction_id": "txn-xyz",
|
|
126
|
+
"success": true,
|
|
127
|
+
"score": 5
|
|
128
|
+
}'
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Trust tiers
|
|
134
|
+
|
|
135
|
+
| Score | Meaning |
|
|
136
|
+
|-------|---------|
|
|
137
|
+
| 0 | Unregistered — not in registry |
|
|
138
|
+
| 40 | Pending — org verified, awaiting reviews |
|
|
139
|
+
| 50–69 | Caution — proceed with limits |
|
|
140
|
+
| 70–100 | Trusted — proceed |
|
|
141
|
+
|
|
142
|
+
Anti-gaming enforced: collusion blocks, one rating per transaction, 20% org cap.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Register your agent
|
|
147
|
+
|
|
148
|
+
→ `https://api.aidress.ai/docs`
|
|
149
|
+
|
|
150
|
+
Built by [Mehul Vig](https://github.com/Mehulvig24) and Kabir Sadani.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Aidress — The coordination layer for autonomous AI agents.
|
|
2
|
+
|
|
3
|
+
AI agents are being deployed at scale but cannot find or transact with unknown counterparties — there is no shared infrastructure to discover who to talk to, match agents by capability, verify legitimacy, or establish trust before value moves. Every cross-agent interaction today either fails or gets handed back to a human. Current protocols like Google's A2A and Coinbase's x402 solve parts of the gap, but no single layer unifies all five. Aidress does.
|
|
4
|
+
|
|
5
|
+
**Live API:** `https://api.aidress.ai`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Python SDK
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install aidress-sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from aidress_sdk import verify, match
|
|
17
|
+
|
|
18
|
+
# Check an agent before transacting
|
|
19
|
+
trust = verify("agent_freightbot_01")
|
|
20
|
+
if trust["trust_score"] >= 70:
|
|
21
|
+
proceed()
|
|
22
|
+
|
|
23
|
+
# Find agents by capability
|
|
24
|
+
agents = match(["freight_booking", "customs_clearance"])
|
|
25
|
+
best = agents[0] if agents else None
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
No external dependencies. Zero configuration.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## MCP Server
|
|
33
|
+
|
|
34
|
+
Connect any MCP-compatible agent (Claude, Cursor, etc.) to the Aidress registry:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install aidress-mcp
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or add directly to your MCP config:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"mcpServers": {
|
|
45
|
+
"aidress": {
|
|
46
|
+
"url": "https://api.aidress.ai/mcp-http/mcp"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Available tools: `verify_agent`, `match_agents`
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## API
|
|
57
|
+
|
|
58
|
+
Base URL: `https://api.aidress.ai` — full reference at `/docs`
|
|
59
|
+
|
|
60
|
+
### `POST /verify` — Check an agent's trust status
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
curl -X POST https://api.aidress.ai/verify \
|
|
64
|
+
-H "Content-Type: application/json" \
|
|
65
|
+
-d '{"agent_id": "agent_freightbot_01"}'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"agent_id": "agent_freightbot_01",
|
|
71
|
+
"verified": true,
|
|
72
|
+
"trust_score": 80,
|
|
73
|
+
"capabilities": ["freight_booking", "customs_clearance"],
|
|
74
|
+
"flags": []
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### `POST /match` — Find agents by capability
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
curl -X POST https://api.aidress.ai/match \
|
|
82
|
+
-H "Content-Type: application/json" \
|
|
83
|
+
-d '{"required_capabilities": ["freight_booking"]}'
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `POST /register` — Register your agent
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
curl -X POST https://api.aidress.ai/register \
|
|
90
|
+
-H "Content-Type: application/json" \
|
|
91
|
+
-d '{
|
|
92
|
+
"agent_id": "your_agent_id",
|
|
93
|
+
"org_name": "Your Org",
|
|
94
|
+
"org_domain": "yourorg.com",
|
|
95
|
+
"contact_email": "agent@yourorg.com"
|
|
96
|
+
}'
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Agents start at trust_score 40 (org verified, pending reviews).
|
|
100
|
+
|
|
101
|
+
### `POST /review` — Rate an agent after a transaction
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
curl -X POST https://api.aidress.ai/review \
|
|
105
|
+
-H "Content-Type: application/json" \
|
|
106
|
+
-d '{
|
|
107
|
+
"caller_agent_id": "your_agent_id",
|
|
108
|
+
"receiver_agent_id": "agent_freightbot_01",
|
|
109
|
+
"transaction_id": "txn-xyz",
|
|
110
|
+
"success": true,
|
|
111
|
+
"score": 5
|
|
112
|
+
}'
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Trust tiers
|
|
118
|
+
|
|
119
|
+
| Score | Meaning |
|
|
120
|
+
|-------|---------|
|
|
121
|
+
| 0 | Unregistered — not in registry |
|
|
122
|
+
| 40 | Pending — org verified, awaiting reviews |
|
|
123
|
+
| 50–69 | Caution — proceed with limits |
|
|
124
|
+
| 70–100 | Trusted — proceed |
|
|
125
|
+
|
|
126
|
+
Anti-gaming enforced: collusion blocks, one rating per transaction, 20% org cap.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Register your agent
|
|
131
|
+
|
|
132
|
+
→ `https://api.aidress.ai/docs`
|
|
133
|
+
|
|
134
|
+
Built by [Mehul Vig](https://github.com/Mehulvig24) and Kabir Sadani.
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
# aidress_sdk.py — Lightweight Aidress client SDK
|
|
4
|
+
#
|
|
5
|
+
# Drop this single file into any Python project to add Aidress trust verification.
|
|
6
|
+
# The simplest possible integration is two lines:
|
|
7
|
+
#
|
|
8
|
+
# from aidress_sdk import verify
|
|
9
|
+
# trust = verify("agent_id_here")
|
|
10
|
+
#
|
|
11
|
+
# No dependencies beyond Python's standard library.
|
|
12
|
+
|
|
13
|
+
import urllib.request
|
|
14
|
+
import urllib.error
|
|
15
|
+
import json
|
|
16
|
+
import time
|
|
17
|
+
|
|
18
|
+
# The error object returned whenever Aidress is unreachable or returns an
|
|
19
|
+
# unexpected response — safe defaults so callers can always read trust_score.
|
|
20
|
+
_UNREACHABLE = {"error": "Aidress unreachable", "verified": False, "trust_score": 0}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _parse_body(raw_bytes: bytes, status_code: int) -> dict:
|
|
24
|
+
"""
|
|
25
|
+
Safely decode an HTTP response body to a dict.
|
|
26
|
+
Falls back to a plain error dict if the body is empty or non-JSON
|
|
27
|
+
(e.g. an HTML gateway error page from a hosting proxy).
|
|
28
|
+
"""
|
|
29
|
+
raw = raw_bytes.decode("utf-8", errors="replace").strip()
|
|
30
|
+
if not raw:
|
|
31
|
+
return {"detail": f"HTTP {status_code} (empty body)"}
|
|
32
|
+
try:
|
|
33
|
+
return json.loads(raw)
|
|
34
|
+
except json.JSONDecodeError:
|
|
35
|
+
return {"detail": f"HTTP {status_code} — non-JSON response from server"}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# ── AidressClient ─────────────────────────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
class AidressClient:
|
|
41
|
+
"""
|
|
42
|
+
A thin wrapper around the Aidress REST API.
|
|
43
|
+
|
|
44
|
+
Create one instance per agent and reuse it across calls:
|
|
45
|
+
client = AidressClient() # uses live API
|
|
46
|
+
client = AidressClient("http://localhost:8000") # points at local server
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def __init__(self, base_url: str = "https://api.aidress.ai"):
|
|
50
|
+
# Strip trailing slash so callers don't need to worry about formatting
|
|
51
|
+
self.base_url = base_url.rstrip("/")
|
|
52
|
+
|
|
53
|
+
# ── Core request methods ─────────────────────────────────────────────────
|
|
54
|
+
|
|
55
|
+
def _post(self, path: str, payload: dict, _retries: int = 7) -> tuple[int, dict]:
|
|
56
|
+
"""
|
|
57
|
+
Send a POST request to the Aidress API and return (status_code, body).
|
|
58
|
+
Retries up to 7 times on 503 — cold starts can take up to 60 seconds;
|
|
59
|
+
we wait 5s between attempts (35s total headroom).
|
|
60
|
+
"""
|
|
61
|
+
data = json.dumps(payload).encode("utf-8")
|
|
62
|
+
req = urllib.request.Request(
|
|
63
|
+
url=f"{self.base_url}{path}",
|
|
64
|
+
data=data,
|
|
65
|
+
headers={"Content-Type": "application/json"},
|
|
66
|
+
method="POST",
|
|
67
|
+
)
|
|
68
|
+
for attempt in range(1, _retries + 1):
|
|
69
|
+
try:
|
|
70
|
+
with urllib.request.urlopen(req) as resp:
|
|
71
|
+
return resp.status, json.loads(resp.read().decode("utf-8"))
|
|
72
|
+
except urllib.error.HTTPError as e:
|
|
73
|
+
body = _parse_body(e.read(), e.code)
|
|
74
|
+
if e.code == 503 and attempt < _retries:
|
|
75
|
+
print(f" [Aidress] Server warming up, retrying ({attempt}/{_retries - 1})…")
|
|
76
|
+
time.sleep(5)
|
|
77
|
+
continue
|
|
78
|
+
return e.code, body
|
|
79
|
+
except urllib.error.URLError:
|
|
80
|
+
return 0, dict(_UNREACHABLE)
|
|
81
|
+
return 503, {"detail": "Server unavailable after retries"}
|
|
82
|
+
|
|
83
|
+
def _get(self, path: str) -> tuple[int, dict | list]:
|
|
84
|
+
"""Send a GET request to the Aidress API and return (status_code, body)."""
|
|
85
|
+
req = urllib.request.Request(
|
|
86
|
+
url=f"{self.base_url}{path}",
|
|
87
|
+
method="GET",
|
|
88
|
+
)
|
|
89
|
+
try:
|
|
90
|
+
with urllib.request.urlopen(req) as resp:
|
|
91
|
+
return resp.status, json.loads(resp.read().decode("utf-8"))
|
|
92
|
+
except urllib.error.HTTPError as e:
|
|
93
|
+
return e.code, _parse_body(e.read(), e.code)
|
|
94
|
+
except urllib.error.URLError:
|
|
95
|
+
return 0, dict(_UNREACHABLE)
|
|
96
|
+
|
|
97
|
+
# ── Public methods ───────────────────────────────────────────────────────
|
|
98
|
+
|
|
99
|
+
def verify(self, agent_id: str) -> dict:
|
|
100
|
+
"""
|
|
101
|
+
Look up an agent's trust profile before transacting with it.
|
|
102
|
+
|
|
103
|
+
Returns a trust object with fields: agent_id, verified, trust_score,
|
|
104
|
+
flags, capabilities, routing, org_name, org_domain.
|
|
105
|
+
Always returns a dict — never raises.
|
|
106
|
+
|
|
107
|
+
Usage:
|
|
108
|
+
trust = client.verify("agent_freightbot_01")
|
|
109
|
+
if trust["trust_score"] >= 70:
|
|
110
|
+
proceed()
|
|
111
|
+
"""
|
|
112
|
+
status, body = self._post("/verify", {"agent_id": agent_id})
|
|
113
|
+
if status == 0:
|
|
114
|
+
return {**_UNREACHABLE, "agent_id": agent_id}
|
|
115
|
+
return body
|
|
116
|
+
|
|
117
|
+
def match(self, required_capabilities: list[str]) -> list[dict]:
|
|
118
|
+
"""
|
|
119
|
+
Find verified agents that have all the capabilities you need,
|
|
120
|
+
ranked by trust_score descending (best match first).
|
|
121
|
+
|
|
122
|
+
Returns a list of trust objects — empty list if nothing matches.
|
|
123
|
+
|
|
124
|
+
Usage:
|
|
125
|
+
agents = client.match(["freight_booking", "customs_clearance"])
|
|
126
|
+
best = agents[0] if agents else None
|
|
127
|
+
"""
|
|
128
|
+
status, body = self._post("/match", {"required_capabilities": required_capabilities})
|
|
129
|
+
if status == 0 or not isinstance(body, list):
|
|
130
|
+
return []
|
|
131
|
+
return body
|
|
132
|
+
|
|
133
|
+
def review(
|
|
134
|
+
self,
|
|
135
|
+
caller_agent_id: str,
|
|
136
|
+
receiver_agent_id: str,
|
|
137
|
+
transaction_id: str,
|
|
138
|
+
success: bool,
|
|
139
|
+
score: int,
|
|
140
|
+
) -> dict:
|
|
141
|
+
"""
|
|
142
|
+
Report a transaction outcome and submit a trust rating in one call.
|
|
143
|
+
Must be called after a transaction completes — not before.
|
|
144
|
+
|
|
145
|
+
score: 1–5 (1 = very bad, 5 = excellent)
|
|
146
|
+
success: whether the transaction completed successfully
|
|
147
|
+
|
|
148
|
+
Returns the updated trust object for the receiver on success,
|
|
149
|
+
or a dict with an "error" key if the rating was blocked.
|
|
150
|
+
|
|
151
|
+
Usage:
|
|
152
|
+
result = client.review(
|
|
153
|
+
caller_agent_id="agent_a",
|
|
154
|
+
receiver_agent_id="agent_b",
|
|
155
|
+
transaction_id="txn-xyz",
|
|
156
|
+
success=True,
|
|
157
|
+
score=5,
|
|
158
|
+
)
|
|
159
|
+
"""
|
|
160
|
+
status, body = self._post("/review", {
|
|
161
|
+
"caller_agent_id": caller_agent_id,
|
|
162
|
+
"receiver_agent_id": receiver_agent_id,
|
|
163
|
+
"transaction_id": transaction_id,
|
|
164
|
+
"success": success,
|
|
165
|
+
"score": score,
|
|
166
|
+
})
|
|
167
|
+
if status == 0:
|
|
168
|
+
return dict(_UNREACHABLE)
|
|
169
|
+
if status == 403:
|
|
170
|
+
return {"error": body.get("detail", "Rating blocked by Aidress anti-gaming rules")}
|
|
171
|
+
return body
|
|
172
|
+
|
|
173
|
+
def register(
|
|
174
|
+
self,
|
|
175
|
+
agent_id: str,
|
|
176
|
+
org_name: str,
|
|
177
|
+
org_domain: str,
|
|
178
|
+
contact_email: str,
|
|
179
|
+
) -> dict:
|
|
180
|
+
"""
|
|
181
|
+
Register a new agent with the Aidress registry.
|
|
182
|
+
|
|
183
|
+
Returns a confirmation dict with status "pending_review" on success,
|
|
184
|
+
or a dict with an "error" key if the agent_id or org_domain is taken.
|
|
185
|
+
|
|
186
|
+
Usage:
|
|
187
|
+
result = client.register("my_agent_01", "Acme Corp", "acme.com", "bot@acme.com")
|
|
188
|
+
"""
|
|
189
|
+
status, body = self._post("/register", {
|
|
190
|
+
"agent_id": agent_id,
|
|
191
|
+
"org_name": org_name,
|
|
192
|
+
"org_domain": org_domain,
|
|
193
|
+
"contact_email": contact_email,
|
|
194
|
+
})
|
|
195
|
+
if status == 0:
|
|
196
|
+
return dict(_UNREACHABLE)
|
|
197
|
+
if status == 409:
|
|
198
|
+
return {"error": body.get("detail", "Agent or domain already registered")}
|
|
199
|
+
return body
|
|
200
|
+
|
|
201
|
+
def get_agent(self, agent_id: str) -> dict:
|
|
202
|
+
"""
|
|
203
|
+
Fetch the full profile for a registered agent.
|
|
204
|
+
|
|
205
|
+
Returns the agent profile dict, or a dict with an "error" key
|
|
206
|
+
if the agent is not found.
|
|
207
|
+
|
|
208
|
+
Usage:
|
|
209
|
+
profile = client.get_agent("agent_freightbot_01")
|
|
210
|
+
"""
|
|
211
|
+
status, body = self._get(f"/agent/{agent_id}")
|
|
212
|
+
if status == 0:
|
|
213
|
+
return dict(_UNREACHABLE)
|
|
214
|
+
if status == 404:
|
|
215
|
+
return {"error": f"Agent '{agent_id}' not found"}
|
|
216
|
+
return body
|
|
217
|
+
|
|
218
|
+
def registry(self) -> list[dict]:
|
|
219
|
+
"""
|
|
220
|
+
List all trusted agents in the Aidress registry (trust_score >= 50).
|
|
221
|
+
|
|
222
|
+
Returns a list of trust objects sorted by trust_score descending.
|
|
223
|
+
|
|
224
|
+
Usage:
|
|
225
|
+
agents = client.registry()
|
|
226
|
+
"""
|
|
227
|
+
status, body = self._get("/registry")
|
|
228
|
+
if status == 0 or not isinstance(body, list):
|
|
229
|
+
return []
|
|
230
|
+
return body
|
|
231
|
+
|
|
232
|
+
def import_agent(self, domain_url: str) -> dict:
|
|
233
|
+
"""
|
|
234
|
+
Pre-populate a registration from a domain's A2A agent card.
|
|
235
|
+
|
|
236
|
+
Fetches /.well-known/agent.json from the domain and returns a preview
|
|
237
|
+
with the fields Aidress was able to extract, plus a list of missing_fields
|
|
238
|
+
that still need to be provided before calling register().
|
|
239
|
+
|
|
240
|
+
Usage:
|
|
241
|
+
preview = client.import_agent("https://example.com")
|
|
242
|
+
if not preview.get("error"):
|
|
243
|
+
# fill missing_fields, then call register()
|
|
244
|
+
print(preview["missing_fields"])
|
|
245
|
+
"""
|
|
246
|
+
status, body = self._post("/import-agent", {"domain_url": domain_url})
|
|
247
|
+
if status == 0:
|
|
248
|
+
return dict(_UNREACHABLE)
|
|
249
|
+
if status == 422:
|
|
250
|
+
return {"error": body.get("detail", "Could not fetch agent card from domain")}
|
|
251
|
+
return body
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
# ── Module-level convenience functions ───────────────────────────────────────
|
|
255
|
+
# These are the one-liners developers can import directly without instantiating
|
|
256
|
+
# a client. They use a shared default client pointed at the live API.
|
|
257
|
+
|
|
258
|
+
_default_client = AidressClient()
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def verify(agent_id: str) -> dict:
|
|
262
|
+
"""
|
|
263
|
+
Look up an agent's trust profile — the single line you add to your agent.
|
|
264
|
+
|
|
265
|
+
from aidress_sdk import verify
|
|
266
|
+
trust = verify("agent_id_here")
|
|
267
|
+
"""
|
|
268
|
+
return _default_client.verify(agent_id)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def match(required_capabilities: list[str]) -> list[dict]:
|
|
272
|
+
"""
|
|
273
|
+
Find trusted agents that can handle the capabilities you need.
|
|
274
|
+
|
|
275
|
+
from aidress_sdk import match
|
|
276
|
+
agents = match(["freight_booking", "customs_clearance"])
|
|
277
|
+
"""
|
|
278
|
+
return _default_client.match(required_capabilities)
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def review(
|
|
282
|
+
caller_agent_id: str,
|
|
283
|
+
receiver_agent_id: str,
|
|
284
|
+
transaction_id: str,
|
|
285
|
+
success: bool,
|
|
286
|
+
score: int,
|
|
287
|
+
) -> dict:
|
|
288
|
+
"""
|
|
289
|
+
Report a transaction outcome and submit a trust rating.
|
|
290
|
+
|
|
291
|
+
from aidress_sdk import review
|
|
292
|
+
review("agent_a", "agent_b", "txn-xyz", success=True, score=5)
|
|
293
|
+
"""
|
|
294
|
+
return _default_client.review(caller_agent_id, receiver_agent_id, transaction_id, success, score)
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def register(
|
|
298
|
+
agent_id: str,
|
|
299
|
+
org_name: str,
|
|
300
|
+
org_domain: str,
|
|
301
|
+
contact_email: str,
|
|
302
|
+
) -> dict:
|
|
303
|
+
"""
|
|
304
|
+
Register a new agent with Aidress.
|
|
305
|
+
|
|
306
|
+
from aidress_sdk import register
|
|
307
|
+
register("my_agent_01", "Acme Corp", "acme.com", "bot@acme.com")
|
|
308
|
+
"""
|
|
309
|
+
return _default_client.register(agent_id, org_name, org_domain, contact_email)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def get_agent(agent_id: str) -> dict:
|
|
313
|
+
"""
|
|
314
|
+
Fetch the full profile for a registered agent.
|
|
315
|
+
|
|
316
|
+
from aidress_sdk import get_agent
|
|
317
|
+
profile = get_agent("agent_freightbot_01")
|
|
318
|
+
"""
|
|
319
|
+
return _default_client.get_agent(agent_id)
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def registry() -> list[dict]:
|
|
323
|
+
"""
|
|
324
|
+
List all trusted agents in the Aidress registry.
|
|
325
|
+
|
|
326
|
+
from aidress_sdk import registry
|
|
327
|
+
agents = registry()
|
|
328
|
+
"""
|
|
329
|
+
return _default_client.registry()
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def import_agent(domain_url: str) -> dict:
|
|
333
|
+
"""
|
|
334
|
+
Pre-populate a registration from a domain's A2A agent card.
|
|
335
|
+
|
|
336
|
+
from aidress_sdk import import_agent
|
|
337
|
+
preview = import_agent("https://example.com")
|
|
338
|
+
"""
|
|
339
|
+
return _default_client.import_agent(domain_url)
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
# ── Demo ──────────────────────────────────────────────────────────────────────
|
|
343
|
+
|
|
344
|
+
if __name__ == "__main__":
|
|
345
|
+
print("\n" + "═" * 55)
|
|
346
|
+
print(" Aidress SDK — integration demo")
|
|
347
|
+
print("═" * 55)
|
|
348
|
+
|
|
349
|
+
# ── verify() ─────────────────────────────────────────────────────────────
|
|
350
|
+
print("\n── verify('agent_freightbot_01') ──")
|
|
351
|
+
trust = verify("agent_freightbot_01")
|
|
352
|
+
print(f" agent_id : {trust.get('agent_id')}")
|
|
353
|
+
print(f" org_name : {trust.get('org_name')}")
|
|
354
|
+
print(f" verified : {trust.get('verified')}")
|
|
355
|
+
print(f" trust_score : {trust.get('trust_score')}/100")
|
|
356
|
+
print(f" capabilities: {trust.get('capabilities', [])}")
|
|
357
|
+
print(f" flags : {trust.get('flags', []) or 'none'}")
|
|
358
|
+
|
|
359
|
+
# ── match() ───────────────────────────────────────────────────────────────
|
|
360
|
+
print("\n── match(['freight_booking']) ──")
|
|
361
|
+
agents = match(["freight_booking"])
|
|
362
|
+
if agents:
|
|
363
|
+
best = agents[0]
|
|
364
|
+
print(f" {len(agents)} agent(s) matched. Top result:")
|
|
365
|
+
print(f" agent_id : {best.get('agent_id')}")
|
|
366
|
+
print(f" org_name : {best.get('org_name')}")
|
|
367
|
+
print(f" trust_score : {best.get('trust_score')}/100")
|
|
368
|
+
print(f" capabilities: {best.get('capabilities', [])}")
|
|
369
|
+
else:
|
|
370
|
+
print(" No agents matched.")
|
|
371
|
+
|
|
372
|
+
# ── registry() ───────────────────────────────────────────────────────────
|
|
373
|
+
print("\n── registry() ──")
|
|
374
|
+
all_agents = registry()
|
|
375
|
+
print(f" {len(all_agents)} trusted agent(s) in registry.")
|
|
376
|
+
|
|
377
|
+
print("\n" + "═" * 55)
|
|
378
|
+
print(" That's the full integration — two imports, two calls.")
|
|
379
|
+
print("═" * 55 + "\n")
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "aidress-sdk"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python SDK for the Aidress AI agent trust registry"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Mehul Vig" },
|
|
14
|
+
{ name = "Kabir Sadani" },
|
|
15
|
+
]
|
|
16
|
+
keywords = ["ai-agents", "trust", "registry", "aidress", "a2a"]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Topic :: Software Development :: Libraries",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
]
|
|
23
|
+
dependencies = []
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
Homepage = "https://github.com/Mehulvig24/aidress"
|
|
27
|
+
Documentation = "https://api.aidress.ai/docs"
|
|
28
|
+
|
|
29
|
+
[tool.hatch.build.targets.sdist]
|
|
30
|
+
include = ["aidress_sdk.py", "README.md", "pyproject.toml"]
|
|
31
|
+
|
|
32
|
+
[tool.hatch.build.targets.wheel]
|
|
33
|
+
packages = ["."]
|
|
34
|
+
only-include = ["aidress_sdk.py"]
|