opengradient 0.4.12b1__tar.gz → 0.4.13__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.
- {opengradient-0.4.12b1/src/opengradient.egg-info → opengradient-0.4.13}/PKG-INFO +3 -5
- {opengradient-0.4.12b1 → opengradient-0.4.13}/pyproject.toml +3 -5
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/__init__.py +7 -5
- opengradient-0.4.13/src/opengradient/abi/InferencePrecompile.abi +1 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/cli.py +2 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/client.py +99 -2
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/defaults.py +2 -1
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/llm/og_langchain.py +2 -2
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/utils.py +5 -14
- {opengradient-0.4.12b1 → opengradient-0.4.13/src/opengradient.egg-info}/PKG-INFO +3 -5
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient.egg-info/SOURCES.txt +1 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient.egg-info/requires.txt +2 -4
- {opengradient-0.4.12b1 → opengradient-0.4.13}/LICENSE +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/README.md +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/setup.cfg +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/abi/PriceHistoryInference.abi +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/abi/WorkflowScheduler.abi +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/abi/inference.abi +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/account.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/alphasense/__init__.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/alphasense/read_workflow_tool.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/alphasense/run_model_tool.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/alphasense/types.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/bin/PriceHistoryInference.bin +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/exceptions.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/llm/__init__.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/llm/og_openai.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/proto/__init__.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/proto/infer.proto +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/proto/infer_pb2.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/proto/infer_pb2_grpc.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/types.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/workflow_models/__init__.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/workflow_models/constants.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/workflow_models/types.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/workflow_models/utils.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/workflow_models/workflow_models.py +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient.egg-info/dependency_links.txt +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient.egg-info/entry_points.txt +0 -0
- {opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opengradient
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.13
|
|
4
4
|
Summary: Python SDK for OpenGradient decentralized model management & inference services
|
|
5
5
|
Author-email: OpenGradient <oliver@opengradient.ai>
|
|
6
6
|
License: MIT License
|
|
@@ -35,10 +35,8 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
35
35
|
Requires-Python: >=3.10
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
37
37
|
License-File: LICENSE
|
|
38
|
-
Requires-Dist: eth-
|
|
39
|
-
Requires-Dist:
|
|
40
|
-
Requires-Dist: web3>=6.11
|
|
41
|
-
Requires-Dist: websockets>=14.1
|
|
38
|
+
Requires-Dist: eth-account>=0.13.4
|
|
39
|
+
Requires-Dist: web3>=7.3.0
|
|
42
40
|
Requires-Dist: click>=8.1.7
|
|
43
41
|
Requires-Dist: firebase-rest-api>=1.11.0
|
|
44
42
|
Requires-Dist: grpcio>=1.66.2
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "opengradient"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.13"
|
|
8
8
|
description = "Python SDK for OpenGradient decentralized model management & inference services"
|
|
9
9
|
authors = [{name = "OpenGradient", email = "oliver@opengradient.ai"}]
|
|
10
10
|
license = {file = "LICENSE"}
|
|
@@ -20,10 +20,8 @@ classifiers = [
|
|
|
20
20
|
]
|
|
21
21
|
|
|
22
22
|
dependencies = [
|
|
23
|
-
"eth-
|
|
24
|
-
"
|
|
25
|
-
"web3>=6.11",
|
|
26
|
-
"websockets>=14.1",
|
|
23
|
+
"eth-account>=0.13.4",
|
|
24
|
+
"web3>=7.3.0",
|
|
27
25
|
"click>=8.1.7",
|
|
28
26
|
"firebase-rest-api>=1.11.0",
|
|
29
27
|
"grpcio>=1.66.2",
|
|
@@ -5,7 +5,7 @@ OpenGradient Python SDK for interacting with AI models and infrastructure.
|
|
|
5
5
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
6
6
|
|
|
7
7
|
from .client import Client
|
|
8
|
-
from .defaults import DEFAULT_INFERENCE_CONTRACT_ADDRESS, DEFAULT_RPC_URL
|
|
8
|
+
from .defaults import DEFAULT_INFERENCE_CONTRACT_ADDRESS, DEFAULT_RPC_URL, DEFAULT_API_URL
|
|
9
9
|
from .types import (
|
|
10
10
|
LLM,
|
|
11
11
|
TEE_LLM,
|
|
@@ -32,6 +32,7 @@ def new_client(
|
|
|
32
32
|
password: Optional[str],
|
|
33
33
|
private_key: str,
|
|
34
34
|
rpc_url=DEFAULT_RPC_URL,
|
|
35
|
+
api_url=DEFAULT_API_URL,
|
|
35
36
|
contract_address=DEFAULT_INFERENCE_CONTRACT_ADDRESS,
|
|
36
37
|
) -> Client:
|
|
37
38
|
"""
|
|
@@ -45,10 +46,10 @@ def new_client(
|
|
|
45
46
|
contract_address: Optional inference contract address
|
|
46
47
|
"""
|
|
47
48
|
|
|
48
|
-
return Client(email=email, password=password, private_key=private_key, rpc_url=rpc_url, contract_address=contract_address)
|
|
49
|
+
return Client(email=email, password=password, private_key=private_key, rpc_url=rpc_url, api_url=api_url, contract_address=contract_address)
|
|
49
50
|
|
|
50
51
|
|
|
51
|
-
def init(email: str, password: str, private_key: str, rpc_url=DEFAULT_RPC_URL, contract_address=DEFAULT_INFERENCE_CONTRACT_ADDRESS):
|
|
52
|
+
def init(email: str, password: str, private_key: str, rpc_url=DEFAULT_RPC_URL, api_url=DEFAULT_API_URL, contract_address=DEFAULT_INFERENCE_CONTRACT_ADDRESS):
|
|
52
53
|
"""Initialize the OpenGradient SDK with authentication and network settings.
|
|
53
54
|
|
|
54
55
|
Args:
|
|
@@ -56,11 +57,12 @@ def init(email: str, password: str, private_key: str, rpc_url=DEFAULT_RPC_URL, c
|
|
|
56
57
|
password: User's password for authentication
|
|
57
58
|
private_key: Ethereum private key for blockchain transactions
|
|
58
59
|
rpc_url: Optional RPC URL for the blockchain network, defaults to mainnet
|
|
60
|
+
api_url: Optional API URL for the OpenGradient API, defaults to mainnet
|
|
59
61
|
contract_address: Optional inference contract address
|
|
60
62
|
"""
|
|
61
63
|
global _client
|
|
62
|
-
|
|
63
|
-
_client = Client(private_key=private_key, rpc_url=rpc_url, email=email, password=password, contract_address=contract_address)
|
|
64
|
+
|
|
65
|
+
_client = Client(private_key=private_key, rpc_url=rpc_url, api_url=api_url, email=email, password=password, contract_address=contract_address)
|
|
64
66
|
return _client
|
|
65
67
|
|
|
66
68
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"inferenceID","type":"string"},{"components":[{"internalType":"enum LLMInferenceMode","name":"mode","type":"uint8"},{"internalType":"string","name":"modelCID","type":"string"},{"components":[{"internalType":"string","name":"role","type":"string"},{"internalType":"string","name":"content","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"tool_call_id","type":"string"},{"components":[{"internalType":"string","name":"id","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"arguments","type":"string"}],"internalType":"struct ToolCall[]","name":"tool_calls","type":"tuple[]"}],"internalType":"struct ChatMessage[]","name":"messages","type":"tuple[]"},{"components":[{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"parameters","type":"string"}],"internalType":"struct ToolDefinition[]","name":"tools","type":"tuple[]"},{"internalType":"string","name":"tool_choice","type":"string"},{"internalType":"uint32","name":"max_tokens","type":"uint32"},{"internalType":"string[]","name":"stop_sequence","type":"string[]"},{"internalType":"uint32","name":"temperature","type":"uint32"}],"indexed":false,"internalType":"struct LLMChatRequest","name":"request","type":"tuple"},{"components":[{"internalType":"string","name":"finish_reason","type":"string"},{"components":[{"internalType":"string","name":"role","type":"string"},{"internalType":"string","name":"content","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"tool_call_id","type":"string"},{"components":[{"internalType":"string","name":"id","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"arguments","type":"string"}],"internalType":"struct ToolCall[]","name":"tool_calls","type":"tuple[]"}],"internalType":"struct ChatMessage","name":"message","type":"tuple"}],"indexed":false,"internalType":"struct LLMChatResponse","name":"response","type":"tuple"}],"name":"LLMChat","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"inferenceID","type":"string"},{"components":[{"internalType":"enum LLMInferenceMode","name":"mode","type":"uint8"},{"internalType":"string","name":"modelCID","type":"string"},{"internalType":"string","name":"prompt","type":"string"},{"internalType":"uint32","name":"max_tokens","type":"uint32"},{"internalType":"string[]","name":"stop_sequence","type":"string[]"},{"internalType":"uint32","name":"temperature","type":"uint32"}],"indexed":false,"internalType":"struct LLMCompletionRequest","name":"request","type":"tuple"},{"components":[{"internalType":"string","name":"answer","type":"string"}],"indexed":false,"internalType":"struct LLMCompletionResponse","name":"response","type":"tuple"}],"name":"LLMCompletionEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"inferenceID","type":"string"},{"components":[{"internalType":"enum ModelInferenceMode","name":"mode","type":"uint8"},{"internalType":"string","name":"modelCID","type":"string"},{"components":[{"components":[{"internalType":"string","name":"name","type":"string"},{"components":[{"internalType":"int128","name":"value","type":"int128"},{"internalType":"int128","name":"decimals","type":"int128"}],"internalType":"struct TensorLib.Number[]","name":"values","type":"tuple[]"},{"internalType":"uint32[]","name":"shape","type":"uint32[]"}],"internalType":"struct TensorLib.MultiDimensionalNumberTensor[]","name":"numbers","type":"tuple[]"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string[]","name":"values","type":"string[]"}],"internalType":"struct TensorLib.StringTensor[]","name":"strings","type":"tuple[]"}],"internalType":"struct ModelInput","name":"input","type":"tuple"}],"indexed":false,"internalType":"struct ModelInferenceRequest","name":"request","type":"tuple"},{"components":[{"components":[{"internalType":"string","name":"name","type":"string"},{"components":[{"internalType":"int128","name":"value","type":"int128"},{"internalType":"int128","name":"decimals","type":"int128"}],"internalType":"struct TensorLib.Number[]","name":"values","type":"tuple[]"},{"internalType":"uint32[]","name":"shape","type":"uint32[]"}],"internalType":"struct TensorLib.MultiDimensionalNumberTensor[]","name":"numbers","type":"tuple[]"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string[]","name":"values","type":"string[]"}],"internalType":"struct TensorLib.StringTensor[]","name":"strings","type":"tuple[]"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"value","type":"string"}],"internalType":"struct TensorLib.JsonScalar[]","name":"jsons","type":"tuple[]"},{"internalType":"bool","name":"is_simulation_result","type":"bool"}],"indexed":false,"internalType":"struct ModelOutput","name":"response","type":"tuple"}],"name":"ModelInferenceEvent","type":"event"},{"inputs":[{"components":[{"internalType":"enum LLMInferenceMode","name":"mode","type":"uint8"},{"internalType":"string","name":"modelCID","type":"string"},{"components":[{"internalType":"string","name":"role","type":"string"},{"internalType":"string","name":"content","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"tool_call_id","type":"string"},{"components":[{"internalType":"string","name":"id","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"arguments","type":"string"}],"internalType":"struct ToolCall[]","name":"tool_calls","type":"tuple[]"}],"internalType":"struct ChatMessage[]","name":"messages","type":"tuple[]"},{"components":[{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"parameters","type":"string"}],"internalType":"struct ToolDefinition[]","name":"tools","type":"tuple[]"},{"internalType":"string","name":"tool_choice","type":"string"},{"internalType":"uint32","name":"max_tokens","type":"uint32"},{"internalType":"string[]","name":"stop_sequence","type":"string[]"},{"internalType":"uint32","name":"temperature","type":"uint32"}],"internalType":"struct LLMChatRequest","name":"request","type":"tuple"}],"name":"runLLMChat","outputs":[{"components":[{"internalType":"string","name":"finish_reason","type":"string"},{"components":[{"internalType":"string","name":"role","type":"string"},{"internalType":"string","name":"content","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"tool_call_id","type":"string"},{"components":[{"internalType":"string","name":"id","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"arguments","type":"string"}],"internalType":"struct ToolCall[]","name":"tool_calls","type":"tuple[]"}],"internalType":"struct ChatMessage","name":"message","type":"tuple"}],"internalType":"struct LLMChatResponse","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"enum LLMInferenceMode","name":"mode","type":"uint8"},{"internalType":"string","name":"modelCID","type":"string"},{"internalType":"string","name":"prompt","type":"string"},{"internalType":"uint32","name":"max_tokens","type":"uint32"},{"internalType":"string[]","name":"stop_sequence","type":"string[]"},{"internalType":"uint32","name":"temperature","type":"uint32"}],"internalType":"struct LLMCompletionRequest","name":"request","type":"tuple"}],"name":"runLLMCompletion","outputs":[{"components":[{"internalType":"string","name":"answer","type":"string"}],"internalType":"struct LLMCompletionResponse","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"enum ModelInferenceMode","name":"mode","type":"uint8"},{"internalType":"string","name":"modelCID","type":"string"},{"components":[{"components":[{"internalType":"string","name":"name","type":"string"},{"components":[{"internalType":"int128","name":"value","type":"int128"},{"internalType":"int128","name":"decimals","type":"int128"}],"internalType":"struct TensorLib.Number[]","name":"values","type":"tuple[]"},{"internalType":"uint32[]","name":"shape","type":"uint32[]"}],"internalType":"struct TensorLib.MultiDimensionalNumberTensor[]","name":"numbers","type":"tuple[]"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string[]","name":"values","type":"string[]"}],"internalType":"struct TensorLib.StringTensor[]","name":"strings","type":"tuple[]"}],"internalType":"struct ModelInput","name":"input","type":"tuple"}],"internalType":"struct ModelInferenceRequest","name":"request","type":"tuple"}],"name":"runModelInference","outputs":[{"components":[{"components":[{"internalType":"string","name":"name","type":"string"},{"components":[{"internalType":"int128","name":"value","type":"int128"},{"internalType":"int128","name":"decimals","type":"int128"}],"internalType":"struct TensorLib.Number[]","name":"values","type":"tuple[]"},{"internalType":"uint32[]","name":"shape","type":"uint32[]"}],"internalType":"struct TensorLib.MultiDimensionalNumberTensor[]","name":"numbers","type":"tuple[]"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string[]","name":"values","type":"string[]"}],"internalType":"struct TensorLib.StringTensor[]","name":"strings","type":"tuple[]"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"value","type":"string"}],"internalType":"struct TensorLib.JsonScalar[]","name":"jsons","type":"tuple[]"},{"internalType":"bool","name":"is_simulation_result","type":"bool"}],"internalType":"struct ModelOutput","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"}]
|
|
@@ -17,6 +17,7 @@ from .defaults import (
|
|
|
17
17
|
DEFAULT_INFERENCE_CONTRACT_ADDRESS,
|
|
18
18
|
DEFAULT_OG_FAUCET_URL,
|
|
19
19
|
DEFAULT_RPC_URL,
|
|
20
|
+
DEFAULT_API_URL,
|
|
20
21
|
)
|
|
21
22
|
from .types import InferenceMode, LlmInferenceMode, LLM, TEE_LLM
|
|
22
23
|
|
|
@@ -132,6 +133,7 @@ def cli(ctx):
|
|
|
132
133
|
ctx.obj["client"] = Client(
|
|
133
134
|
private_key=ctx.obj["private_key"],
|
|
134
135
|
rpc_url=DEFAULT_RPC_URL,
|
|
136
|
+
api_url=DEFAULT_API_URL,
|
|
135
137
|
contract_address=DEFAULT_INFERENCE_CONTRACT_ADDRESS,
|
|
136
138
|
email=ctx.obj.get("email"),
|
|
137
139
|
password=ctx.obj.get("password"),
|
|
@@ -2,6 +2,7 @@ import json
|
|
|
2
2
|
import logging
|
|
3
3
|
import os
|
|
4
4
|
import time
|
|
5
|
+
import base64
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
from typing import Any, Dict, List, Optional, Union, Callable
|
|
7
8
|
|
|
@@ -12,6 +13,7 @@ from eth_account.account import LocalAccount
|
|
|
12
13
|
from web3 import Web3
|
|
13
14
|
from web3.exceptions import ContractLogicError
|
|
14
15
|
from web3.logs import DISCARD
|
|
16
|
+
import urllib.parse
|
|
15
17
|
|
|
16
18
|
from .exceptions import OpenGradientError
|
|
17
19
|
from .proto import infer_pb2, infer_pb2_grpc
|
|
@@ -49,6 +51,7 @@ REGULAR_TX_TIMEOUT = 30
|
|
|
49
51
|
DEFAULT_MAX_RETRY = 5
|
|
50
52
|
DEFAULT_RETRY_DELAY_SEC = 1
|
|
51
53
|
|
|
54
|
+
PRECOMPILE_CONTRACT_ADDRESS = "0x00000000000000000000000000000000000000F4"
|
|
52
55
|
|
|
53
56
|
class Client:
|
|
54
57
|
_inference_hub_contract_address: str
|
|
@@ -56,9 +59,10 @@ class Client:
|
|
|
56
59
|
_wallet_account: LocalAccount
|
|
57
60
|
|
|
58
61
|
_hub_user: Optional[Dict]
|
|
62
|
+
_api_url: str
|
|
59
63
|
_inference_abi: Dict
|
|
60
|
-
|
|
61
|
-
def __init__(self, private_key: str, rpc_url: str, contract_address: str, email: Optional[str], password: Optional[str]):
|
|
64
|
+
_precompile_abi: Dict
|
|
65
|
+
def __init__(self, private_key: str, rpc_url: str, api_url: str, contract_address: str, email: Optional[str], password: Optional[str]):
|
|
62
66
|
"""
|
|
63
67
|
Initialize the Client with private key, RPC URL, and contract address.
|
|
64
68
|
|
|
@@ -71,12 +75,17 @@ class Client:
|
|
|
71
75
|
"""
|
|
72
76
|
self._inference_hub_contract_address = contract_address
|
|
73
77
|
self._blockchain = Web3(Web3.HTTPProvider(rpc_url))
|
|
78
|
+
self._api_url = api_url
|
|
74
79
|
self._wallet_account = self._blockchain.eth.account.from_key(private_key)
|
|
75
80
|
|
|
76
81
|
abi_path = Path(__file__).parent / "abi" / "inference.abi"
|
|
77
82
|
with open(abi_path, "r") as abi_file:
|
|
78
83
|
self._inference_abi = json.load(abi_file)
|
|
79
84
|
|
|
85
|
+
abi_path = Path(__file__).parent / "abi" / "InferencePrecompile.abi"
|
|
86
|
+
with open(abi_path, "r") as abi_file:
|
|
87
|
+
self._precompile_abi = json.load(abi_file)
|
|
88
|
+
|
|
80
89
|
if email is not None:
|
|
81
90
|
self._hub_user = self._login_to_hub(email, password)
|
|
82
91
|
else:
|
|
@@ -292,6 +301,7 @@ class Client:
|
|
|
292
301
|
|
|
293
302
|
def execute_transaction():
|
|
294
303
|
contract = self._blockchain.eth.contract(address=self._inference_hub_contract_address, abi=self._inference_abi)
|
|
304
|
+
precompile_contract = self._blockchain.eth.contract(address=PRECOMPILE_CONTRACT_ADDRESS, abi=self._precompile_abi)
|
|
295
305
|
|
|
296
306
|
inference_mode_uint8 = inference_mode.value
|
|
297
307
|
converted_model_input = convert_to_model_input(model_input)
|
|
@@ -305,6 +315,12 @@ class Client:
|
|
|
305
315
|
|
|
306
316
|
# TODO: This should return a ModelOutput class object
|
|
307
317
|
model_output = convert_to_model_output(parsed_logs[0]["args"])
|
|
318
|
+
if len(model_output) == 0:
|
|
319
|
+
# check inference directly from node
|
|
320
|
+
parsed_logs = precompile_contract.events.ModelInferenceEvent().process_receipt(tx_receipt, errors=DISCARD)
|
|
321
|
+
inference_id = parsed_logs[0]["args"]["inferenceID"]
|
|
322
|
+
inference_result = self._get_inference_result_from_node(inference_id, inference_mode)
|
|
323
|
+
model_output = convert_to_model_output(inference_result)
|
|
308
324
|
|
|
309
325
|
return InferenceResult(tx_hash.hex(), model_output)
|
|
310
326
|
|
|
@@ -956,6 +972,87 @@ class Client:
|
|
|
956
972
|
return [convert_array_to_model_output(result) for result in results]
|
|
957
973
|
|
|
958
974
|
|
|
975
|
+
def _get_inference_result_from_node(self, inference_id: str, inference_mode: InferenceMode) -> Dict:
|
|
976
|
+
"""
|
|
977
|
+
Get the inference result from node.
|
|
978
|
+
|
|
979
|
+
Args:
|
|
980
|
+
inference_id (str): Inference id for a inference request
|
|
981
|
+
|
|
982
|
+
Returns:
|
|
983
|
+
Dict: The inference result as returned by the node
|
|
984
|
+
|
|
985
|
+
Raises:
|
|
986
|
+
OpenGradientError: If the request fails or returns an error
|
|
987
|
+
"""
|
|
988
|
+
try:
|
|
989
|
+
encoded_id = urllib.parse.quote(inference_id, safe='')
|
|
990
|
+
url = f"{self._api_url}/artela-network/artela-rollkit/inference/tx/{encoded_id}"
|
|
991
|
+
|
|
992
|
+
response = requests.get(url)
|
|
993
|
+
if response.status_code == 200:
|
|
994
|
+
resp = response.json()
|
|
995
|
+
inference_result = resp.get("inference_results", {})
|
|
996
|
+
if inference_result:
|
|
997
|
+
decoded_bytes = base64.b64decode(inference_result[0])
|
|
998
|
+
decoded_string = decoded_bytes.decode('utf-8')
|
|
999
|
+
output = json.loads(decoded_string).get("InferenceResult",{})
|
|
1000
|
+
if output is None:
|
|
1001
|
+
raise OpenGradientError("Missing InferenceResult in inference output")
|
|
1002
|
+
|
|
1003
|
+
match inference_mode:
|
|
1004
|
+
case InferenceMode.VANILLA:
|
|
1005
|
+
if "VanillaResult" not in output:
|
|
1006
|
+
raise OpenGradientError("Missing VanillaResult in inference output")
|
|
1007
|
+
if "model_output" not in output["VanillaResult"]:
|
|
1008
|
+
raise OpenGradientError("Missing model_output in VanillaResult")
|
|
1009
|
+
return {
|
|
1010
|
+
"output": output["VanillaResult"]["model_output"]
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
case InferenceMode.TEE:
|
|
1014
|
+
if "TeeNodeResult" not in output:
|
|
1015
|
+
raise OpenGradientError("Missing TeeNodeResult in inference output")
|
|
1016
|
+
if "Response" not in output["TeeNodeResult"]:
|
|
1017
|
+
raise OpenGradientError("Missing Response in TeeNodeResult")
|
|
1018
|
+
if "VanillaResponse" in output["TeeNodeResult"]["Response"]:
|
|
1019
|
+
if "model_output" not in output["TeeNodeResult"]["Response"]["VanillaResponse"]:
|
|
1020
|
+
raise OpenGradientError("Missing model_output in VanillaResponse")
|
|
1021
|
+
return {
|
|
1022
|
+
"output": output["TeeNodeResult"]["Response"]["VanillaResponse"]["model_output"]
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
else:
|
|
1026
|
+
raise OpenGradientError("Missing VanillaResponse in TeeNodeResult Response")
|
|
1027
|
+
|
|
1028
|
+
case InferenceMode.ZKML:
|
|
1029
|
+
if "ZkmlResult" not in output:
|
|
1030
|
+
raise OpenGradientError("Missing ZkmlResult in inference output")
|
|
1031
|
+
if "model_output" not in output["ZkmlResult"]:
|
|
1032
|
+
raise OpenGradientError("Missing model_output in ZkmlResult")
|
|
1033
|
+
return {
|
|
1034
|
+
"output": output["ZkmlResult"]["model_output"]
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
case _:
|
|
1038
|
+
raise OpenGradientError(f"Invalid inference mode: {inference_mode}")
|
|
1039
|
+
else:
|
|
1040
|
+
return None
|
|
1041
|
+
|
|
1042
|
+
else:
|
|
1043
|
+
error_message = f"Failed to get inference result: HTTP {response.status_code}"
|
|
1044
|
+
if response.text:
|
|
1045
|
+
error_message += f" - {response.text}"
|
|
1046
|
+
logging.error(error_message)
|
|
1047
|
+
raise OpenGradientError(error_message)
|
|
1048
|
+
|
|
1049
|
+
except requests.RequestException as e:
|
|
1050
|
+
logging.error(f"Request exception when getting inference result: {str(e)}")
|
|
1051
|
+
raise OpenGradientError(f"Failed to get inference result: {str(e)}")
|
|
1052
|
+
except Exception as e:
|
|
1053
|
+
logging.error(f"Unexpected error when getting inference result: {str(e)}", exc_info=True)
|
|
1054
|
+
raise OpenGradientError(f"Failed to get inference result: {str(e)}")
|
|
1055
|
+
|
|
959
1056
|
def run_with_retry(txn_function: Callable, max_retries=DEFAULT_MAX_RETRY, retry_delay=DEFAULT_RETRY_DELAY_SEC):
|
|
960
1057
|
"""
|
|
961
1058
|
Execute a blockchain transaction with retry logic.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Default variables
|
|
2
2
|
DEFAULT_RPC_URL = "https://eth-devnet.opengradient.ai"
|
|
3
|
+
DEFAULT_API_URL = "https://sdk-devnet.opengradient.ai"
|
|
3
4
|
DEFAULT_OG_FAUCET_URL = "https://faucet.opengradient.ai/?address="
|
|
4
5
|
DEFAULT_HUB_SIGNUP_URL = "https://hub.opengradient.ai/signup"
|
|
5
6
|
DEFAULT_INFERENCE_CONTRACT_ADDRESS = "0x8383C9bD7462F12Eb996DD02F78234C0421A6FaE"
|
|
6
7
|
DEFAULT_SCHEDULER_ADDRESS = "0x7179724De4e7FF9271FA40C0337c7f90C0508eF6"
|
|
7
8
|
DEFAULT_BLOCKCHAIN_EXPLORER = "https://explorer.opengradient.ai/tx/"
|
|
8
9
|
DEFAULT_IMAGE_GEN_HOST = "18.217.25.69"
|
|
9
|
-
DEFAULT_IMAGE_GEN_PORT = 5125
|
|
10
|
+
DEFAULT_IMAGE_GEN_PORT = 5125
|
|
@@ -19,7 +19,7 @@ from langchain_core.runnables import Runnable
|
|
|
19
19
|
from langchain_core.language_models.base import LanguageModelInput
|
|
20
20
|
|
|
21
21
|
from opengradient import Client, LlmInferenceMode, LLM
|
|
22
|
-
from opengradient.defaults import DEFAULT_INFERENCE_CONTRACT_ADDRESS, DEFAULT_RPC_URL
|
|
22
|
+
from opengradient.defaults import DEFAULT_INFERENCE_CONTRACT_ADDRESS, DEFAULT_RPC_URL, DEFAULT_API_URL
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class OpenGradientChatModel(BaseChatModel):
|
|
@@ -34,7 +34,7 @@ class OpenGradientChatModel(BaseChatModel):
|
|
|
34
34
|
super().__init__()
|
|
35
35
|
|
|
36
36
|
self._client = Client(
|
|
37
|
-
private_key=private_key, rpc_url=DEFAULT_RPC_URL, contract_address=DEFAULT_INFERENCE_CONTRACT_ADDRESS, email=None, password=None
|
|
37
|
+
private_key=private_key, rpc_url=DEFAULT_RPC_URL, api_url=DEFAULT_API_URL, contract_address=DEFAULT_INFERENCE_CONTRACT_ADDRESS, email=None, password=None
|
|
38
38
|
)
|
|
39
39
|
self._model_cid = model_cid
|
|
40
40
|
self._max_tokens = max_tokens
|
|
@@ -122,24 +122,18 @@ def convert_to_model_output(event_data: AttributeDict) -> Dict[str, np.ndarray]:
|
|
|
122
122
|
We need to reshape each output array using the shape parameter in order to get the array
|
|
123
123
|
back into its original shape.
|
|
124
124
|
"""
|
|
125
|
-
logging.debug(f"Parsing event data: {event_data}")
|
|
126
|
-
|
|
127
125
|
output_dict = {}
|
|
128
|
-
|
|
129
126
|
output = event_data.get("output", {})
|
|
130
|
-
logging.debug(f"Output data: {output}")
|
|
131
127
|
|
|
132
|
-
if isinstance(output, AttributeDict):
|
|
133
|
-
# Parse numbers
|
|
128
|
+
if isinstance(output, (AttributeDict, dict)):
|
|
134
129
|
for tensor in output.get("numbers", []):
|
|
135
|
-
|
|
136
|
-
if isinstance(tensor, AttributeDict):
|
|
130
|
+
if isinstance(tensor, (AttributeDict, dict)):
|
|
137
131
|
name = tensor.get("name")
|
|
138
132
|
shape = tensor.get("shape")
|
|
139
133
|
values = []
|
|
140
134
|
# Convert from fixed point back into np.float32
|
|
141
135
|
for v in tensor.get("values", []):
|
|
142
|
-
if isinstance(v, AttributeDict):
|
|
136
|
+
if isinstance(v, (AttributeDict, dict)):
|
|
143
137
|
values.append(convert_to_float32(value=int(v.get("value")), decimals=int(v.get("decimals"))))
|
|
144
138
|
else:
|
|
145
139
|
logging.warning(f"Unexpected number type: {type(v)}")
|
|
@@ -149,8 +143,7 @@ def convert_to_model_output(event_data: AttributeDict) -> Dict[str, np.ndarray]:
|
|
|
149
143
|
|
|
150
144
|
# Parse strings
|
|
151
145
|
for tensor in output.get("strings", []):
|
|
152
|
-
|
|
153
|
-
if isinstance(tensor, AttributeDict):
|
|
146
|
+
if isinstance(tensor, (AttributeDict, dict)):
|
|
154
147
|
name = tensor.get("name")
|
|
155
148
|
shape = tensor.get("shape")
|
|
156
149
|
values = tensor.get("values", [])
|
|
@@ -160,8 +153,7 @@ def convert_to_model_output(event_data: AttributeDict) -> Dict[str, np.ndarray]:
|
|
|
160
153
|
|
|
161
154
|
# Parse JSON dicts
|
|
162
155
|
for tensor in output.get("jsons", []):
|
|
163
|
-
|
|
164
|
-
if isinstance(tensor, AttributeDict):
|
|
156
|
+
if isinstance(tensor, (AttributeDict, dict)):
|
|
165
157
|
name = tensor.get("name")
|
|
166
158
|
value = tensor.get("value")
|
|
167
159
|
output_dict[name] = np.array(json.loads(value))
|
|
@@ -172,7 +164,6 @@ def convert_to_model_output(event_data: AttributeDict) -> Dict[str, np.ndarray]:
|
|
|
172
164
|
logging.warning(f"Unexpected output type: {type(output)}")
|
|
173
165
|
|
|
174
166
|
logging.debug(f"Parsed output: {output_dict}")
|
|
175
|
-
|
|
176
167
|
return output_dict
|
|
177
168
|
|
|
178
169
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opengradient
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.13
|
|
4
4
|
Summary: Python SDK for OpenGradient decentralized model management & inference services
|
|
5
5
|
Author-email: OpenGradient <oliver@opengradient.ai>
|
|
6
6
|
License: MIT License
|
|
@@ -35,10 +35,8 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
35
35
|
Requires-Python: >=3.10
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
37
37
|
License-File: LICENSE
|
|
38
|
-
Requires-Dist: eth-
|
|
39
|
-
Requires-Dist:
|
|
40
|
-
Requires-Dist: web3>=6.11
|
|
41
|
-
Requires-Dist: websockets>=14.1
|
|
38
|
+
Requires-Dist: eth-account>=0.13.4
|
|
39
|
+
Requires-Dist: web3>=7.3.0
|
|
42
40
|
Requires-Dist: click>=8.1.7
|
|
43
41
|
Requires-Dist: firebase-rest-api>=1.11.0
|
|
44
42
|
Requires-Dist: grpcio>=1.66.2
|
|
@@ -15,6 +15,7 @@ src/opengradient.egg-info/dependency_links.txt
|
|
|
15
15
|
src/opengradient.egg-info/entry_points.txt
|
|
16
16
|
src/opengradient.egg-info/requires.txt
|
|
17
17
|
src/opengradient.egg-info/top_level.txt
|
|
18
|
+
src/opengradient/abi/InferencePrecompile.abi
|
|
18
19
|
src/opengradient/abi/PriceHistoryInference.abi
|
|
19
20
|
src/opengradient/abi/WorkflowScheduler.abi
|
|
20
21
|
src/opengradient/abi/inference.abi
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/abi/PriceHistoryInference.abi
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/alphasense/read_workflow_tool.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/bin/PriceHistoryInference.bin
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient/workflow_models/workflow_models.py
RENAMED
|
File without changes
|
{opengradient-0.4.12b1 → opengradient-0.4.13}/src/opengradient.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|