Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BLCKCHN-141] optimise client params, sync it up with server #8

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
40 changes: 30 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,31 @@ from crypto_com_ai_agent_client import create_client

client = create_client({
'openAI': {
'apiKey': 'YOUR_OPEN_AI_API_KEY'
'apiKey': 'YOUR_OPEN_AI_API_KEY',
'model': 'gpt-4o' # Optional, defaults to 'gpt-4-turbo'
},
'chain': {
'id': 'CHAIN_ID', # e.g. 282 for the Cronos ZkEVM Testnet
'name': 'CHAIN_NAME',
'rpc': 'CHAIN_RPC_URL',
'chainId': 25, # e.g., for the Cronos EVM Mainnet
'explorerKeys': {
'cronosMainnetKey': 'CRONOS_MAINNET_API_KEY',
'cronosTestnetKey': 'CRONOS_TESTNET_API_KEY',
'cronosZkEvmKey': 'CRONOS_ZKEVM_API_KEY',
'cronosZkEvmTestnetKey': 'CRONOS_ZKEVM_TESTNET_API_KEY'
},
'explorer': {
'apiKey': 'EXPLORER_API_KEY',
}
'context': [], # Optional
'signerAppUrl': 'https://my-signer-app', # Optional
'customRPC': 'https://rpc.vvs.finance' # Optional, if not provided, the default RPC for the chainId will be used
})
```

### Sending a Query

```py
import json

def send_query(query):
try:
response = client.agent.generate_query(query)
print('Crypto.com AI Agent Response:', response)
print('Crypto.com AI Agent Response:', json.dumps(response.to_dict(), indent=2))
except Exception as e:
print(f"Error sending query: {str(e)}")

Expand All @@ -60,7 +65,22 @@ send_query("What is the latest block?")

### Client Methods

- `generate_query(query)`: Generates a query that is send to the Crypto.com AI Agent Service and returns a response.
- `generate_query(query)`: Generates a query that is sent to the Crypto.com AI Agent Service and returns a response.

### Configuration Options

- `openAI`: Dictionary containing OpenAI configuration
- `apiKey`: Your OpenAI API key
- `model`: (Optional) The model to use (defaults to 'gpt-4-turbo')
- `chainId`: The ID of the blockchain network (25 for Cronos EVM Mainnet, 338 for Cronos EVM Testnet, 388 for Cronos ZkEVM Mainnet, 282 for Cronos ZkEVM Testnet)
- `explorerKeys`: Dictionary of API keys for different explorers, ensure that the keys match the chainId
- `cronosMainnetKey`: (Optional) API key for Cronos Mainnet
- `cronosTestnetKey`: (Optional) API key for Cronos Testnet
- `cronosZkEvmKey`: (Optional) API key for Cronos ZkEVM
- `cronosZkEvmTestnetKey`: (Optional) API key for Cronos ZkEVM Testnet
- `signerAppUrl`: (Optional) URL for the signer app
- `context`: (Optional) List of context items for the query
- `customRPC`: (Optional) Custom RPC URL, if not provided, the default RPC for the chainId will be used

## Licensing

Expand Down
28 changes: 22 additions & 6 deletions crypto_com_ai_agent_client/client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Dict, List, Optional

from .integrations.cdc_ai_agent_api import generate_query
from .integrations.cdc_ai_agent_interface import CryptoComAiAgentResponse

Expand All @@ -7,7 +9,7 @@ class CryptoComAiAgentClient:
A client for interacting with the CDC AI Agent service.

This client manages configuration and provides methods to send queries to the CDC AI Agent service.

Attributes:
config (dict): The configuration for the client, including OpenAI API key, blockchain details, and explorer API key.
agent (Agent): An inner class providing the method to send queries to the AI agent.
Expand Down Expand Up @@ -56,21 +58,35 @@ def generate_query(self, query: str) -> CryptoComAiAgentResponse:
return generate_query(query, self.config)


def create_client(config: dict) -> CryptoComAiAgentClient:
def create_client(config: Dict[str, any]) -> CryptoComAiAgentClient:
"""
Creates a new client for interacting with the CDC AI Agent Service.

Args:
config (dict): Configuration for the client, including OpenAI API key, blockchain details, explorer API key.
config (Dict[str, any]): Configuration for the client, including:
openAI (dict): OpenAI configuration with apiKey and optional model
chainId (int): The chain ID
explorerKeys (dict): API keys for different explorers
signerAppUrl (str, optional): URL for the signer app
context (List[Dict], optional): Context for the query
customRPC (str, optional): Custom RPC URL

Returns:
CryptoComAiAgentClient: A new instance of the CDC AI Agent Client.

Example:
>>> config = {
>>> 'openAI': {'apiKey': 'YOUR_OPEN_AI_API_KEY'},
>>> 'chain': {'id': 282, 'name': 'Cronos Testnet', 'rpc': 'CHAIN_RPC_URL'},
>>> 'explorer': {'apiKey': 'EXPLORER_API_KEY'}
>>> 'openAI': {'apiKey': 'YOUR_OPEN_AI_API_KEY', 'model': 'gpt-4-turbo'},
>>> 'chainId': 25,
>>> 'explorerKeys': {
>>> 'cronosMainnetKey': 'CRONOS_MAINNET_API_KEY',
>>> 'cronosTestnetKey': 'CRONOS_TESTNET_API_KEY',
>>> 'cronosZkEvmKey': 'CRONOS_ZKEVM_API_KEY',
>>> 'cronosZkEvmTestnetKey': 'CRONOS_ZKEVM_TESTNET_API_KEY'
>>> },
>>> 'context': [],
>>> 'signerAppUrl': 'https://my-signer-app',
>>> 'customRPC': 'https://rpc.vvs.finance'
>>> }
>>> client = create_client(config)
>>> response = client.agent.generate_query('What is the latest block?')
Expand Down
32 changes: 22 additions & 10 deletions crypto_com_ai_agent_client/integrations/cdc_ai_agent_api.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import json
from typing import Any, Dict

import requests

from .cdc_ai_agent_interface import CryptoComAiAgentResponse


def generate_query(query: str, options: dict) -> CryptoComAiAgentResponse:
def generate_query(query: str, options: Dict[str, Any]) -> CryptoComAiAgentResponse:
"""
Sends a query to the CDC AI Agent service and returns the AI-generated response.

Args:
query (str): The query string to send to the CDC AI Agent service.
options (dict): A dictionary containing configuration options like OpenAI API key,
chain details, and explorer information.
options (Dict[str, Any]): A dictionary containing configuration options including OpenAI details,
chain ID, explorer keys, context, signer app URL, and custom RPC.

Returns:
CryptoComAiAgentResponse: A response object that contains the AI-generated message and related data.
Expand All @@ -19,25 +23,33 @@ def generate_query(query: str, options: dict) -> CryptoComAiAgentResponse:
or if there's an issue sending the request or parsing the response.

Example:
>>> config = {'openAI': {'apiKey': 'YOUR_OPEN_AI_API_KEY'},
'chain': {'id': 'CHAIN_ID, 'name': 'CHAIN_NAME', 'rpc': 'CHAIN_RPC_URL'},
'explorer': {'apiKey': 'EXPLORER_API_KEY'}}
>>> options = {
>>> 'openAI': {'apiKey': 'YOUR_OPEN_AI_API_KEY', 'model': 'gpt-4-turbo'},
>>> 'chainId': 25,
>>> 'explorerKeys': {
>>> 'cronosTestnetKey': 'CRONOS_TESTNET_API_KEY',
>>> 'cronosZkEvmKey': 'CRONOS_ZKEVM_API_KEY',
>>> 'cronosZkEvmTestnetKey': 'CRONOS_ZKEVM_TESTNET_API_KEY'
>>> },
>>> 'context': [],
>>> 'signerAppUrl': 'https://my-signer-app',
>>> 'customRPC': 'https://rpc.vvs.finance'
>>> }
>>> query = "What is the latest block?"
>>> response = generate_query(query, config)
>>> response = generate_query(query, options)
>>> print(response.result)
"""
url = 'https://ai-agent-api.crypto.com/api/v1/cdc-ai-agent-service/query'
payload = {'query': query, 'options': options}

try:
response = requests.post(url, json=payload)

if response.status_code not in [200, 201, 202]:
raise Exception(f"HTTP error! Status: {response.status_code}")
raise Exception(f"""Error with status code: {
response.status_code}, message: {json.dumps(response.json(), indent=2)}""")

data = response.json()
return CryptoComAiAgentResponse(**data)

except Exception as e:
print(f"[CryptoComAiAgent/generate_query] - {str(e)}")
raise Exception(f"Failed to generate response: {str(e)}")
129 changes: 105 additions & 24 deletions crypto_com_ai_agent_client/integrations/cdc_ai_agent_interface.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,136 @@
from typing import Any, Dict
from enum import Enum
from typing import Any, Dict, List, Optional


class Role(Enum):
"""
Enum respresenting the role of a QueryContext
"""
USER = "user"
ASSISTANT = "assistant"
SYSTEM = "system"


class QueryContext:
"""
A class representing the context within a CryptoComAiAgentResponse.

Attributes:
role (Role): The role of the context (e.g., system, user, assistant).
content (str): The content of the context.
"""

def __init__(self, role: Role, content: str):
self.role = role
self.content = content

def __repr__(self):
return f"QueryContext(role={self.role}, content={self.content})"

def __str__(self):
return f"QueryContext(role={self.role}, content={self.content})"


class Status(Enum):
"""
Enum respresenting the status of a Result
"""
SUCCESS = "success"
ERROR = "error"


class Result:
"""
A class representing the result of a CryptoComAiAgentResponse.

Attributes:
status (str): The status of the result.
function (str): The function associated with the result.
message (str): A message describing the result.
data (Dict[str, Any]): Additional data associated with the result.
"""

def __init__(self, status: Status, function: str, message: str, data: Dict[str, Any]):
self.status = status
self.function = function
self.message = message
self.data = data

def __repr__(self):
return f"Result(status={self.status}, function={self.function}, message={self.message}, data={self.data})"


class CryptoComAiAgentResponse:
"""
A class representing the response from the CDC AI Agent service.

Attributes:
status (str): The status of the response (e.g., Success, Failed).
result (Dict[str, Any]): The result of the query, containing action, message, and other data.
status (str): The status of the response. (e.g. "success" or "failed")
message (Optional[str]): An optional message from the response describing any errors.
has_errors (Optional[bool]): Indicates whether the results list contains any errors.
results (Optional[List[Result]]): The results of the query, if available.
context (Optional[List[QueryContext]]): The context of the query, if available.
"""

def __init__(self, status: str, result: Dict[str, Any]):
def __init__(self, status: str, message: Optional[str] = None,
hasErrors: Optional[bool] = None, results: Optional[List[Dict[str, Any]]] = None,
context: Optional[List[Dict[str, Any]]] = None):
"""
Initialize the CryptoComAiAgentResponse object.

Args:
status (str): The status of the response (Success or Failed).
result (Dict[str, Any]): A dictionary containing the result of the AI query.
status (str): The status of the response. (e.g. "success" or "failed")
message (Optional[str]): An optional message from the response describing any errors.
hasErrors (Optional[bool]): Indicates whether the results list contains any errors.
results (Optional[List[Dict[str, Any]]]): The results of the query, if available.
context (Optional[List[Dict[str, Any]]]): The context of the query, if available.
"""
self.status = status
self.result = result
self.message = message
self.hasErrors = hasErrors
self.results = [Result(r['status'], r['function'],
r['message'], r['data']) for r in results] if results else None
self.context = [QueryContext((r['role']), r['content'])
for r in context] if context else None

@property
def has_errors(self):
"""
Get the has_errors property. The property is named hasErrors in the response from the API.
"""
return self.hasErrors

def __repr__(self):
"""
Provide a string representation for debugging purposes.

Returns:
str: A string showing the status and result of the response.
str: A string showing the attributes of the response.
"""
return f"CryptoComAiAgentResponse(status={self.status}, result={self.result})"
return (f"CryptoComAiAgentResponse(status={self.status}, message={self.message}, "
f"has_errors={self.has_errors}, results={self.results}, context={self.context})")

def __str__(self):
"""
Provide a user-friendly string representation of the response.

Returns:
str: A formatted string with the status and result of the response.
str: A formatted string with the attributes of the response.
"""
return f"Status: {self.status}, Result: {self.result}"
return (f"Status: {self.status}, Message: {self.message}, Has Errors: {self.has_errors}, "
f"Results: {self.results}, Context: {self.context}")

class Method:
"""
A class representing HTTP methods used for interacting with the CDC AI Agent service.
def to_dict(self):
"""
Convert the CryptoComAiAgentResponse object to a dictionary.

Attributes:
GET (str): Represents the GET HTTP method.
POST (str): Represents the POST HTTP method.
PUT (str): Represents the PUT HTTP method.
DELETE (str): Represents the DELETE HTTP method.
"""
GET = 'GET'
POST = 'POST'
PUT = 'PUT'
DELETE = 'DELETE'
Returns:
dict: A dictionary representation of the response.
"""
return {
"status": self.status,
"message": self.message,
"hasErrors": self.hasErrors,
"results": [result.__dict__ for result in self.results],
"context": [context.__dict__ for context in self.context]
}