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

Enhance onboarding process and optimize prompts #34

Merged
merged 8 commits into from
Aug 8, 2024
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
16 changes: 8 additions & 8 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@ DB_CONNECTION=postgresql+psycopg://postgres:password@vector_db:5432/openagent

# LLM provider settings (at least one required)
# To get a Google Cloud Vertex project ID, visit: https://console.cloud.google.com/vertex-ai
VERTEX_PROJECT_ID=your_google_cloud_vertex_project_id
VERTEX_PROJECT_ID=
# To get an OpenAI API key, sign up at: https://platform.openai.com/signup
OPENAI_API_KEY=your_openai_api_key
OPENAI_API_KEY=
# To get a Google Gemini API key, visit: https://ai.google.dev
GOOGLE_GEMINI_API_KEY=your_google_gemini_api_key
GOOGLE_GEMINI_API_KEY=
# For Ollama, download and install from: https://github.com/ollama/ollama
OLLAMA_HOST=http://ollama:11434

# Optional API keys for additional features
# Sign up for NFTScan API key at: https://developer.nftscan.com/
NFTSCAN_API_KEY=your_nftscan_api_key
NFTSCAN_API_KEY=
# Get your Tavily API key at: https://www.tavily.com/
TAVILY_API_KEY=your_tavily_api_key
TAVILY_API_KEY=
# Get your Covalent API key at: https://www.covalenthq.com/platform/auth/register/
COVALENT_API_KEY=your_covalent_api_key
COVALENT_API_KEY=
# Register for a RootData API key at: https://www.rootdata.com/
ROOTDATA_API_KEY=your_rootdata_api_key
ROOTDATA_API_KEY=
# Sign up for a CoinGecko API key at: https://www.coingecko.com/en/api/pricing
COINGECKO_API_KEY=your_coingecko_api_key
COINGECKO_API_KEY=
# RSS3 API URLs (default values provided, change if needed)
RSS3_DATA_API=https://gi.rss3.io
RSS3_SEARCH_API=https://devnet.rss3.io/search
Expand Down
3 changes: 1 addition & 2 deletions openagent/agents/asset_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@

1. Query and report on users' token balances
2. Check and inform about users' NFT holdings
3. Generate cross-chain swap widgets for users
4. Generate transfer widgets for users
3. Handle user requests to swap or transfer tokens

When interacting with users:
- Provide accurate and detailed information
Expand Down
5 changes: 3 additions & 2 deletions openagent/executors/swap_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ class ParamSchema(BaseModel):
description="Blockchain network to swap from, support networks: 'ETH', 'BSC', 'ARBITRUM', 'OPTIMISM', 'POLYGON'. Default: 'ETH'.",
)
to_chain: ChainLiteral = Field(
default="ETH", description="Blockchain network to swap to, support networks: 'ETH', 'BSC', 'ARBITRUM', 'OPTIMISM', 'POLYGON'. Default: 'ETH'."
default="ETH",
description="Blockchain network to swap to, support networks: 'ETH', 'BSC', 'ARBITRUM', 'OPTIMISM', 'POLYGON'. Default: 'ETH'.",
)
amount: str = Field(description="Amount of the from-side token to swap, e.g., '0.1', '1', '10'. Default: '1'.")

