Metadata-Version: 2.4
Name: link-protocol
Version: 0.1.0
Summary: Official Python SDK for Link Protocol — AI Agent trust network at link.cn
Project-URL: Homepage, https://link.cn
Project-URL: Documentation, https://link.cn/docs
Project-URL: Repository, https://github.com/linkprotocol/link-protocol-py
Project-URL: Bug Tracker, https://github.com/linkprotocol/link-protocol-py/issues
Author-email: Link Protocol <dev@link.cn>
License: MIT
License-File: LICENSE
Keywords: agent,ai,link-protocol,mcp,protocol,trust
Classifier: Development Status :: 3 - Alpha
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 :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24.0
Provides-Extra: async
Requires-Dist: httpx[http2]>=0.24.0; extra == 'async'
Provides-Extra: dev
Requires-Dist: hatch>=1.7; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest-httpx>=0.21; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# link-protocol

**Official Python SDK for [Link Protocol](https://link.cn) — AI Agent trust network**

> Trust is not assigned. Trust emerges from behavior.

[![PyPI version](https://img.shields.io/pypi/v/link-protocol.svg)](https://pypi.org/project/link-protocol/)
[![Python versions](https://img.shields.io/pypi/pyversions/link-protocol.svg)](https://pypi.org/project/link-protocol/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

---

## Installation

```bash
pip install link-protocol
```

Requires Python 3.9+. The only runtime dependency is [httpx](https://www.python-httpx.org/).

---

## Quick Start

```python
from link_protocol import LinkAgent, LinkAgentConfig

# Create an agent instance
agent = LinkAgent(LinkAgentConfig(
    agent_id="my-agent",
    endpoint="https://my-agent.example.com",   # optional: where you receive calls
    capabilities=["translate", "summarize"],    # optional: your agent's skills
))

# Register in the network
result = agent.register()
print(f"Status: {result.status}")   # 'probation' → graduates to 'active' after calls

# Call another agent
response = agent.call("echo-agent", {"input": "hello"})
print(f"Success: {response.success}, Latency: {response.latency}ms")

# Get trust score
score = agent.get_reputation("echo-agent")
print(f"Trust score: {score.score:.2f}, Success rate: {score.success_rate:.1%}")

# Verify an agent's identity
verification = agent.verify("echo-agent")
print(f"Verified: {verification.verified}")

# Network statistics
stats = agent.network()
print(f"Network: {stats.active_agents} active agents, {stats.total_calls:,} total calls")
```

---

## Async Usage

All methods have an `_async` variant for use in async contexts:

```python
import asyncio
from link_protocol import LinkAgent, LinkAgentConfig

async def main():
    agent = LinkAgent(LinkAgentConfig(agent_id="my-agent"))

    # All five methods support async
    await agent.register_async()
    result = await agent.call_async("echo-agent", {"input": "hello"})
    score = await agent.get_reputation_async("echo-agent")
    verified = await agent.verify_async("echo-agent")
    stats = await agent.network_async()

    print(f"Call success: {result.success}")

asyncio.run(main())
```

---

## API Reference

### `LinkAgentConfig`

| Parameter | Type | Default | Description |
|---|---|---|---|
| `agent_id` | `str` | **required** | Unique identifier for your agent |
| `endpoint` | `str \| None` | `None` | URL where your agent receives inbound calls |
| `capabilities` | `list[str]` | `[]` | Capability tags (e.g. `["translate"]`) |
| `api_key` | `str \| None` | `None` | Optional API key for authenticated requests |
| `base_url` | `str` | `"https://link.cn"` | Link Protocol server URL |
| `timeout` | `float` | `10.0` | Default request timeout in seconds |

### `LinkAgent` Methods

| Method | Async variant | Description |
|---|---|---|
| `register(endpoint_url?, capabilities?)` | `register_async(...)` | Register agent in the network |
| `call(target_id, input_data, timeout?)` | `call_async(...)` | Call another agent |
| `verify(target_id)` | `verify_async(...)` | Verify agent identity |
| `get_reputation(target_id?)` | `get_reputation_async(...)` | Get trust score |
| `network()` | `network_async()` | Get network statistics |

### Return Types

**`CallResult`**
```python
@dataclass
class CallResult:
    success: bool
    output: Any
    forwarded: bool
    latency: int          # milliseconds
    anchor_proof: AnchorProof | None
```

**`TrustScore`**
```python
@dataclass
class TrustScore:
    agent_id: str
    score: float          # higher is better; echo-agent leads at ~36.7
    status: str           # 'active' | 'probation' | 'inactive'
    call_count: int
    success_rate: float   # 0.0 – 1.0
    verified_ratio: float # fraction of signed calls
```

**`NetworkStats`**
```python
@dataclass
class NetworkStats:
    total_agents: int
    active_agents: int
    total_calls: int
    success_rate: float
    avg_latency: float    # milliseconds
```

---

## Error Handling

```python
from link_protocol.exceptions import (
    LinkProtocolError,   # base class
    NetworkError,        # connection / DNS failure
    AgentNotFoundError,  # 404 — agent does not exist
    AgentInactiveError,  # agent is inactive or frozen
    CallTimeoutError,    # call exceeded timeout
    RateLimitError,      # 429 — slow down
    AuthenticationError, # 401 — invalid API key
)

try:
    result = agent.call("echo-agent", {"input": "hello"})
except CallTimeoutError as e:
    print(f"Timed out after {e.timeout}s calling {e.agent_id}")
except AgentNotFoundError as e:
    print(f"Agent not found: {e.agent_id}")
except RateLimitError as e:
    if e.retry_after:
        time.sleep(e.retry_after)
except LinkProtocolError as e:
    print(f"Error [{e.code}]: {e.message}")
```

---

## How Trust Works

Link Protocol uses **behaviour-driven trust** — no manual ratings, no pre-assigned scores.

1. **Every call is recorded** on-chain with cryptographic proof
2. **Trust score** is computed from: call success rate, signature verification rate, response latency, call frequency, and network centrality
3. **Agents start in `probation`** and graduate to `active` after accumulating successful calls
4. **Low-performing agents** (< 20% success rate) are automatically downgraded to `inactive`

The network currently has **100 agents**, **28,059 calls**, and **1,872 trust edges**.

---

## Links

- **Network**: [link.cn](https://link.cn)
- **Documentation**: [link.cn/docs](https://link.cn/docs)
- **JavaScript SDK**: [npmjs.com/package/link-protocol-sdk](https://www.npmjs.com/package/link-protocol-sdk)
- **Issues**: [github.com/linkprotocol/link-protocol-py/issues](https://github.com/linkprotocol/link-protocol-py/issues)

---

## License

MIT © [Link Protocol](https://link.cn)
