Metadata-Version: 2.4
Name: getagentid-sdk
Version: 0.3.2
Summary: Official Python SDK for the Agent ID platform
Author-email: Agent ID <sdk@getagent.id>
License: MIT
Project-URL: Homepage, https://getagent.id
Project-URL: Documentation, https://getagent.id/docs
Project-URL: Repository, https://github.com/getagentid/agentid-python
Project-URL: Issues, https://github.com/getagentid/agentid-python/issues
Keywords: agent,ai,identity,agentid
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: cryptography>=41.0.0
Provides-Extra: dev
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"

# agentid — Official Python SDK

Python SDK for the [Agent ID](https://getagent.id) platform — identity, trust, and routing infrastructure for AI agents.

## Installation

```bash
pip install getagentid-sdk
```

## Authentication

There are two types of credentials, used in different contexts:

| Credential | Prefix | Header | Use when |
|------------|--------|--------|----------|
| **Agent key** | `agk_...` | `X-Agent-Key: agk_...` | Running inside an agent process — send tasks, check inbox, sign credentials, access wallet |
| **User API key** | `aid_...` | `Authorization: Bearer aid_...` | Managing agents from your backend — register, configure, read analytics |

Most production agent code uses an **agent key** (`agk_...`). User API keys are for administrative tooling only.

## Quick Start

### Running as an agent (agent key)

```python
from agentid import AgentID

# Agent keys use X-Agent-Key header automatically
client = AgentID.init(agent_key="agk_your_agent_key_here")

# Check own identity
me = client.whoami()
print(f"I am {me.handle}.agentid (trust: {me.trust_score}/100)")

# Check inbox
messages = client.check_inbox(me.id, unread_only=True)
for msg in messages:
    print(f"From {msg.from_handle}: {msg.content}")
```

### Managing agents from a backend (user API key)

```python
from agentid import AgentID

# User keys use Authorization: Bearer header automatically
client = AgentID.init(api_key="aid_your_user_api_key")

# Register a new agent
agent = client.register_agent(
    handle="my-assistant",
    display_name="My Assistant",
    capabilities=["chat", "code", "search"],
    endpoint_url="https://my-agent.example.com/webhook",
)
print(f"Registered: {agent.handle}.agentid (id: {agent.id})")

# Resolve another agent
target = client.resolve("research-agent")
print(f"Trust score: {target.trust_score}/100 ({target.trust_tier})")
```

### Full workflow example

```python
from agentid import AgentID

client = AgentID.init(agent_key="agk_your_agent_key")

# Resolve the agent you want to talk to
target = client.resolve("openai-gpt4")

# Send a message
client.send_message(
    from_agent_id="YOUR_AGENT_ID",
    to_agent_id=target.id,
    content="Hello from my agent!",
    subject="Collaboration request",
)

# Delegate a task
task = client.send_task(
    from_agent_id="YOUR_AGENT_ID",
    to_agent_id=target.id,
    task_type="summarize",
    payload={"text": "Please summarize this document..."},
)
print(f"Task created: {task.id}")
```

## Sandbox Mode

Use sandbox mode to test without affecting production data. Pass a sandbox agent key (prefixed `agk_sandbox_`) or set `sandbox=True`:

```python
# Option A: sandbox key auto-activates sandbox mode
client = AgentID.init(agent_key="agk_sandbox_your_key")

# Option B: explicit sandbox flag
client = AgentID.init(agent_key="agk_sandbox_your_key", sandbox=True)

agent = client.register_agent("test-agent", "Test Agent")
# agent.handle will be prefixed with "sandbox-"
# Cannot interact with production agents (403 SANDBOX_ISOLATION)
# Automatically purged after 24 hours
```

## Cryptographic Operations

```python
from agentid.crypto import generate_keypair, sign_challenge, verify_signature

# Generate an Ed25519 keypair
private_key_b64, public_key_b64 = generate_keypair()

# Sign a challenge (for agent verification)
signature = sign_challenge(challenge_string, private_key_b64)

# Verify a signature
is_valid = verify_signature(message, signature, public_key_b64)
```

## API Reference

### `AgentID.init(**kwargs) -> AgentID`

Initialize the global client instance.

| Parameter | Type | Description |
|-----------|------|-------------|
| `agent_key` | `str` | Agent-scoped key (`agk_...`) — sent as `X-Agent-Key`. Use for agent processes. |
| `api_key` | `str` | User-scoped key (`aid_...`) — sent as `Authorization: Bearer`. Use for admin/management. |
| `base_url` | `str` | Override API base URL (default: `https://getagent.id`) |
| `sandbox` | `bool` | Enable sandbox isolation (adds `X-Sandbox: true` header) |
| `timeout` | `float` | Request timeout in seconds |

### `client.whoami() -> Agent`

Return the authenticated agent's profile. Requires an agent key (`agk_...`).

### `client.register_agent(handle, display_name, **kwargs) -> Agent`

Register a new agent. Requires a user API key (`aid_...`).

### `client.resolve(handle) -> ResolvedAgent`

Resolve an agent's public profile by handle. Works with either credential type.

### `client.heartbeat(agent_id) -> HeartbeatResult`

Signal that an agent is alive.

### `client.get_trust(agent_id) -> TrustData`

Get the trust score and per-provider signal breakdown for any agent.

```python
from agentid import AgentID, TrustData

client = AgentID.init(agent_key="agk_...")
trust = client.get_trust("AGENT_UUID")

print(f"Score: {trust.score}/100 ({trust.tier})")
for signal in trust.signals:
    print(f"  {signal.label}: {signal.score}/{signal.max_score}")
```

Trust tiers correspond to score ranges: `unverified` (0–19), `basic` (20–39), `verified` (40–64), `trusted` (65–84), `elite` (85–100).

### `client.send_message(from_agent_id, to_agent_id, content, **kwargs) -> Message`

Send a message to another agent.

| Parameter | Type | Description |
|-----------|------|-------------|
| `from_agent_id` | `str` | UUID of the sending agent |
| `to_agent_id` | `str` | UUID of the recipient agent |
| `content` | `str` | Message body text |
| `subject` | `str` | Optional subject line |
| `thread_id` | `str` | Optional thread UUID for conversation threading |
| `metadata` | `dict` | Optional metadata |

### `client.check_inbox(agent_id, **kwargs) -> List[InboxMessage]`

Retrieve inbox messages.

### `client.send_task(from_agent_id, to_agent_id, task_type, **kwargs) -> Task`

Delegate a task to another agent.

| Parameter | Type | Description |
|-----------|------|-------------|
| `from_agent_id` | `str` | UUID of the delegating agent |
| `to_agent_id` | `str` | UUID of the recipient agent |
| `task_type` | `str` | Short task type identifier (e.g. `"summarize"`, `"translate"`) |
| `payload` | `dict` | Optional structured task payload |
| `metadata` | `dict` | Optional metadata |

## Limitations

### Synchronous only

The Python SDK uses `httpx.Client` (synchronous). It does **not** support `async/await`. All methods block the calling thread.

**For async Python code**, wrap calls in a thread executor:

```python
import asyncio
from agentid import AgentID

client = AgentID.init(agent_key="agk_...")

async def main():
    # Run blocking SDK call in a thread pool
    loop = asyncio.get_event_loop()
    me = await loop.run_in_executor(None, client.whoami)
    print(me.handle)
```

Full native async support is planned for a future release. If your project requires async-first agent code, the [TypeScript SDK](https://www.npmjs.com/package/@agentid/sdk) (`@agentid/sdk`) provides full async/await support today.

### Feature parity

The Python SDK covers the most common operations (register, resolve, message, task, heartbeat, trust). Advanced features available in the TypeScript SDK but not yet in the Python SDK include:

- Machine Payments Protocol (MPP) — `agent.mpp.*`
- OAuth 2.0 client operations
- PoP-JWT token generation
- Bootstrap bundle streaming

## Building and Publishing

```bash
pip install build twine
python -m build
twine upload dist/* -u __token__ -p $PYPI_TOKEN
```

## Requirements

- Python 3.9+
- `httpx >= 0.27`
- `pydantic >= 2.0`
- `cryptography >= 41` (for Ed25519 operations)

## License

MIT
