Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ docs:
# Testing
# ============================================================================

test: utils_test client_test langchain_adapter_test
test: utils_test client_test langchain_adapter_test opg_token_test

utils_test:
pytest tests/utils_test.py -v
Expand All @@ -42,6 +42,9 @@ client_test:
langchain_adapter_test:
pytest tests/langchain_adapter_test.py -v

opg_token_test:
pytest tests/opg_token_test.py -v

integrationtest:
python integrationtest/agent/test_agent.py
python integrationtest/workflow_models/test_workflow_models.py
Expand Down Expand Up @@ -89,5 +92,5 @@ chat-tool:
--max-tokens 100 \
--stream

.PHONY: install build publish check docs test utils_test client_test integrationtest examples \
.PHONY: install build publish check docs test utils_test client_test langchain_adapter_test opg_token_test integrationtest examples \
infer completion chat chat-stream chat-tool
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,18 @@ result = client.llm.chat(
)
```

### OPG Token Approval

LLM inference payments use OPG tokens via the [Permit2](https://github.com/Uniswap/permit2) protocol. Before making requests, ensure your wallet has approved sufficient OPG for spending:

```python
# Checks current Permit2 allowance — only sends an on-chain transaction
# if the allowance is below the requested amount.
client.llm.ensure_opg_approval(opg_amount=5)
```

This is idempotent: if your wallet already has an allowance >= the requested amount, no transaction is sent.

## Examples

Additional code examples are available in the [examples](./examples) directory.
Expand Down
21 changes: 16 additions & 5 deletions docs/opengradient/client/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,33 @@ Main Client class that unifies all OpenGradient service namespaces.
Main OpenGradient SDK client.

Provides unified access to all OpenGradient services including LLM inference,
on-chain model inference, and the Model Hub. Handles authentication via
blockchain private key and optional Model Hub credentials.
on-chain model inference, and the Model Hub.

The client operates across two chains:

- **LLM inference** (``client.llm``) settles via x402 on **Base Sepolia**
using OPG tokens (funded by ``private_key``).
- **Alpha Testnet** (``client.alpha``) runs on the **OpenGradient network**
using testnet gas tokens (funded by ``alpha_private_key``, or ``private_key``
when not provided).

#### Constructor

```python
def __init__(private_key: str, email: Optional[str] = None, password: Optional[str] = None, twins_api_key: Optional[str] = None, wallet_address: str = None, rpc_url: str = 'https://ogevmdevnet.opengradient.ai', api_url: str = 'https://sdk-devnet.opengradient.ai', contract_address: str = '0x8383C9bD7462F12Eb996DD02F78234C0421A6FaE', og_llm_server_url: Optional[str] = 'https://llm.opengradient.ai', og_llm_streaming_server_url: Optional[str] = 'https://llm.opengradient.ai')
def __init__(private_key: str, alpha_private_key: Optional[str] = None, email: Optional[str] = None, password: Optional[str] = None, twins_api_key: Optional[str] = None, wallet_address: str = None, rpc_url: str = 'https://ogevmdevnet.opengradient.ai', api_url: str = 'https://sdk-devnet.opengradient.ai', contract_address: str = '0x8383C9bD7462F12Eb996DD02F78234C0421A6FaE', og_llm_server_url: Optional[str] = 'https://llm.opengradient.ai', og_llm_streaming_server_url: Optional[str] = 'https://llm.opengradient.ai')
```

**Arguments**

* **`private_key`**: Private key for OpenGradient transactions.
* **`private_key`**: Private key whose wallet holds **Base Sepolia OPG tokens**
for x402 LLM payments.
* **`alpha_private_key`**: Private key whose wallet holds **OpenGradient testnet
gas tokens** for on-chain inference. Optional -- falls back to
``private_key`` for backward compatibility.
* **`email`**: Email for Model Hub authentication. Optional.
* **`password`**: Password for Model Hub authentication. Optional.
* **`twins_api_key`**: API key for digital twins chat (twin.fun). Optional.
* **`rpc_url`**: RPC URL for the blockchain network.
* **`rpc_url`**: RPC URL for the OpenGradient Alpha Testnet.
* **`api_url`**: API URL for the OpenGradient API.
* **`contract_address`**: Inference contract address.
* **`og_llm_server_url`**: OpenGradient LLM server URL.
Expand Down
37 changes: 30 additions & 7 deletions docs/opengradient/client/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,29 @@ OpenGradient Client -- the central entry point to all SDK services.

The [Client](./client) class provides unified access to four service namespaces:

- **[llm](./llm)** -- LLM chat and text completion with TEE-verified execution and x402 payment settlement
- **[llm](./llm)** -- LLM chat and text completion with TEE-verified execution and x402 payment settlement (Base Sepolia OPG tokens)
- **[model_hub](./model_hub)** -- Model repository management: create, version, and upload ML models
- **[alpha](./alpha)** -- Alpha Testnet features: on-chain ONNX model inference (VANILLA, TEE, ZKML modes), workflow deployment, and scheduled ML model execution
- **[alpha](./alpha)** -- Alpha Testnet features: on-chain ONNX model inference (VANILLA, TEE, ZKML modes), workflow deployment, and scheduled ML model execution (OpenGradient testnet gas tokens)
- **[twins](./twins)** -- Digital twins chat via OpenGradient verifiable inference

## Private Keys

The SDK operates across two chains:

- **`private_key`** -- used for LLM inference (``client.llm``). Pays via x402 on **Base Sepolia** with OPG tokens.
- **`alpha_private_key`** *(optional)* -- used for Alpha Testnet features (``client.alpha``). Pays gas on the **OpenGradient network** with testnet tokens. Falls back to ``private_key`` when omitted.

## Usage

```python
import opengradient as og

