agentcheck-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.
- agentcheck_sdk-0.1.0/PKG-INFO +80 -0
- agentcheck_sdk-0.1.0/README.md +56 -0
- agentcheck_sdk-0.1.0/agentcheck/__init__.py +95 -0
- agentcheck_sdk-0.1.0/agentcheck/client.py +157 -0
- agentcheck_sdk-0.1.0/agentcheck/exceptions.py +23 -0
- agentcheck_sdk-0.1.0/agentcheck/models.py +26 -0
- agentcheck_sdk-0.1.0/agentcheck/webhook/__init__.py +3 -0
- agentcheck_sdk-0.1.0/agentcheck/webhook/handler.py +59 -0
- agentcheck_sdk-0.1.0/agentcheck_sdk.egg-info/PKG-INFO +80 -0
- agentcheck_sdk-0.1.0/agentcheck_sdk.egg-info/SOURCES.txt +13 -0
- agentcheck_sdk-0.1.0/agentcheck_sdk.egg-info/dependency_links.txt +1 -0
- agentcheck_sdk-0.1.0/agentcheck_sdk.egg-info/requires.txt +2 -0
- agentcheck_sdk-0.1.0/agentcheck_sdk.egg-info/top_level.txt +1 -0
- agentcheck_sdk-0.1.0/pyproject.toml +36 -0
- agentcheck_sdk-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentcheck-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Record what your AI agent is allowed to do
|
|
5
|
+
Author-email: AgentCheck <dev@agentcheck.io>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://agentcheck.io
|
|
8
|
+
Project-URL: Repository, https://github.com/agentcheck/agentcheck-python
|
|
9
|
+
Keywords: ai,agent,delegation,trust,authorization
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Security
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: httpx>=0.25
|
|
23
|
+
Requires-Dist: pydantic>=2.0
|
|
24
|
+
|
|
25
|
+
# agentcheck
|
|
26
|
+
|
|
27
|
+
Record what your AI agent is allowed to do.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install agentcheck
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Quickstart
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
import agentcheck
|
|
39
|
+
|
|
40
|
+
agentcheck.init(api_key="ak_live_...", base_url="https://agentcheck.fly.dev")
|
|
41
|
+
|
|
42
|
+
proof = agentcheck.record(
|
|
43
|
+
agent="factory-bot",
|
|
44
|
+
scope="order parts under $10K, monitor equipment 24/7",
|
|
45
|
+
authorized_by="kim@factory.com"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# Kim gets an email, clicks "Approve"
|
|
49
|
+
# Anyone can verify: /api/v1/verify/{proof.id}
|
|
50
|
+
|
|
51
|
+
record = agentcheck.get(proof.id)
|
|
52
|
+
print(record.status) # "approved"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## API
|
|
56
|
+
|
|
57
|
+
| Function | Description |
|
|
58
|
+
|----------|-------------|
|
|
59
|
+
| `agentcheck.init(api_key, base_url)` | Initialize with your API key |
|
|
60
|
+
| `agentcheck.record(agent, scope, authorized_by)` | Create agreement |
|
|
61
|
+
| `agentcheck.get(id)` | Get agreement details |
|
|
62
|
+
| `agentcheck.list(status, agent)` | List agreements |
|
|
63
|
+
| `agentcheck.amend(id, new_scope)` | Amend agreement scope |
|
|
64
|
+
|
|
65
|
+
## Sign Up
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from agentcheck import Client
|
|
69
|
+
|
|
70
|
+
result = Client.signup(
|
|
71
|
+
email="dev@company.com",
|
|
72
|
+
company_name="My Company",
|
|
73
|
+
base_url="https://agentcheck.fly.dev"
|
|
74
|
+
)
|
|
75
|
+
print(result["api_key"]) # Save this - shown once only
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
MIT
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# agentcheck
|
|
2
|
+
|
|
3
|
+
Record what your AI agent is allowed to do.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install agentcheck
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import agentcheck
|
|
15
|
+
|
|
16
|
+
agentcheck.init(api_key="ak_live_...", base_url="https://agentcheck.fly.dev")
|
|
17
|
+
|
|
18
|
+
proof = agentcheck.record(
|
|
19
|
+
agent="factory-bot",
|
|
20
|
+
scope="order parts under $10K, monitor equipment 24/7",
|
|
21
|
+
authorized_by="kim@factory.com"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
# Kim gets an email, clicks "Approve"
|
|
25
|
+
# Anyone can verify: /api/v1/verify/{proof.id}
|
|
26
|
+
|
|
27
|
+
record = agentcheck.get(proof.id)
|
|
28
|
+
print(record.status) # "approved"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## API
|
|
32
|
+
|
|
33
|
+
| Function | Description |
|
|
34
|
+
|----------|-------------|
|
|
35
|
+
| `agentcheck.init(api_key, base_url)` | Initialize with your API key |
|
|
36
|
+
| `agentcheck.record(agent, scope, authorized_by)` | Create agreement |
|
|
37
|
+
| `agentcheck.get(id)` | Get agreement details |
|
|
38
|
+
| `agentcheck.list(status, agent)` | List agreements |
|
|
39
|
+
| `agentcheck.amend(id, new_scope)` | Amend agreement scope |
|
|
40
|
+
|
|
41
|
+
## Sign Up
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from agentcheck import Client
|
|
45
|
+
|
|
46
|
+
result = Client.signup(
|
|
47
|
+
email="dev@company.com",
|
|
48
|
+
company_name="My Company",
|
|
49
|
+
base_url="https://agentcheck.fly.dev"
|
|
50
|
+
)
|
|
51
|
+
print(result["api_key"]) # Save this - shown once only
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## License
|
|
55
|
+
|
|
56
|
+
MIT
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""AgentCheck - Record what your AI agent is allowed to do."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from .client import Client
|
|
6
|
+
from .exceptions import (
|
|
7
|
+
AgentCheckError,
|
|
8
|
+
AuthenticationError,
|
|
9
|
+
NotFoundError,
|
|
10
|
+
ServerError,
|
|
11
|
+
ValidationError,
|
|
12
|
+
)
|
|
13
|
+
from .models import Agreement, AgreementList
|
|
14
|
+
|
|
15
|
+
__version__ = "0.1.0"
|
|
16
|
+
__all__ = [
|
|
17
|
+
"Client",
|
|
18
|
+
"Agreement",
|
|
19
|
+
"AgreementList",
|
|
20
|
+
"AgentCheckError",
|
|
21
|
+
"AuthenticationError",
|
|
22
|
+
"NotFoundError",
|
|
23
|
+
"ValidationError",
|
|
24
|
+
"ServerError",
|
|
25
|
+
"init",
|
|
26
|
+
"record",
|
|
27
|
+
"get",
|
|
28
|
+
"list",
|
|
29
|
+
"amend",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
# -- Module-level convenience API --
|
|
33
|
+
# Enables: agentcheck.record(agent, scope, authorized_by)
|
|
34
|
+
|
|
35
|
+
_client: Client | None = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def init(api_key: str, base_url: str = "https://api.agentcheck.io"):
|
|
39
|
+
"""Initialize the global client."""
|
|
40
|
+
global _client
|
|
41
|
+
_client = Client(api_key=api_key, base_url=base_url)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _get_client() -> Client:
|
|
45
|
+
if _client is None:
|
|
46
|
+
raise AgentCheckError(
|
|
47
|
+
"Call agentcheck.init(api_key='...') first",
|
|
48
|
+
code="not_initialized",
|
|
49
|
+
)
|
|
50
|
+
return _client
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def record(
|
|
54
|
+
agent: str,
|
|
55
|
+
scope: str,
|
|
56
|
+
authorized_by: str,
|
|
57
|
+
**kwargs,
|
|
58
|
+
) -> Agreement:
|
|
59
|
+
"""Create a new agreement. One line is all you need."""
|
|
60
|
+
return _get_client().record(
|
|
61
|
+
agent=agent,
|
|
62
|
+
scope=scope,
|
|
63
|
+
authorized_by=authorized_by,
|
|
64
|
+
**kwargs,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get(agreement_id: str) -> Agreement:
|
|
69
|
+
"""Get agreement details."""
|
|
70
|
+
return _get_client().get(agreement_id)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def list(
|
|
74
|
+
status: str | None = None,
|
|
75
|
+
agent: str | None = None,
|
|
76
|
+
limit: int = 50,
|
|
77
|
+
offset: int = 0,
|
|
78
|
+
) -> AgreementList:
|
|
79
|
+
"""List agreements."""
|
|
80
|
+
return _get_client().list(status=status, agent=agent, limit=limit, offset=offset)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def amend(
|
|
84
|
+
agreement_id: str,
|
|
85
|
+
new_scope: str,
|
|
86
|
+
reason: str | None = None,
|
|
87
|
+
require_reauth: bool = True,
|
|
88
|
+
) -> Agreement:
|
|
89
|
+
"""Amend an agreement's scope."""
|
|
90
|
+
return _get_client().amend(
|
|
91
|
+
agreement_id=agreement_id,
|
|
92
|
+
new_scope=new_scope,
|
|
93
|
+
reason=reason,
|
|
94
|
+
require_reauth=require_reauth,
|
|
95
|
+
)
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import httpx
|
|
4
|
+
|
|
5
|
+
from .exceptions import (
|
|
6
|
+
AgentCheckError,
|
|
7
|
+
AuthenticationError,
|
|
8
|
+
NotFoundError,
|
|
9
|
+
ServerError,
|
|
10
|
+
ValidationError,
|
|
11
|
+
)
|
|
12
|
+
from .models import Agreement, AgreementList
|
|
13
|
+
|
|
14
|
+
_DEFAULT_BASE_URL = "https://api.agentcheck.io"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Client:
|
|
18
|
+
"""AgentCheck API client."""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
api_key: str,
|
|
23
|
+
base_url: str = _DEFAULT_BASE_URL,
|
|
24
|
+
timeout: float = 30.0,
|
|
25
|
+
):
|
|
26
|
+
self._api_key = api_key
|
|
27
|
+
self._base_url = base_url.rstrip("/")
|
|
28
|
+
self._http = httpx.Client(
|
|
29
|
+
base_url=self._base_url,
|
|
30
|
+
headers={"X-API-Key": api_key},
|
|
31
|
+
timeout=timeout,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def _handle_response(self, resp: httpx.Response) -> dict:
|
|
35
|
+
if resp.status_code == 401:
|
|
36
|
+
raise AuthenticationError("Invalid API key", code="unauthorized")
|
|
37
|
+
if resp.status_code == 404:
|
|
38
|
+
raise NotFoundError("Resource not found", code="not_found")
|
|
39
|
+
if resp.status_code == 400:
|
|
40
|
+
data = resp.json()
|
|
41
|
+
msg = data.get("error", {}).get("message", "Bad request")
|
|
42
|
+
raise ValidationError(msg, code="bad_request")
|
|
43
|
+
if resp.status_code >= 500:
|
|
44
|
+
raise ServerError("Server error", code="server_error")
|
|
45
|
+
if not resp.is_success:
|
|
46
|
+
raise AgentCheckError(f"HTTP {resp.status_code}")
|
|
47
|
+
return resp.json()
|
|
48
|
+
|
|
49
|
+
def record(
|
|
50
|
+
self,
|
|
51
|
+
agent: str,
|
|
52
|
+
scope: str,
|
|
53
|
+
authorized_by: str,
|
|
54
|
+
agent_provider: str | None = None,
|
|
55
|
+
expires_in_days: int | None = None,
|
|
56
|
+
metadata: dict | None = None,
|
|
57
|
+
) -> Agreement:
|
|
58
|
+
"""Create a new agreement and send approval email."""
|
|
59
|
+
body: dict = {
|
|
60
|
+
"agent": agent,
|
|
61
|
+
"scope": scope,
|
|
62
|
+
"authorized_by": authorized_by,
|
|
63
|
+
}
|
|
64
|
+
if agent_provider is not None:
|
|
65
|
+
body["agent_provider"] = agent_provider
|
|
66
|
+
if expires_in_days is not None:
|
|
67
|
+
body["expires_in_days"] = expires_in_days
|
|
68
|
+
if metadata is not None:
|
|
69
|
+
body["metadata"] = metadata
|
|
70
|
+
|
|
71
|
+
resp = self._http.post("/api/v1/record", json=body)
|
|
72
|
+
data = self._handle_response(resp)
|
|
73
|
+
return Agreement.model_validate(data["data"])
|
|
74
|
+
|
|
75
|
+
def get(self, agreement_id: str) -> Agreement:
|
|
76
|
+
"""Get agreement details by ID."""
|
|
77
|
+
resp = self._http.get(f"/api/v1/record/{agreement_id}")
|
|
78
|
+
data = self._handle_response(resp)
|
|
79
|
+
return Agreement.model_validate(data["data"])
|
|
80
|
+
|
|
81
|
+
def list(
|
|
82
|
+
self,
|
|
83
|
+
status: str | None = None,
|
|
84
|
+
agent: str | None = None,
|
|
85
|
+
limit: int = 50,
|
|
86
|
+
offset: int = 0,
|
|
87
|
+
) -> AgreementList:
|
|
88
|
+
"""List agreements with optional filters."""
|
|
89
|
+
params: dict = {"limit": limit, "offset": offset}
|
|
90
|
+
if status is not None:
|
|
91
|
+
params["status"] = status
|
|
92
|
+
if agent is not None:
|
|
93
|
+
params["agent"] = agent
|
|
94
|
+
|
|
95
|
+
resp = self._http.get("/api/v1/records", params=params)
|
|
96
|
+
data = self._handle_response(resp)
|
|
97
|
+
return AgreementList.model_validate(data["data"])
|
|
98
|
+
|
|
99
|
+
def amend(
|
|
100
|
+
self,
|
|
101
|
+
agreement_id: str,
|
|
102
|
+
new_scope: str,
|
|
103
|
+
reason: str | None = None,
|
|
104
|
+
require_reauth: bool = True,
|
|
105
|
+
) -> Agreement:
|
|
106
|
+
"""Amend an agreement's scope. Creates a new version."""
|
|
107
|
+
body: dict = {
|
|
108
|
+
"new_scope": new_scope,
|
|
109
|
+
"require_reauth": require_reauth,
|
|
110
|
+
}
|
|
111
|
+
if reason is not None:
|
|
112
|
+
body["reason"] = reason
|
|
113
|
+
|
|
114
|
+
resp = self._http.post(f"/api/v1/record/{agreement_id}/amend", json=body)
|
|
115
|
+
data = self._handle_response(resp)
|
|
116
|
+
return Agreement.model_validate(data["data"])
|
|
117
|
+
|
|
118
|
+
def register_webhook(
|
|
119
|
+
self,
|
|
120
|
+
url: str,
|
|
121
|
+
events: list[str],
|
|
122
|
+
) -> dict:
|
|
123
|
+
"""Register a webhook endpoint."""
|
|
124
|
+
resp = self._http.post(
|
|
125
|
+
"/api/v1/webhooks",
|
|
126
|
+
json={"url": url, "events": events},
|
|
127
|
+
)
|
|
128
|
+
data = self._handle_response(resp)
|
|
129
|
+
return data["data"]
|
|
130
|
+
|
|
131
|
+
@staticmethod
|
|
132
|
+
def signup(
|
|
133
|
+
email: str,
|
|
134
|
+
company_name: str | None = None,
|
|
135
|
+
base_url: str = _DEFAULT_BASE_URL,
|
|
136
|
+
) -> dict:
|
|
137
|
+
"""Self-service signup. Returns API key (shown once)."""
|
|
138
|
+
body: dict = {"email": email}
|
|
139
|
+
if company_name is not None:
|
|
140
|
+
body["company_name"] = company_name
|
|
141
|
+
resp = httpx.post(f"{base_url}/api/v1/signup", json=body)
|
|
142
|
+
if resp.status_code == 429:
|
|
143
|
+
raise AgentCheckError("Rate limited", code="rate_limited")
|
|
144
|
+
if not resp.is_success:
|
|
145
|
+
data = resp.json()
|
|
146
|
+
msg = data.get("error", {}).get("message", "Signup failed")
|
|
147
|
+
raise AgentCheckError(msg)
|
|
148
|
+
return resp.json()["data"]
|
|
149
|
+
|
|
150
|
+
def close(self):
|
|
151
|
+
self._http.close()
|
|
152
|
+
|
|
153
|
+
def __enter__(self):
|
|
154
|
+
return self
|
|
155
|
+
|
|
156
|
+
def __exit__(self, *args):
|
|
157
|
+
self.close()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class AgentCheckError(Exception):
|
|
2
|
+
"""Base exception for AgentCheck SDK."""
|
|
3
|
+
|
|
4
|
+
def __init__(self, message: str, code: str | None = None):
|
|
5
|
+
self.message = message
|
|
6
|
+
self.code = code
|
|
7
|
+
super().__init__(message)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AuthenticationError(AgentCheckError):
|
|
11
|
+
"""Invalid or missing API key."""
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class NotFoundError(AgentCheckError):
|
|
15
|
+
"""Resource not found."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ValidationError(AgentCheckError):
|
|
19
|
+
"""Invalid request parameters."""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ServerError(AgentCheckError):
|
|
23
|
+
"""Server-side error."""
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Agreement(BaseModel):
|
|
9
|
+
id: str
|
|
10
|
+
status: str
|
|
11
|
+
agent: str
|
|
12
|
+
agent_provider: str | None = None
|
|
13
|
+
scope: str
|
|
14
|
+
authorized_by: str
|
|
15
|
+
created_at: datetime
|
|
16
|
+
approved_at: datetime | None = None
|
|
17
|
+
expires_at: datetime | None = None
|
|
18
|
+
verify_url: str
|
|
19
|
+
signature: str | None = None
|
|
20
|
+
sig_algorithm: str = "HMAC-SHA256"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class AgreementList(BaseModel):
|
|
24
|
+
records: list[Agreement]
|
|
25
|
+
limit: int
|
|
26
|
+
offset: int
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
import hmac
|
|
5
|
+
import json
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
|
|
9
|
+
from ..exceptions import AgentCheckError
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class WebhookEvent:
|
|
14
|
+
id: str
|
|
15
|
+
type: str
|
|
16
|
+
created_at: str
|
|
17
|
+
data: dict
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class WebhookHandler:
|
|
21
|
+
"""Verify and parse incoming webhook events."""
|
|
22
|
+
|
|
23
|
+
def __init__(self, secret: str):
|
|
24
|
+
self._secret = secret
|
|
25
|
+
|
|
26
|
+
def verify_and_parse(self, body: str | bytes, signature: str) -> WebhookEvent:
|
|
27
|
+
"""Verify HMAC signature and parse webhook payload.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
body: Raw request body (str or bytes).
|
|
31
|
+
signature: Value from X-AgentCheck-Signature header.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
Parsed WebhookEvent.
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
AgentCheckError: If signature is invalid.
|
|
38
|
+
"""
|
|
39
|
+
if isinstance(body, str):
|
|
40
|
+
body_bytes = body.encode("utf-8")
|
|
41
|
+
else:
|
|
42
|
+
body_bytes = body
|
|
43
|
+
|
|
44
|
+
expected = hmac.new(
|
|
45
|
+
self._secret.encode("utf-8"),
|
|
46
|
+
body_bytes,
|
|
47
|
+
hashlib.sha256,
|
|
48
|
+
).hexdigest()
|
|
49
|
+
|
|
50
|
+
if not hmac.compare_digest(expected, signature):
|
|
51
|
+
raise AgentCheckError("Invalid webhook signature", code="invalid_signature")
|
|
52
|
+
|
|
53
|
+
payload = json.loads(body_bytes)
|
|
54
|
+
return WebhookEvent(
|
|
55
|
+
id=payload["id"],
|
|
56
|
+
type=payload["type"],
|
|
57
|
+
created_at=payload["created_at"],
|
|
58
|
+
data=payload.get("data", {}),
|
|
59
|
+
)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentcheck-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Record what your AI agent is allowed to do
|
|
5
|
+
Author-email: AgentCheck <dev@agentcheck.io>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://agentcheck.io
|
|
8
|
+
Project-URL: Repository, https://github.com/agentcheck/agentcheck-python
|
|
9
|
+
Keywords: ai,agent,delegation,trust,authorization
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Security
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: httpx>=0.25
|
|
23
|
+
Requires-Dist: pydantic>=2.0
|
|
24
|
+
|
|
25
|
+
# agentcheck
|
|
26
|
+
|
|
27
|
+
Record what your AI agent is allowed to do.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install agentcheck
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Quickstart
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
import agentcheck
|
|
39
|
+
|
|
40
|
+
agentcheck.init(api_key="ak_live_...", base_url="https://agentcheck.fly.dev")
|
|
41
|
+
|
|
42
|
+
proof = agentcheck.record(
|
|
43
|
+
agent="factory-bot",
|
|
44
|
+
scope="order parts under $10K, monitor equipment 24/7",
|
|
45
|
+
authorized_by="kim@factory.com"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# Kim gets an email, clicks "Approve"
|
|
49
|
+
# Anyone can verify: /api/v1/verify/{proof.id}
|
|
50
|
+
|
|
51
|
+
record = agentcheck.get(proof.id)
|
|
52
|
+
print(record.status) # "approved"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## API
|
|
56
|
+
|
|
57
|
+
| Function | Description |
|
|
58
|
+
|----------|-------------|
|
|
59
|
+
| `agentcheck.init(api_key, base_url)` | Initialize with your API key |
|
|
60
|
+
| `agentcheck.record(agent, scope, authorized_by)` | Create agreement |
|
|
61
|
+
| `agentcheck.get(id)` | Get agreement details |
|
|
62
|
+
| `agentcheck.list(status, agent)` | List agreements |
|
|
63
|
+
| `agentcheck.amend(id, new_scope)` | Amend agreement scope |
|
|
64
|
+
|
|
65
|
+
## Sign Up
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from agentcheck import Client
|
|
69
|
+
|
|
70
|
+
result = Client.signup(
|
|
71
|
+
email="dev@company.com",
|
|
72
|
+
company_name="My Company",
|
|
73
|
+
base_url="https://agentcheck.fly.dev"
|
|
74
|
+
)
|
|
75
|
+
print(result["api_key"]) # Save this - shown once only
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
MIT
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
agentcheck/__init__.py
|
|
4
|
+
agentcheck/client.py
|
|
5
|
+
agentcheck/exceptions.py
|
|
6
|
+
agentcheck/models.py
|
|
7
|
+
agentcheck/webhook/__init__.py
|
|
8
|
+
agentcheck/webhook/handler.py
|
|
9
|
+
agentcheck_sdk.egg-info/PKG-INFO
|
|
10
|
+
agentcheck_sdk.egg-info/SOURCES.txt
|
|
11
|
+
agentcheck_sdk.egg-info/dependency_links.txt
|
|
12
|
+
agentcheck_sdk.egg-info/requires.txt
|
|
13
|
+
agentcheck_sdk.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
agentcheck
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "agentcheck-sdk"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Record what your AI agent is allowed to do"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
authors = [{name = "AgentCheck", email = "dev@agentcheck.io"}]
|
|
13
|
+
keywords = ["ai", "agent", "delegation", "trust", "authorization"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.9",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Topic :: Security",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"httpx>=0.25",
|
|
28
|
+
"pydantic>=2.0",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://agentcheck.io"
|
|
33
|
+
Repository = "https://github.com/agentcheck/agentcheck-python"
|
|
34
|
+
|
|
35
|
+
[tool.setuptools.packages.find]
|
|
36
|
+
include = ["agentcheck*"]
|