diff --git a/Makefile b/Makefile index 465e0d3..161f312 100644 --- a/Makefile +++ b/Makefile @@ -68,28 +68,22 @@ completion: --prompt "Hello, how are you?" \ --max-tokens 50 -chat-og-evm: +chat: python -m opengradient.cli chat \ --model $(MODEL) \ --messages '[{"role":"user","content":"Tell me a fun fact"}]' \ - --max-tokens 150 --network og-evm - -chat-base-testnet: - python -m opengradient.cli chat \ - --model $(MODEL) \ - --messages '[{"role":"user","content":"Tell me a fun fact"}]' \ - --max-tokens 150 --network base-testnet + --max-tokens 150 chat-stream: python -m opengradient.cli chat \ - --model $(MODEL) --mode TEE \ + --model $(MODEL) \ --messages '[{"role":"user","content":"Tell me a short story"}]' \ --max-tokens 250 \ --stream chat-tool: python -m opengradient.cli chat \ - --model $(MODEL) --mode TEE \ + --model $(MODEL) \ --messages '[{"role":"user","content":"What is the weather in Tokyo?"}]' \ --tools '[{"type":"function","function":{"name":"get_weather","description":"Get weather for a location","parameters":{"type":"object","properties":{"location":{"type":"string"},"unit":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["location"]}}}]' \ --max-tokens 100 \ diff --git a/docs/opengradient/client/client.md b/docs/opengradient/client/client.md index 98da12a..2f295f7 100644 --- a/docs/opengradient/client/client.md +++ b/docs/opengradient/client/client.md @@ -21,7 +21,7 @@ blockchain private key and optional Model Hub credentials. #### 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://llmogevm.opengradient.ai', og_llm_streaming_server_url: Optional[str] = 'https://llmogevm.opengradient.ai') +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') ``` **Arguments** diff --git a/docs/opengradient/client/index.md b/docs/opengradient/client/index.md index 54d0b3d..19a04b0 100644 --- a/docs/opengradient/client/index.md +++ b/docs/opengradient/client/index.md @@ -68,7 +68,7 @@ blockchain private key and optional Model Hub credentials. #### 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://llmogevm.opengradient.ai', og_llm_streaming_server_url: Optional[str] = 'https://llmogevm.opengradient.ai') +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') ``` **Arguments** diff --git a/docs/opengradient/index.md b/docs/opengradient/index.md index 9395fb0..8d11e5b 100644 --- a/docs/opengradient/index.md +++ b/docs/opengradient/index.md @@ -127,7 +127,7 @@ blockchain private key and optional Model Hub credentials. #### 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://llmogevm.opengradient.ai', og_llm_streaming_server_url: Optional[str] = 'https://llmogevm.opengradient.ai') +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') ``` **Arguments** diff --git a/examples/run_x402_llm.py b/examples/run_x402_llm.py index 1156c3d..d5f3f0c 100644 --- a/examples/run_x402_llm.py +++ b/examples/run_x402_llm.py @@ -14,13 +14,11 @@ import opengradient as og from x402_permit2 import check_permit2_approval -network = "base-testnet" - client = og.Client( private_key=os.environ.get("OG_PRIVATE_KEY"), ) -check_permit2_approval(client.wallet_address, network) +check_permit2_approval(client.wallet_address) messages = [ {"role": "user", "content": "What is Python?"}, @@ -29,6 +27,6 @@ ] result = client.llm.chat( - model=og.TEE_LLM.GPT_4_1_2025_04_14, messages=messages, x402_settlement_mode=og.x402SettlementMode.SETTLE_METADATA, network=network + model=og.TEE_LLM.GPT_4_1_2025_04_14, messages=messages, x402_settlement_mode=og.x402SettlementMode.SETTLE_METADATA ) print(f"Response: {result.chat_output['content']}") diff --git a/examples/run_x402_llm_stream.py b/examples/run_x402_llm_stream.py index cee1602..3b7d6da 100644 --- a/examples/run_x402_llm_stream.py +++ b/examples/run_x402_llm_stream.py @@ -3,13 +3,11 @@ import opengradient as og from x402_permit2 import check_permit2_approval -network = "base-testnet" - client = og.Client( private_key=os.environ.get("OG_PRIVATE_KEY"), ) -check_permit2_approval(client.wallet_address, network) +check_permit2_approval(client.wallet_address) messages = [ {"role": "user", "content": "What is Python?"}, @@ -23,7 +21,6 @@ x402_settlement_mode=og.x402SettlementMode.SETTLE_METADATA, stream=True, max_tokens=300, - network=network, ) for chunk in stream: diff --git a/examples/x402_permit2.py b/examples/x402_permit2.py index 070fb6e..6d921d8 100644 --- a/examples/x402_permit2.py +++ b/examples/x402_permit2.py @@ -8,7 +8,6 @@ BASE_OPG_ADDRESS = "0x240b09731D96979f50B2C649C9CE10FcF9C7987F" BASE_SEPOLIA_RPC = "https://sepolia.base.org" -BASE_TESTNET = "base-testnet" MAX_UINT256 = (1 << 256) - 1 ERC20_ABI = [ @@ -48,11 +47,8 @@ def get_permit2_allowance(client_address: str) -> int: ).call() -def check_permit2_approval(client_address: str, network: str) -> None: +def check_permit2_approval(client_address: str) -> None: """Raise an error if Permit2 approval is missing for base-testnet.""" - if network != BASE_TESTNET: - return - allowance = get_permit2_allowance(client_address) print(f"Current OPG Permit2 allowance: {allowance}") diff --git a/pyproject.toml b/pyproject.toml index 00d1148..ffca660 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,8 +27,7 @@ dependencies = [ "langchain>=0.3.7", "openai>=1.58.1", "pydantic>=2.9.2", - "og-test-x402==0.0.9", - "og-test-v2-x402==0.0.6" + "og-test-v2-x402==0.0.9" ] [project.scripts] diff --git a/requirements.txt b/requirements.txt index 6bb305c..7a51cd1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,5 +7,4 @@ requests>=2.32.3 langchain>=0.3.7 openai>=1.58.1 pydantic>=2.9.2 -og-test-x402==0.0.9 -og-test-v2-x402==0.0.6 \ No newline at end of file +og-test-v2-x402==0.0.9 \ No newline at end of file diff --git a/src/opengradient/cli.py b/src/opengradient/cli.py index 7b8c208..72ffec5 100644 --- a/src/opengradient/cli.py +++ b/src/opengradient/cli.py @@ -20,7 +20,7 @@ DEFAULT_OG_FAUCET_URL, DEFAULT_RPC_URL, ) -from .types import InferenceMode, x402Network, x402SettlementMode +from .types import InferenceMode, x402SettlementMode OG_CONFIG_FILE = Path.home() / ".opengradient_config.json" @@ -74,11 +74,6 @@ def convert(self, value, param, ctx): "settle-metadata": x402SettlementMode.SETTLE_METADATA, } -x402Networks = { - "og-evm": x402Network.OG_EVM, - "base-testnet": x402Network.BASE_TESTNET, -} - def initialize_config(ctx): """Interactively initialize OpenGradient config""" @@ -466,12 +461,6 @@ def print_llm_completion_result(model_cid, tx_hash, llm_output, is_vanilla=True) default="settle-batch", help="Settlement mode for x402 payments: settle (hashes only), settle-batch (batched, default), settle-metadata (full data)", ) -@click.option( - "--network", - type=click.Choice(x402Networks.keys()), - default="og-evm", - help="x402 network to use for TEE chat payments: og-evm (default) or base-testnet", -) @click.option("--stream", is_flag=True, default=False, help="Stream the output from the LLM") @click.pass_context def chat( @@ -486,7 +475,6 @@ def chat( tools_file: Optional[Path], tool_choice: Optional[str], x402_settlement_mode: Optional[str], - network: str, stream: bool, ): """ @@ -573,7 +561,6 @@ def chat( tools=parsed_tools, tool_choice=tool_choice, x402_settlement_mode=x402SettlementModes[x402_settlement_mode], - network=x402Networks[network], stream=stream, ) diff --git a/src/opengradient/client/llm.py b/src/opengradient/client/llm.py index cc32d1a..95c4c3d 100644 --- a/src/opengradient/client/llm.py +++ b/src/opengradient/client/llm.py @@ -6,9 +6,6 @@ import httpx from eth_account.account import LocalAccount -from x402.clients.base import x402Client -from x402.clients.httpx import x402HttpxClient - from x402v2 import x402Client as x402Clientv2 from x402v2.http import x402HTTPClient as x402HTTPClientv2 from x402v2.http.clients import x402HttpxClient as x402HttpxClientv2 @@ -19,10 +16,8 @@ from x402v2.mechanisms.evm.upto.register import register_upto_evm_client as register_upto_evm_clientv2 from eth_account import Account -from ..defaults import DEFAULT_NETWORK_FILTER, DEFAULT_OPENGRADIENT_V2_LLM_SERVER_URL -from ..types import TEE_LLM, StreamChunk, TextGenerationOutput, TextGenerationStream, x402SettlementMode, x402Network +from ..types import TEE_LLM, StreamChunk, TextGenerationOutput, TextGenerationStream, x402SettlementMode from .exceptions import OpenGradientError -from .x402_auth import X402Auth X402_PROCESSING_HASH_HEADER = "x-processing-hash" X402_PLACEHOLDER_API_KEY = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" @@ -61,15 +56,6 @@ def __init__(self, wallet_account: LocalAccount, og_llm_server_url: str, og_llm_ self._og_llm_server_url = og_llm_server_url self._og_llm_streaming_server_url = og_llm_streaming_server_url - def _og_payment_selector(self, accepts, network_filter=DEFAULT_NETWORK_FILTER, scheme_filter=None, max_value=None): - """Custom payment selector for OpenGradient network.""" - return x402Client.default_payment_requirements_selector( - accepts, - network_filter=network_filter, - scheme_filter=scheme_filter, - max_value=max_value, - ) - def completion( self, model: TEE_LLM, @@ -125,14 +111,13 @@ def _tee_llm_completion( Route completion request to OpenGradient TEE LLM server with x402 payments. """ - async def make_request(): + async def make_request_v2(): + x402_client = x402Clientv2() + register_exact_evm_clientv2(x402_client, EthAccountSignerv2(self._wallet_account), networks=[BASE_TESTNET_NETWORK]) + register_upto_evm_clientv2(x402_client, EthAccountSignerv2(self._wallet_account), networks=[BASE_TESTNET_NETWORK]) + # Security Fix: verify=True enabled - async with x402HttpxClient( - account=self._wallet_account, - base_url=self._og_llm_server_url, - payment_requirements_selector=self._og_payment_selector, - verify=True, - ) as client: + async with x402HttpxClientv2(x402_client) as client: headers = { "Content-Type": "application/json", "Authorization": f"Bearer {X402_PLACEHOLDER_API_KEY}", @@ -150,7 +135,7 @@ async def make_request(): payload["stop"] = stop_sequence try: - response = await client.post("/v1/completions", json=payload, headers=headers, timeout=60) + response = await client.post(self._og_llm_server_url + "/v1/completions", json=payload, headers=headers, timeout=60) # Read the response content content = await response.aread() @@ -182,7 +167,6 @@ def chat( tool_choice: Optional[str] = None, x402_settlement_mode: Optional[x402SettlementMode] = x402SettlementMode.SETTLE_BATCH, stream: bool = False, - network: Optional[x402Network] = x402Network.OG_EVM, ) -> Union[TextGenerationOutput, TextGenerationStream]: """ Perform inference on an LLM model using chat via TEE. @@ -221,7 +205,6 @@ def chat( tools=tools, tool_choice=tool_choice, x402_settlement_mode=x402_settlement_mode, - network=network, ) else: # Non-streaming @@ -234,7 +217,6 @@ def chat( tools=tools, tool_choice=tool_choice, x402_settlement_mode=x402_settlement_mode, - network=network, ) def _tee_llm_chat( @@ -247,61 +229,11 @@ def _tee_llm_chat( tools: Optional[List[Dict]] = None, tool_choice: Optional[str] = None, x402_settlement_mode: x402SettlementMode = x402SettlementMode.SETTLE_BATCH, - network: Optional[x402Network] = x402Network.OG_EVM, ) -> TextGenerationOutput: """ Route chat request to OpenGradient TEE LLM server with x402 payments. """ - async def make_request(): - # Security Fix: verify=True enabled - async with x402HttpxClient( - account=self._wallet_account, - base_url=self._og_llm_server_url, - payment_requirements_selector=self._og_payment_selector, - verify=True, - ) as client: - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {X402_PLACEHOLDER_API_KEY}", - "X-SETTLEMENT-TYPE": x402_settlement_mode, - } - - payload = { - "model": model, - "messages": messages, - "max_tokens": max_tokens, - "temperature": temperature, - } - - if stop_sequence: - payload["stop"] = stop_sequence - - if tools: - payload["tools"] = tools - payload["tool_choice"] = tool_choice or "auto" - - try: - # Non-streaming with x402 - endpoint = "/v1/chat/completions" - response = await client.post(endpoint, json=payload, headers=headers, timeout=60) - - content = await response.aread() - result = json.loads(content.decode()) - - choices = result.get("choices") - if not choices: - raise OpenGradientError(f"Invalid response: 'choices' missing or empty in {result}") - - return TextGenerationOutput( - transaction_hash="external", - finish_reason=choices[0].get("finish_reason"), - chat_output=choices[0].get("message"), - ) - - except Exception as e: - raise OpenGradientError(f"TEE LLM chat request failed: {str(e)}") - async def make_request_v2(): x402_client = x402Clientv2() register_exact_evm_clientv2(x402_client, EthAccountSignerv2(self._wallet_account), networks=[BASE_TESTNET_NETWORK]) @@ -333,7 +265,7 @@ async def make_request_v2(): # Non-streaming with x402 endpoint = "/v1/chat/completions" response = await client.post( - DEFAULT_OPENGRADIENT_V2_LLM_SERVER_URL + endpoint, json=payload, headers=headers, timeout=60 + self._og_llm_server_url + endpoint, json=payload, headers=headers, timeout=60 ) content = await response.aread() @@ -353,12 +285,7 @@ async def make_request_v2(): raise OpenGradientError(f"TEE LLM chat request failed: {str(e)}") try: - if network == x402Network.OG_EVM: - return asyncio.run(make_request()) - elif network == x402Network.BASE_TESTNET: - return asyncio.run(make_request_v2()) - else: - raise OpenGradientError(f"Invalid network: {network}") + return asyncio.run(make_request_v2()) except OpenGradientError: raise except Exception as e: @@ -374,7 +301,6 @@ def _tee_llm_chat_stream_sync( tools: Optional[List[Dict]] = None, tool_choice: Optional[str] = None, x402_settlement_mode: x402SettlementMode = x402SettlementMode.SETTLE_BATCH, - network: Optional[x402Network] = x402Network.OG_EVM, ): """ Sync streaming using threading bridge - TRUE real-time streaming. @@ -406,7 +332,6 @@ async def _stream(): tools=tools, tool_choice=tool_choice, x402_settlement_mode=x402_settlement_mode, - network=network, ): queue.put(chunk) # Put chunk immediately except Exception as e: @@ -460,7 +385,6 @@ async def _tee_llm_chat_stream_async( tools: Optional[List[Dict]] = None, tool_choice: Optional[str] = None, x402_settlement_mode: x402SettlementMode = x402SettlementMode.SETTLE_BATCH, - network: Optional[x402Network] = x402Network.OG_EVM, ): """ Internal async streaming implementation for TEE LLM with x402 payments. @@ -525,41 +449,19 @@ async def _parse_sse_response(response) -> AsyncGenerator[StreamChunk, None]: except json.JSONDecodeError: continue - if network == x402Network.OG_EVM: - async with httpx.AsyncClient( - base_url=self._og_llm_streaming_server_url, - headers={"Authorization": f"Bearer {X402_PLACEHOLDER_API_KEY}"}, - timeout=TIMEOUT, - limits=LIMITS, - http2=False, - follow_redirects=False, - auth=X402Auth(account=self._wallet_account, network_filter=DEFAULT_NETWORK_FILTER), # type: ignore - verify=True, - ) as client: - async with client.stream( - "POST", - "/v1/chat/completions", - json=payload, - headers=headers, - ) as response: - async for parsed_chunk in _parse_sse_response(response): - yield parsed_chunk - - elif network == x402Network.BASE_TESTNET: - x402_client = x402Clientv2() - register_exact_evm_clientv2(x402_client, EthAccountSignerv2(self._wallet_account), networks=[BASE_TESTNET_NETWORK]) - register_upto_evm_clientv2(x402_client, EthAccountSignerv2(self._wallet_account), networks=[BASE_TESTNET_NETWORK]) + x402_client = x402Clientv2() + register_exact_evm_clientv2(x402_client, EthAccountSignerv2(self._wallet_account), networks=[BASE_TESTNET_NETWORK]) + register_upto_evm_clientv2(x402_client, EthAccountSignerv2(self._wallet_account), networks=[BASE_TESTNET_NETWORK]) + + async with x402HttpxClientv2(x402_client) as client: + endpoint = "/v1/chat/completions" + async with client.stream( + "POST", + self._og_llm_streaming_server_url + endpoint, + json=payload, + headers=headers, + timeout=60, + ) as response: + async for parsed_chunk in _parse_sse_response(response): + yield parsed_chunk - async with x402HttpxClientv2(x402_client) as client: - endpoint = "/v1/chat/completions" - async with client.stream( - "POST", - DEFAULT_OPENGRADIENT_V2_LLM_SERVER_URL + endpoint, - json=payload, - headers=headers, - timeout=60, - ) as response: - async for parsed_chunk in _parse_sse_response(response): - yield parsed_chunk - else: - raise OpenGradientError(f"Invalid network: {network}") diff --git a/src/opengradient/client/x402_auth.py b/src/opengradient/client/x402_auth.py deleted file mode 100644 index 9f54c14..0000000 --- a/src/opengradient/client/x402_auth.py +++ /dev/null @@ -1,95 +0,0 @@ -""" -X402 Authentication handler for httpx streaming requests. - -This module provides an httpx Auth class that handles x402 payment protocol -authentication for streaming responses. -""" - -import logging -import typing - -import httpx -from x402.clients.base import x402Client -from x402.types import PaymentRequirements, x402PaymentRequiredResponse - - -class X402Auth(httpx.Auth): - """ - httpx Auth handler for x402 payment protocol. - - This class implements the httpx Auth interface to handle 402 Payment Required - responses by automatically creating and attaching payment headers. - - Example: - async with httpx.AsyncClient(auth=X402Auth(account=wallet_account)) as client: - response = await client.get("https://api.example.com/paid-resource") - """ - - requires_response_body = True - - def __init__( - self, - account: typing.Any, - max_value: typing.Optional[int] = None, - payment_requirements_selector: typing.Optional[ - typing.Callable[ - [ - list[PaymentRequirements], - typing.Optional[str], - typing.Optional[str], - typing.Optional[int], - ], - PaymentRequirements, - ] - ] = None, - network_filter: typing.Optional[str] = None, - ): - """ - Initialize X402Auth with an Ethereum account for signing payments. - - Args: - account: eth_account LocalAccount instance for signing payments - max_value: Optional maximum allowed payment amount in base units - network_filter: Optional network filter for selecting payment requirements - scheme_filter: Optional scheme filter for selecting payment requirements - """ - self.x402_client = x402Client( - account, - max_value=max_value, - payment_requirements_selector=payment_requirements_selector, # type: ignore - ) - self.network_filter = network_filter - - async def async_auth_flow(self, request: httpx.Request) -> typing.AsyncGenerator[httpx.Request, httpx.Response]: - """ - Handle authentication flow for x402 payment protocol. - - Args: - request: httpx Request object to be authenticated - - Yields: - httpx Request object with authentication headers attached - """ - response = yield request - - if response.status_code == 402: - try: - await response.aread() - data = response.json() - - payment_response = x402PaymentRequiredResponse(**data) - - selected_requirements = self.x402_client.select_payment_requirements( - payment_response.accepts, - self.network_filter, - ) - - payment_header = self.x402_client.create_payment_header(selected_requirements, payment_response.x402_version) - - request.headers["X-Payment"] = payment_header - request.headers["Access-Control-Expose-Headers"] = "X-Payment-Response" - yield request - - except Exception as e: - logging.error(f"X402Auth: Error handling payment: {e}") - return diff --git a/src/opengradient/defaults.py b/src/opengradient/defaults.py index 143aee0..fcd97e5 100644 --- a/src/opengradient/defaults.py +++ b/src/opengradient/defaults.py @@ -6,8 +6,6 @@ DEFAULT_INFERENCE_CONTRACT_ADDRESS = "0x8383C9bD7462F12Eb996DD02F78234C0421A6FaE" DEFAULT_SCHEDULER_ADDRESS = "0x7179724De4e7FF9271FA40C0337c7f90C0508eF6" DEFAULT_BLOCKCHAIN_EXPLORER = "https://explorer.opengradient.ai/tx/" -DEFAULT_OPENGRADIENT_LLM_SERVER_URL = "https://llmogevm.opengradient.ai" -DEFAULT_OPENGRADIENT_LLM_STREAMING_SERVER_URL = "https://llmogevm.opengradient.ai" -DEFAULT_OPENGRADIENT_V2_LLM_SERVER_URL = "https://llm.opengradient.ai" -DEFAULT_OPENGRADIENT_V2_LLM_STREAMING_SERVER_URL = "https://llm.opengradient.ai" -DEFAULT_NETWORK_FILTER = "og-evm" +DEFAULT_OPENGRADIENT_LLM_SERVER_URL = "https://llm.opengradient.ai" +DEFAULT_OPENGRADIENT_LLM_STREAMING_SERVER_URL = "https://llm.opengradient.ai" + diff --git a/src/opengradient/types.py b/src/opengradient/types.py index 917e5e4..fa89c98 100644 --- a/src/opengradient/types.py +++ b/src/opengradient/types.py @@ -70,11 +70,6 @@ class CandleType(IntEnum): VOLUME = 4 -class x402Network(str, Enum): - OG_EVM = "og-evm" - BASE_TESTNET = "base-testnet" - - @dataclass class HistoricalInputQuery: base: str