# Single key for both chains (backward compatible)
client = og.init(private_key="0x...")

# Separate keys: Base Sepolia OPG for LLM, OpenGradient testnet gas for Alpha
client = og.init(private_key="0xLLM_KEY...", alpha_private_key="0xALPHA_KEY...")

# LLM chat (TEE-verified, streamed)
for chunk in client.llm.chat(
model=og.TEE_LLM.CLAUDE_3_5_HAIKU,
Expand Down Expand Up @@ -53,6 +64,7 @@ repo = client.model_hub.create_model("my-model", "A price prediction model")
* [exceptions](./exceptions): Exception types for OpenGradient SDK errors.
* [llm](./llm): LLM chat and completion via TEE-verified execution with x402 payments.
* [model_hub](./model_hub): Model Hub for creating, versioning, and uploading ML models.
* [opg_token](./opg_token): OPG token Permit2 approval utilities for x402 payments.
* [twins](./twins): Digital twins chat via OpenGradient verifiable inference.

## Classes
Expand All @@ -62,22 +74,33 @@ repo = client.model_hub.create_model("my-model", "A price prediction model")
Main OpenGradient SDK client.

Provides unified access to all OpenGradient services including LLM inference,
on-chain model inference, and the Model Hub. Handles authentication via
blockchain private key and optional Model Hub credentials.
on-chain model inference, and the Model Hub.

The client operates across two chains:

- **LLM inference** (``client.llm``) settles via x402 on **Base Sepolia**
using OPG tokens (funded by ``private_key``).
- **Alpha Testnet** (``client.alpha``) runs on the **OpenGradient network**
using testnet gas tokens (funded by ``alpha_private_key``, or ``private_key``
when not provided).

#### Constructor

```python
def __init__(private_key: str, email: Optional[str] = None, password: Optional[str] = None, twins_api_key: Optional[str] = None, wallet_address: str = None, rpc_url: str = 'https://ogevmdevnet.opengradient.ai', api_url: str = 'https://sdk-devnet.opengradient.ai', contract_address: str = '0x8383C9bD7462F12Eb996DD02F78234C0421A6FaE', og_llm_server_url: Optional[str] = 'https://llm.opengradient.ai', og_llm_streaming_server_url: Optional[str] = 'https://llm.opengradient.ai')
def __init__(private_key: str, alpha_private_key: Optional[str] = None, email: Optional[str] = None, password: Optional[str] = None, twins_api_key: Optional[str] = None, wallet_address: str = None, rpc_url: str = 'https://ogevmdevnet.opengradient.ai', api_url: str = 'https://sdk-devnet.opengradient.ai', contract_address: str = '0x8383C9bD7462F12Eb996DD02F78234C0421A6FaE', og_llm_server_url: Optional[str] = 'https://llm.opengradient.ai', og_llm_streaming_server_url: Optional[str] = 'https://llm.opengradient.ai')
```

**Arguments**

* **`private_key`**: Private key for OpenGradient transactions.
* **`private_key`**: Private key whose wallet holds **Base Sepolia OPG tokens**
for x402 LLM payments.
* **`alpha_private_key`**: Private key whose wallet holds **OpenGradient testnet
gas tokens** for on-chain inference. Optional -- falls back to
``private_key`` for backward compatibility.
* **`email`**: Email for Model Hub authentication. Optional.
* **`password`**: Password for Model Hub authentication. Optional.
* **`twins_api_key`**: API key for digital twins chat (twin.fun). Optional.
* **`rpc_url`**: RPC URL for the blockchain network.
* **`rpc_url`**: RPC URL for the OpenGradient Alpha Testnet.
* **`api_url`**: API URL for the OpenGradient API.
* **`contract_address`**: Inference contract address.
* **`og_llm_server_url`**: OpenGradient LLM server URL.
Expand Down
37 changes: 35 additions & 2 deletions docs/opengradient/client/llm.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ Provides access to large language model completions and chat via TEE
(Trusted Execution Environment) with x402 payment protocol support.
Supports both streaming and non-streaming responses.

Before making LLM requests, ensure your wallet has approved sufficient
OPG tokens for Permit2 spending by calling ``ensure_opg_approval``.
This only sends an on-chain transaction when the current allowance is
below the requested amount.

#### Constructor

```python
Expand All @@ -31,7 +36,7 @@ def __init__(wallet_account: `LocalAccount`, og_llm_server_url: str, og_llm_st
#### `chat()`

```python
def chat(self, model: `TEE_LLM`, messages: List[Dict], max_tokens: int = 100, stop_sequence: Optional[List[str]] = None, temperature: float = 0.0, tools: Optional[List[Dict]] = [], tool_choice: Optional[str] = None, x402_settlement_mode: Optional[`x402SettlementMode`] = x402SettlementMode.SETTLE_BATCH, stream: bool = False) ‑> Union[`TextGenerationOutput`, `TextGenerationStream`]
def chat(self, model: `TEE_LLM`, messages: List[Dict], max_tokens: int = 100, stop_sequence: Optional[List[str]] = None, temperature: float = 0.0, tools: Optional[List[Dict]] = None, tool_choice: Optional[str] = None, x402_settlement_mode: Optional[`x402SettlementMode`] = x402SettlementMode.SETTLE_BATCH, stream: bool = False) ‑> Union[`TextGenerationOutput`, `TextGenerationStream`]
```
Perform inference on an LLM model using chat via TEE.

Expand Down Expand Up @@ -92,4 +97,32 @@ TextGenerationOutput: Generated text results including:

**Raises**

* **`OpenGradientError`**: If the inference fails.
* **`OpenGradientError`**: If the inference fails.

---

#### `ensure_opg_approval()`

```python
def ensure_opg_approval(self, opg_amount: float) ‑> `Permit2ApprovalResult`
```
Ensure the Permit2 allowance for OPG is at least ``opg_amount``.

Checks the current Permit2 allowance for the wallet. If the allowance
is already >= the requested amount, returns immediately without sending
a transaction. Otherwise, sends an ERC-20 approve transaction.

**Arguments**

* **`opg_amount`**: Minimum number of OPG tokens required (e.g. ``5.0``
for 5 OPG). Converted to base units (18 decimals) internally.

**Returns**

Permit2ApprovalResult: Contains ``allowance_before``,
``allowance_after``, and ``tx_hash`` (None when no approval
was needed).

**Raises**

* **`OpenGradientError`**: If the approval transaction fails.
64 changes: 64 additions & 0 deletions docs/opengradient/client/opg_token.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
outline: [2,3]
---

[opengradient](../index) / [client](./index) / opg_token

# Package opengradient.client.opg_token

OPG token Permit2 approval utilities for x402 payments.

## Functions

---

### `ensure_opg_approval()`

```python
def ensure_opg_approval(wallet_account: `LocalAccount`, opg_amount: float) ‑> `Permit2ApprovalResult`
```
Ensure the Permit2 allowance for OPG is at least ``opg_amount``.

Checks the current Permit2 allowance for the wallet. If the allowance
is already >= the requested amount, returns immediately without sending
a transaction. Otherwise, sends an ERC-20 approve transaction.

**Arguments**

* **`wallet_account`**: The wallet account to check and approve from.
* **`opg_amount`**: Minimum number of OPG tokens required (e.g. ``5.0``
for 5 OPG). Converted to base units (18 decimals) internally.

**Returns**

Permit2ApprovalResult: Contains ``allowance_before``,
``allowance_after``, and ``tx_hash`` (None when no approval
was needed).

**Raises**

* **`OpenGradientError`**: If the approval transaction fails.

## Classes

### `Permit2ApprovalResult`

Result of a Permit2 allowance check / approval.

**Attributes**

* **`allowance_before`**: The Permit2 allowance before the method ran.
* **`allowance_after`**: The Permit2 allowance after the method ran.
* **`tx_hash`**: Transaction hash of the approval, or None if no transaction was needed.

#### Constructor

```python
def __init__(allowance_before: int, allowance_after: int, tx_hash: Optional[str] = None)
```

#### Variables

* static `allowance_after` : int
* static `allowance_before` : int
* static `tx_hash` : Optional[str]
47 changes: 37 additions & 10 deletions docs/opengradient/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ opengradient

# Package opengradient

**Version: 0.7.0**
**Version: 0.7.1**

OpenGradient Python SDK for decentralized AI inference with end-to-end verification.

Expand Down Expand Up @@ -55,12 +55,24 @@ result = client.alpha.infer(
print(result.model_output)
```

## Private Keys

The SDK operates across two chains. You can use a single key for both, or provide separate keys:

- **``private_key``** -- pays for LLM inference via x402 on **Base Sepolia** (requires OPG tokens)
- **``alpha_private_key``** *(optional)* -- pays gas for Alpha Testnet on-chain inference on the **OpenGradient network** (requires testnet gas tokens). Falls back to ``private_key`` when omitted.

```python
# Separate keys for each chain
client = og.init(private_key="0xBASE_KEY...", alpha_private_key="0xALPHA_KEY...")
```

## Client Namespaces

The [Client](./client/index) object exposes four namespaces:

- **[llm](./client/llm)** -- Verifiable LLM chat and completion via TEE-verified execution with x402 payments
- **[alpha](./client/alpha)** -- On-chain ONNX model inference, workflow deployment, and scheduled ML model execution (only available on the Alpha Testnet)
- **[llm](./client/llm)** -- Verifiable LLM chat and completion via TEE-verified execution with x402 payments (Base Sepolia OPG tokens)
- **[alpha](./client/alpha)** -- On-chain ONNX model inference, workflow deployment, and scheduled ML model execution (OpenGradient testnet gas tokens)
- **[model_hub](./client/model_hub)** -- Model repository management
- **[twins](./client/twins)** -- Digital twins chat via OpenGradient verifiable inference (requires twins API key)

Expand Down Expand Up @@ -96,7 +108,7 @@ The SDK includes adapters for popular AI frameworks -- see the `agents` submodul
### `init()`

```python
def init(private_key: str, email: Optional[str] = None, password: Optional[str] = None, **kwargs) ‑> `Client`
def init(private_key: str, alpha_private_key: Optional[str] = None, email: Optional[str] = None, password: Optional[str] = None, **kwargs) ‑> `Client`
```
Initialize the global OpenGradient client.

Expand All @@ -105,7 +117,11 @@ and stores it as the global client for convenience.

**Arguments**

* **`private_key`**: Private key for OpenGradient transactions.
* **`private_key`**: Private key whose wallet holds **Base Sepolia OPG tokens**
for x402 LLM payments.
* **`alpha_private_key`**: Private key whose wallet holds **OpenGradient testnet
gas tokens** for on-chain inference. Optional -- falls back to
``private_key`` for backward compatibility.
* **`email`**: Email for Model Hub authentication. Optional.
* **`password`**: Password for Model Hub authentication. Optional.
**kwargs: Additional arguments forwarded to `Client`.
Expand All @@ -121,22 +137,33 @@ The newly created `Client` instance.
Main OpenGradient SDK client.

Provides unified access to all OpenGradient services including LLM inference,
on-chain model inference, and the Model Hub. Handles authentication via
blockchain private key and optional Model Hub credentials.
on-chain model inference, and the Model Hub.

The client operates across two chains:

- **LLM inference** (``client.llm``) settles via x402 on **Base Sepolia**
using OPG tokens (funded by ``private_key``).
- **Alpha Testnet** (``client.alpha``) runs on the **OpenGradient network**
using testnet gas tokens (funded by ``alpha_private_key``, or ``private_key``
when not provided).

#### Constructor

```python
def __init__(private_key: str, email: Optional[str] = None, password: Optional[str] = None, twins_api_key: Optional[str] = None, wallet_address: str = None, rpc_url: str = 'https://ogevmdevnet.opengradient.ai', api_url: str = 'https://sdk-devnet.opengradient.ai', contract_address: str = '0x8383C9bD7462F12Eb996DD02F78234C0421A6FaE', og_llm_server_url: Optional[str] = 'https://llm.opengradient.ai', og_llm_streaming_server_url: Optional[str] = 'https://llm.opengradient.ai')
def __init__(private_key: str, alpha_private_key: Optional[str] = None, email: Optional[str] = None, password: Optional[str] = None, twins_api_key: Optional[str] = None, wallet_address: str = None, rpc_url: str = 'https://ogevmdevnet.opengradient.ai', api_url: str = 'https://sdk-devnet.opengradient.ai', contract_address: str = '0x8383C9bD7462F12Eb996DD02F78234C0421A6FaE', og_llm_server_url: Optional[str] = 'https://llm.opengradient.ai', og_llm_streaming_server_url: Optional[str] = 'https://llm.opengradient.ai')
```

**Arguments**

* **`private_key`**: Private key for OpenGradient transactions.
* **`private_key`**: Private key whose wallet holds **Base Sepolia OPG tokens**
for x402 LLM payments.
* **`alpha_private_key`**: Private key whose wallet holds **OpenGradient testnet
gas tokens** for on-chain inference. Optional -- falls back to
``private_key`` for backward compatibility.
* **`email`**: Email for Model Hub authentication. Optional.
* **`password`**: Password for Model Hub authentication. Optional.
* **`twins_api_key`**: API key for digital twins chat (twin.fun). Optional.
* **`rpc_url`**: RPC URL for the blockchain network.
* **`rpc_url`**: RPC URL for the OpenGradient Alpha Testnet.
* **`api_url`**: API URL for the OpenGradient API.
* **`contract_address`**: Inference contract address.
* **`og_llm_server_url`**: OpenGradient LLM server URL.
Expand Down
Loading