Expand All @@ -48,7 +49,7 @@ class SwapExecutor(BaseTool):
"""

name = "SwapExecutor"
description = "Use this tool to generate a swap widget for the user to swap cryptocurrencies."
description = "Use this tool to handle user requests to swap cryptocurrencies."
args_schema: Type[ParamSchema] = ParamSchema
return_direct = False

Expand Down
2 changes: 1 addition & 1 deletion openagent/executors/token_balance_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ARGS(BaseModel):

class TokenBalanceExecutor(BaseTool):
name = "TokenBalanceExecutor"
description = "get the token balance of a wallet."
description = "get the token balance of a wallet address."
args_schema: Type[ARGS] = ARGS

def _run(
Expand Down
14 changes: 12 additions & 2 deletions openagent/executors/token_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def chain_name_to_id(chain_name: str) -> str:
return chain_map.get(chain_name, "1")


@cached(ttl=60, cache=Cache.MEMORY)
@cached(ttl=300, cache=Cache.MEMORY)
async def fetch_tokens() -> Dict[str, List[Dict]]:
"""
Fetch the token list from the API and cache it for 60 seconds.
Expand Down Expand Up @@ -71,6 +71,14 @@ async def select_best_token(keyword: str, chain_id: str) -> Optional[Dict]:
"""
keyword = keyword.lower()

# special case for eth on non-ethereum chains
if keyword == "eth" and chain_id != "1":
keyword = "weth"

# special case for btc
if keyword == "btc":
keyword = "wbtc"

tokens = await fetch_tokens()
tokens_on_chain = tokens.get(chain_id, [])

Expand All @@ -84,8 +92,10 @@ async def select_best_token(keyword: str, chain_id: str) -> Optional[Dict]:
# Sort based on priority
results.sort(
key=lambda x: (
"logoURI" in x,
x["symbol"].lower() == keyword,
x["coinKey"].lower() == keyword,
x.get("coinKey", "").lower() == keyword,
x.get("priceUSD") is not None,
x["name"].lower() == keyword,
),
reverse=True,
Expand Down
1 change: 0 additions & 1 deletion openagent/ui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ async def on_chat_start():
provider_key = profile_name_to_provider_key(profile)
set_current_llm(provider_key)
setup_runnable()
await cl.Message(content=f"starting chat using the {profile} chat profile").send()


def build_token(token_symbol: str, token_address: str):
Expand Down
28 changes: 27 additions & 1 deletion openagent/ui/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,33 @@
def provider_to_profile(provider_key):
profile_info = provider_key_to_profile_info.get(provider_key)
if profile_info:
return cl.ChatProfile(name=profile_info["name"], markdown_description=profile_info["markdown_description"], icon=profile_info["icon"])
return cl.ChatProfile(
name=profile_info["name"],
markdown_description=profile_info["markdown_description"],
icon=profile_info["icon"],
starters=[
cl.Starter(
label="Swap coins",
message="Swap 1 ETH for USDC on the Ethereum.",
icon="/public/swap.png",
),
cl.Starter(
label="Market analysis",
message="What's the current price of Ethereum and its market trend?",
icon="/public/market.png",
),
cl.Starter(
label="Transfer coins",
message="Can you help me transfer 0.1 ETH to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e on the Ethereum network?",
icon="/public/transfer.png",
),
cl.Starter(
label="Block explorer",
message="What's the latest block height on the Ethereum network, and what are the current gas fees?",
icon="/public/block_chain.png",
),
],
)
return None


Expand Down
9 changes: 7 additions & 2 deletions openagent/workflows/member.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
FALLBACK = "fallback_agent"

AgentRole = Literal[
"market_analysis_agent", "asset_management_agent", "block_explorer_agent", "feed_explorer_agent", "research_analyst_agent", "fallback_agent"
"market_analysis_agent",
"asset_management_agent",
"block_explorer_agent",
"feed_explorer_agent",
"research_analyst_agent",
"fallback_agent",
]

members = [
Expand All @@ -33,7 +38,7 @@
Responsibilities:
1. Query and report on users' token balances
2. Check and inform about users' NFT holdings
3. Generate cross-chain swap widgets for users
3. Swap or transfer of cryptocurrency tokens

Provide accurate information with a friendly tone, using occasional puns or emojis to keep interactions engaging.
""".strip(),
Expand Down
Binary file added public/block_chain.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/logo_dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/logo_light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/market.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/swap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/transfer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 8 additions & 2 deletions tests/supervisor_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def next_role(query) -> str:

class TestNextRole(unittest.TestCase):
def setUp(self):
# set_current_llm("gemini-1.5-pro")
set_current_llm("gemini-1.5-flash")
set_current_llm("gemini-1.5-pro")
# set_current_llm("gemini-1.5-flash")
# set_current_llm("gpt-3.5-turbo")
# set_current_llm("llama3.1:latest")

Expand All @@ -33,6 +33,12 @@ def test_asset_management(self):
result = next_role(query)
self.assertEqual(result, expected_role, f"Expected {expected_role}, but got {result} for query: {query}")

def test_asset_management_swap(self):
query = "swap 1 eth to usdt on ethereum."
expected_role = "asset_management_agent"
result = next_role(query)
self.assertEqual(result, expected_role, f"Expected {expected_role}, but got {result} for query: {query}")

def test_transfer_expert(self):
query = "Can you help me transfer 0.5 ETH to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e on the Ethereum network?"
expected_role = "asset_management_agent"
Expand Down
Loading