clervo-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.
- clervo_sdk-0.1.0/PKG-INFO +129 -0
- clervo_sdk-0.1.0/README.md +120 -0
- clervo_sdk-0.1.0/clervo/__init__.py +17 -0
- clervo_sdk-0.1.0/clervo/client.py +155 -0
- clervo_sdk-0.1.0/pyproject.toml +26 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: clervo-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Clervo x402 Gateway SDK
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Requires-Dist: httpx>=0.24
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
|
|
10
|
+
# clervo
|
|
11
|
+
|
|
12
|
+
Python SDK for the [Clervo x402 Gateway](https://api.clervo.dev).
|
|
13
|
+
|
|
14
|
+
23 AI models. 8 free. Pay per call in USDC on Solana. No API keys.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install clervo
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick start
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from clervo import Clervo
|
|
26
|
+
|
|
27
|
+
client = Clervo()
|
|
28
|
+
|
|
29
|
+
# Free call — no wallet needed
|
|
30
|
+
text = client.chat("groq/llama-3.1-8b-instant", "Explain recursion in 2 sentences")
|
|
31
|
+
print(text)
|
|
32
|
+
|
|
33
|
+
# List models
|
|
34
|
+
models = client.models()
|
|
35
|
+
free = client.free_models()
|
|
36
|
+
print(f"{len(free)} free models available")
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Free models
|
|
40
|
+
|
|
41
|
+
No payment, no wallet, no signup:
|
|
42
|
+
|
|
43
|
+
| Model | Speed | Best for |
|
|
44
|
+
|-------|-------|----------|
|
|
45
|
+
| `groq/llama-3.1-8b-instant` | 170ms | Fast responses |
|
|
46
|
+
| `groq/llama-3.3-70b` | 800ms | Strong general |
|
|
47
|
+
| `sambanova/deepseek-v3.2` | 1.6s | Reasoning |
|
|
48
|
+
| `sambanova/llama-3.3-70b` | 1.5s | General |
|
|
49
|
+
| `hcn/qwen3.6-35b` | 0.9s | Fast small |
|
|
50
|
+
| `hcn/step-3.7-flash` | 3s | Reasoning |
|
|
51
|
+
| `hcn/deepseek-v4-pro` | 9s | Deep reasoning |
|
|
52
|
+
| `hcn/auto` | 3s | Auto-routed |
|
|
53
|
+
|
|
54
|
+
## Paid models (10-20% cheaper than BlockRun)
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from clervo import Clervo, PaymentRequired
|
|
58
|
+
|
|
59
|
+
client = Clervo()
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
text = client.chat("tongkhokr/claude-opus-5", "Review this code...")
|
|
63
|
+
except PaymentRequired:
|
|
64
|
+
print("Fund a Solana wallet with USDC for paid models")
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
| Model | Price/req |
|
|
68
|
+
|-------|-----------|
|
|
69
|
+
| `tongkhokr/claude-haiku-4.5` | $0.002 |
|
|
70
|
+
| `tongkhokr/claude-sonnet-5` | $0.015 |
|
|
71
|
+
| `tongkhokr/claude-opus-5` | $0.084 |
|
|
72
|
+
| `quickai/gpt-5.4-mini` | $0.005 |
|
|
73
|
+
| `quickai/gpt-5.5` | $0.035 |
|
|
74
|
+
|
|
75
|
+
## API
|
|
76
|
+
|
|
77
|
+
### `Clervo(api_url=None, timeout=30.0)`
|
|
78
|
+
|
|
79
|
+
| Param | Default | Description |
|
|
80
|
+
|-------|---------|-------------|
|
|
81
|
+
| `api_url` | `https://api.clervo.dev` | API base URL |
|
|
82
|
+
| `timeout` | `30.0` | Request timeout seconds |
|
|
83
|
+
|
|
84
|
+
### `client.chat(model, message, *, system=None, max_tokens=1024)`
|
|
85
|
+
|
|
86
|
+
Simple chat. Returns the text response.
|
|
87
|
+
|
|
88
|
+
### `client.chat_completion(model, messages, *, max_tokens=1024, response_format=None)`
|
|
89
|
+
|
|
90
|
+
Full OpenAI-compatible chat completion. Returns the full response dict.
|
|
91
|
+
|
|
92
|
+
### `client.models()`
|
|
93
|
+
|
|
94
|
+
List all available models.
|
|
95
|
+
|
|
96
|
+
### `client.free_models()`
|
|
97
|
+
|
|
98
|
+
List only free models.
|
|
99
|
+
|
|
100
|
+
### `client.operation(operation_id)`
|
|
101
|
+
|
|
102
|
+
Look up an operation by ID.
|
|
103
|
+
|
|
104
|
+
## OpenAI drop-in
|
|
105
|
+
|
|
106
|
+
Since Clervo is OpenAI-compatible:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from openai import OpenAI
|
|
110
|
+
|
|
111
|
+
client = OpenAI(
|
|
112
|
+
base_url="https://api.clervo.dev/v1",
|
|
113
|
+
api_key="unused" # no key needed for free models
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
response = client.chat.completions.create(
|
|
117
|
+
model="groq/llama-3.1-8b-instant",
|
|
118
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
119
|
+
)
|
|
120
|
+
print(response.choices[0].message.content)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Links
|
|
124
|
+
|
|
125
|
+
- API: https://api.clervo.dev
|
|
126
|
+
- Models: https://api.clervo.dev/v1/models
|
|
127
|
+
- Quickstart: https://api.clervo.dev/quickstart.md
|
|
128
|
+
- TypeScript SDK: https://npmjs.com/package/@clervo/sdk
|
|
129
|
+
- MCP: https://npmjs.com/package/@clervo/mcp
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# clervo
|
|
2
|
+
|
|
3
|
+
Python SDK for the [Clervo x402 Gateway](https://api.clervo.dev).
|
|
4
|
+
|
|
5
|
+
23 AI models. 8 free. Pay per call in USDC on Solana. No API keys.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install clervo
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from clervo import Clervo
|
|
17
|
+
|
|
18
|
+
client = Clervo()
|
|
19
|
+
|
|
20
|
+
# Free call — no wallet needed
|
|
21
|
+
text = client.chat("groq/llama-3.1-8b-instant", "Explain recursion in 2 sentences")
|
|
22
|
+
print(text)
|
|
23
|
+
|
|
24
|
+
# List models
|
|
25
|
+
models = client.models()
|
|
26
|
+
free = client.free_models()
|
|
27
|
+
print(f"{len(free)} free models available")
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Free models
|
|
31
|
+
|
|
32
|
+
No payment, no wallet, no signup:
|
|
33
|
+
|
|
34
|
+
| Model | Speed | Best for |
|
|
35
|
+
|-------|-------|----------|
|
|
36
|
+
| `groq/llama-3.1-8b-instant` | 170ms | Fast responses |
|
|
37
|
+
| `groq/llama-3.3-70b` | 800ms | Strong general |
|
|
38
|
+
| `sambanova/deepseek-v3.2` | 1.6s | Reasoning |
|
|
39
|
+
| `sambanova/llama-3.3-70b` | 1.5s | General |
|
|
40
|
+
| `hcn/qwen3.6-35b` | 0.9s | Fast small |
|
|
41
|
+
| `hcn/step-3.7-flash` | 3s | Reasoning |
|
|
42
|
+
| `hcn/deepseek-v4-pro` | 9s | Deep reasoning |
|
|
43
|
+
| `hcn/auto` | 3s | Auto-routed |
|
|
44
|
+
|
|
45
|
+
## Paid models (10-20% cheaper than BlockRun)
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from clervo import Clervo, PaymentRequired
|
|
49
|
+
|
|
50
|
+
client = Clervo()
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
text = client.chat("tongkhokr/claude-opus-5", "Review this code...")
|
|
54
|
+
except PaymentRequired:
|
|
55
|
+
print("Fund a Solana wallet with USDC for paid models")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
| Model | Price/req |
|
|
59
|
+
|-------|-----------|
|
|
60
|
+
| `tongkhokr/claude-haiku-4.5` | $0.002 |
|
|
61
|
+
| `tongkhokr/claude-sonnet-5` | $0.015 |
|
|
62
|
+
| `tongkhokr/claude-opus-5` | $0.084 |
|
|
63
|
+
| `quickai/gpt-5.4-mini` | $0.005 |
|
|
64
|
+
| `quickai/gpt-5.5` | $0.035 |
|
|
65
|
+
|
|
66
|
+
## API
|
|
67
|
+
|
|
68
|
+
### `Clervo(api_url=None, timeout=30.0)`
|
|
69
|
+
|
|
70
|
+
| Param | Default | Description |
|
|
71
|
+
|-------|---------|-------------|
|
|
72
|
+
| `api_url` | `https://api.clervo.dev` | API base URL |
|
|
73
|
+
| `timeout` | `30.0` | Request timeout seconds |
|
|
74
|
+
|
|
75
|
+
### `client.chat(model, message, *, system=None, max_tokens=1024)`
|
|
76
|
+
|
|
77
|
+
Simple chat. Returns the text response.
|
|
78
|
+
|
|
79
|
+
### `client.chat_completion(model, messages, *, max_tokens=1024, response_format=None)`
|
|
80
|
+
|
|
81
|
+
Full OpenAI-compatible chat completion. Returns the full response dict.
|
|
82
|
+
|
|
83
|
+
### `client.models()`
|
|
84
|
+
|
|
85
|
+
List all available models.
|
|
86
|
+
|
|
87
|
+
### `client.free_models()`
|
|
88
|
+
|
|
89
|
+
List only free models.
|
|
90
|
+
|
|
91
|
+
### `client.operation(operation_id)`
|
|
92
|
+
|
|
93
|
+
Look up an operation by ID.
|
|
94
|
+
|
|
95
|
+
## OpenAI drop-in
|
|
96
|
+
|
|
97
|
+
Since Clervo is OpenAI-compatible:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from openai import OpenAI
|
|
101
|
+
|
|
102
|
+
client = OpenAI(
|
|
103
|
+
base_url="https://api.clervo.dev/v1",
|
|
104
|
+
api_key="unused" # no key needed for free models
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
response = client.chat.completions.create(
|
|
108
|
+
model="groq/llama-3.1-8b-instant",
|
|
109
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
110
|
+
)
|
|
111
|
+
print(response.choices[0].message.content)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Links
|
|
115
|
+
|
|
116
|
+
- API: https://api.clervo.dev
|
|
117
|
+
- Models: https://api.clervo.dev/v1/models
|
|
118
|
+
- Quickstart: https://api.clervo.dev/quickstart.md
|
|
119
|
+
- TypeScript SDK: https://npmjs.com/package/@clervo/sdk
|
|
120
|
+
- MCP: https://npmjs.com/package/@clervo/mcp
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Clervo x402 Gateway SDK
|
|
3
|
+
|
|
4
|
+
23 AI models. 8 free. Pay per call in USDC on Solana.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
from clervo import Clervo
|
|
8
|
+
|
|
9
|
+
client = Clervo()
|
|
10
|
+
response = client.chat("groq/llama-3.1-8b-instant", "Hello!")
|
|
11
|
+
print(response)
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from clervo.client import Clervo
|
|
15
|
+
|
|
16
|
+
__all__ = ["Clervo"]
|
|
17
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""Clervo x402 Gateway client."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import uuid
|
|
5
|
+
from typing import Any, Dict, List, Optional
|
|
6
|
+
|
|
7
|
+
import httpx
|
|
8
|
+
|
|
9
|
+
DEFAULT_API = "https://api.clervo.dev"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ClervoError(Exception):
|
|
13
|
+
"""Base exception for Clervo SDK errors."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, message: str, status: int = 0, code: str = ""):
|
|
16
|
+
super().__init__(message)
|
|
17
|
+
self.status = status
|
|
18
|
+
self.code = code
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class PaymentRequired(ClervoError):
|
|
22
|
+
"""Raised when a paid model is called without payment."""
|
|
23
|
+
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Clervo:
|
|
28
|
+
"""Clervo x402 Gateway client.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
api_url: Base URL for the Clervo API. Defaults to CLERVO_API_URL env or https://api.clervo.dev.
|
|
32
|
+
timeout: Request timeout in seconds. Default 30.
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
>>> from clervo import Clervo
|
|
36
|
+
>>> client = Clervo()
|
|
37
|
+
>>> text = client.chat("groq/llama-3.1-8b-instant", "Hello!")
|
|
38
|
+
>>> print(text)
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(self, api_url: Optional[str] = None, timeout: float = 30.0):
|
|
42
|
+
self._api_url = api_url or os.environ.get("CLERVO_API_URL", DEFAULT_API)
|
|
43
|
+
self._client = httpx.Client(base_url=self._api_url, timeout=timeout)
|
|
44
|
+
|
|
45
|
+
def chat(
|
|
46
|
+
self,
|
|
47
|
+
model: str,
|
|
48
|
+
message: str,
|
|
49
|
+
*,
|
|
50
|
+
system: Optional[str] = None,
|
|
51
|
+
max_tokens: int = 1024,
|
|
52
|
+
) -> str:
|
|
53
|
+
"""Simple chat — returns just the text response.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
model: Model ID (e.g. "groq/llama-3.1-8b-instant").
|
|
57
|
+
message: User message.
|
|
58
|
+
system: Optional system prompt.
|
|
59
|
+
max_tokens: Max output tokens.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
The assistant's text response.
|
|
63
|
+
|
|
64
|
+
Raises:
|
|
65
|
+
PaymentRequired: If model requires x402 payment.
|
|
66
|
+
ClervoError: On API errors.
|
|
67
|
+
"""
|
|
68
|
+
messages = []
|
|
69
|
+
if system:
|
|
70
|
+
messages.append({"role": "system", "content": system})
|
|
71
|
+
messages.append({"role": "user", "content": message})
|
|
72
|
+
|
|
73
|
+
result = self.chat_completion(model, messages, max_tokens=max_tokens)
|
|
74
|
+
return result["choices"][0]["message"]["content"]
|
|
75
|
+
|
|
76
|
+
def chat_completion(
|
|
77
|
+
self,
|
|
78
|
+
model: str,
|
|
79
|
+
messages: List[Dict[str, str]],
|
|
80
|
+
*,
|
|
81
|
+
max_tokens: int = 1024,
|
|
82
|
+
response_format: Optional[Dict[str, Any]] = None,
|
|
83
|
+
) -> Dict[str, Any]:
|
|
84
|
+
"""Full OpenAI-compatible chat completion.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
model: Model ID.
|
|
88
|
+
messages: List of message dicts with 'role' and 'content'.
|
|
89
|
+
max_tokens: Max output tokens.
|
|
90
|
+
response_format: Optional response format spec.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
Full completion response dict (OpenAI-compatible).
|
|
94
|
+
"""
|
|
95
|
+
body: Dict[str, Any] = {
|
|
96
|
+
"model": model,
|
|
97
|
+
"messages": messages,
|
|
98
|
+
"max_completion_tokens": max_tokens,
|
|
99
|
+
}
|
|
100
|
+
if response_format:
|
|
101
|
+
body["response_format"] = response_format
|
|
102
|
+
|
|
103
|
+
r = self._client.post(
|
|
104
|
+
"/v1/chat/completions",
|
|
105
|
+
json=body,
|
|
106
|
+
headers={
|
|
107
|
+
"idempotency-key": str(uuid.uuid4()),
|
|
108
|
+
},
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
if r.status_code == 402:
|
|
112
|
+
raise PaymentRequired(
|
|
113
|
+
f'Payment required for model "{model}". Use a free model or fund a wallet.',
|
|
114
|
+
status=402,
|
|
115
|
+
code="PAYMENT_REQUIRED",
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
if r.status_code != 200:
|
|
119
|
+
data = r.json() if r.headers.get("content-type", "").startswith("application/json") else {}
|
|
120
|
+
raise ClervoError(
|
|
121
|
+
data.get("error", {}).get("message", f"API error: {r.status_code}"),
|
|
122
|
+
status=r.status_code,
|
|
123
|
+
code=data.get("error", {}).get("code", "API_ERROR"),
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
result = r.json()
|
|
127
|
+
result["_operation_id"] = r.headers.get("x-clervo-operation-id")
|
|
128
|
+
result["_replay"] = r.headers.get("x-idempotent-replay") == "true"
|
|
129
|
+
return result
|
|
130
|
+
|
|
131
|
+
def models(self) -> List[Dict[str, Any]]:
|
|
132
|
+
"""List all available models."""
|
|
133
|
+
r = self._client.get("/v1/models")
|
|
134
|
+
return r.json().get("data", [])
|
|
135
|
+
|
|
136
|
+
def free_models(self) -> List[Dict[str, Any]]:
|
|
137
|
+
"""List only free models (no payment needed)."""
|
|
138
|
+
return [m for m in self.models() if m.get("lifecycle") == "free_beta"]
|
|
139
|
+
|
|
140
|
+
def operation(self, operation_id: str) -> Optional[Dict[str, Any]]:
|
|
141
|
+
"""Get operation status/receipt."""
|
|
142
|
+
r = self._client.get(f"/v1/operations/{operation_id}")
|
|
143
|
+
if r.status_code == 404:
|
|
144
|
+
return None
|
|
145
|
+
return r.json()
|
|
146
|
+
|
|
147
|
+
def close(self):
|
|
148
|
+
"""Close the HTTP client."""
|
|
149
|
+
self._client.close()
|
|
150
|
+
|
|
151
|
+
def __enter__(self):
|
|
152
|
+
return self
|
|
153
|
+
|
|
154
|
+
def __exit__(self, *_):
|
|
155
|
+
self.close()
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "clervo"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Clervo x402 Gateway SDK — 23 AI models, 8 free. Pay per call in USDC."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.8"
|
|
12
|
+
keywords = ["clervo", "x402", "ai", "claude", "gpt", "deepseek", "llm", "usdc", "solana", "openai"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 4 - Beta",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
19
|
+
]
|
|
20
|
+
dependencies = ["httpx>=0.24"]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://clervo.dev"
|
|
24
|
+
API = "https://api.clervo.dev"
|
|
25
|
+
Documentation = "https://api.clervo.dev/quickstart.md"
|
|
26
|
+
Repository = "https://github.com/clervo/clervo-python"
|