LONGYKING
commited on
Commit
·
3c728a8
1
Parent(s):
bc66df6
swap integerated
Browse files- chatxbt-assistant.py +44 -44
- src/libs/rpc_client.py +1 -1
- src/tools/crypto_swap_toolkit.py +30 -39
- src/tools/user_profile_toolkit.py +3 -0
chatxbt-assistant.py
CHANGED
|
@@ -23,6 +23,50 @@ storage = PgAssistantStorage(
|
|
| 23 |
db_engine=sqlalchemy_engine
|
| 24 |
)
|
| 25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
@cl.oauth_callback
|
| 27 |
def oauth_callback(
|
| 28 |
provider_id: str,
|
|
@@ -81,50 +125,6 @@ async def set_starters():
|
|
| 81 |
)
|
| 82 |
]
|
| 83 |
|
| 84 |
-
@cl.on_chat_start
|
| 85 |
-
async def start():
|
| 86 |
-
is_dev_mode = True if os.getenv("DEV_MODE") else False
|
| 87 |
-
|
| 88 |
-
# Initialize the assistant
|
| 89 |
-
cxbt_assistant = Assistant(
|
| 90 |
-
llm=OpenAIChat(model="gpt-4o"),
|
| 91 |
-
tools=[
|
| 92 |
-
UserProfileToolkit(),
|
| 93 |
-
DuckDuckGo(),
|
| 94 |
-
CryptoDataTools(),
|
| 95 |
-
CryptoSwapTools(),
|
| 96 |
-
CryptoEVMWalletTools(),
|
| 97 |
-
UserConfirmationPinToolkit(),
|
| 98 |
-
YFinanceTools(stock_price=True)
|
| 99 |
-
],
|
| 100 |
-
show_tool_calls=is_dev_mode,
|
| 101 |
-
markdown=True,
|
| 102 |
-
knowledge_base=knowledge_base,
|
| 103 |
-
storage=storage,
|
| 104 |
-
search_knowledge=True,
|
| 105 |
-
read_chat_history=True,
|
| 106 |
-
add_references_to_prompt=True,
|
| 107 |
-
add_chat_history_to_prompt=True
|
| 108 |
-
)
|
| 109 |
-
cxbt_assistant.knowledge_base.load(recreate=False)
|
| 110 |
-
|
| 111 |
-
# Set the assistant in the user session
|
| 112 |
-
cl.user_session.set("agent", cxbt_assistant)
|
| 113 |
-
|
| 114 |
-
@cl.on_message
|
| 115 |
-
async def main(message: cl.Message):
|
| 116 |
-
|
| 117 |
-
# Retrieve the assistant from the user session
|
| 118 |
-
agent = cl.user_session.get("agent")
|
| 119 |
-
|
| 120 |
-
# Process the user message using the assistant
|
| 121 |
-
response = ""
|
| 122 |
-
for delta in agent.run(message.content, stream=True):
|
| 123 |
-
response += delta
|
| 124 |
-
|
| 125 |
-
# Send the response back to the user
|
| 126 |
-
await cl.Message(content=response).send()
|
| 127 |
-
|
| 128 |
# Run the Chainlit application
|
| 129 |
if __name__ == "__main__":
|
| 130 |
cl.run()
|
|
|
|
| 23 |
db_engine=sqlalchemy_engine
|
| 24 |
)
|
| 25 |
|
| 26 |
+
@cl.on_chat_start
|
| 27 |
+
async def start():
|
| 28 |
+
is_dev_mode = True if os.getenv("DEV_MODE") else False
|
| 29 |
+
|
| 30 |
+
# Initialize the assistant
|
| 31 |
+
cxbt_assistant = Assistant(
|
| 32 |
+
llm=OpenAIChat(model="gpt-4o"),
|
| 33 |
+
tools=[
|
| 34 |
+
UserProfileToolkit(),
|
| 35 |
+
DuckDuckGo(),
|
| 36 |
+
CryptoDataTools(),
|
| 37 |
+
CryptoSwapTools(),
|
| 38 |
+
CryptoEVMWalletTools(),
|
| 39 |
+
UserConfirmationPinToolkit(),
|
| 40 |
+
YFinanceTools(stock_price=True)
|
| 41 |
+
],
|
| 42 |
+
show_tool_calls=is_dev_mode,
|
| 43 |
+
markdown=True,
|
| 44 |
+
knowledge_base=knowledge_base,
|
| 45 |
+
storage=storage,
|
| 46 |
+
search_knowledge=True,
|
| 47 |
+
read_chat_history=True,
|
| 48 |
+
add_references_to_prompt=True,
|
| 49 |
+
add_chat_history_to_prompt=True
|
| 50 |
+
)
|
| 51 |
+
cxbt_assistant.knowledge_base.load(recreate=False)
|
| 52 |
+
|
| 53 |
+
# Set the assistant in the user session
|
| 54 |
+
cl.user_session.set("agent", cxbt_assistant)
|
| 55 |
+
|
| 56 |
+
@cl.on_message
|
| 57 |
+
async def main(message: cl.Message):
|
| 58 |
+
|
| 59 |
+
# Retrieve the assistant from the user session
|
| 60 |
+
agent = cl.user_session.get("agent")
|
| 61 |
+
|
| 62 |
+
# Process the user message using the assistant
|
| 63 |
+
response = ""
|
| 64 |
+
for delta in agent.run(message.content, stream=True):
|
| 65 |
+
response += delta
|
| 66 |
+
|
| 67 |
+
# Send the response back to the user
|
| 68 |
+
await cl.Message(content=response).send()
|
| 69 |
+
|
| 70 |
@cl.oauth_callback
|
| 71 |
def oauth_callback(
|
| 72 |
provider_id: str,
|
|
|
|
| 125 |
)
|
| 126 |
]
|
| 127 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
# Run the Chainlit application
|
| 129 |
if __name__ == "__main__":
|
| 130 |
cl.run()
|
src/libs/rpc_client.py
CHANGED
|
@@ -49,4 +49,4 @@ async def rpc_call(
|
|
| 49 |
return response.json()
|
| 50 |
except httpx.RequestError as e:
|
| 51 |
print(f"Error making RPC call: {e}")
|
| 52 |
-
|
|
|
|
| 49 |
return response.json()
|
| 50 |
except httpx.RequestError as e:
|
| 51 |
print(f"Error making RPC call: {e}")
|
| 52 |
+
raise ValueError(f"Error making RPC call: {e}")
|
src/tools/crypto_swap_toolkit.py
CHANGED
|
@@ -99,58 +99,49 @@ class CryptoSwapTools(Toolkit):
|
|
| 99 |
response = asyncio.run(rpc_call(method_name="getSwapSources"))
|
| 100 |
return f"{response}"
|
| 101 |
|
| 102 |
-
def execute_swap(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
"""
|
| 104 |
Executes a swap using the 0x Swap API.
|
| 105 |
|
| 106 |
Args:
|
| 107 |
-
buy_token (str): The token to buy (e.g., 'DAI').
|
| 108 |
-
sell_token (str): The token to sell (e.g., 'ETH').
|
| 109 |
-
sell_amount (str): The amount of the sell token to swap, in the smallest unit (e.g., wei for ETH).
|
| 110 |
-
|
|
|
|
| 111 |
|
| 112 |
Returns:
|
| 113 |
dict: The transaction receipt of the swap transaction.
|
| 114 |
|
| 115 |
Example:
|
| 116 |
-
>>> execute_swap('DAI', 'ETH', '1000000000000000000', '
|
| 117 |
"""
|
| 118 |
-
# Get the swap quote
|
| 119 |
-
quote = json.loads(self.get_swap_quote(buy_token, sell_token, sell_amount))
|
| 120 |
-
logger.info(f"Swap quote: {quote}")
|
| 121 |
-
|
| 122 |
-
if 'error' in quote:
|
| 123 |
-
# return {"error": "Failed to get swap quote"}
|
| 124 |
-
return f"Error: Failed to get swap quote"
|
| 125 |
-
|
| 126 |
-
# Approve the token if needed (skip if selling ETH)
|
| 127 |
-
if sell_token != 'ETH':
|
| 128 |
-
approval_receipt = self.token_approval_helper.approve_token(sell_token, quote['allowanceTarget'],
|
| 129 |
-
sell_amount, eth_address)
|
| 130 |
-
logger.info(f"Approval receipt: {approval_receipt}")
|
| 131 |
-
|
| 132 |
-
if 'status' not in approval_receipt or approval_receipt['status'] != 1:
|
| 133 |
-
# return {"error": "Token approval failed"}
|
| 134 |
-
return f"Error: Token approval failed"
|
| 135 |
|
| 136 |
-
|
| 137 |
try:
|
| 138 |
-
|
| 139 |
-
'
|
| 140 |
-
'
|
| 141 |
-
'
|
| 142 |
-
'
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
|
|
|
|
|
|
|
|
|
| 146 |
}
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
# return receipt
|
| 152 |
-
return f"{(receipt)}"
|
| 153 |
-
except Exception as e:
|
| 154 |
logger.warning(f"Failed to execute swap: {e}")
|
| 155 |
# return {"error": str(e)}
|
| 156 |
return f"Error: {e}"
|
|
|
|
| 99 |
response = asyncio.run(rpc_call(method_name="getSwapSources"))
|
| 100 |
return f"{response}"
|
| 101 |
|
| 102 |
+
def execute_swap(
|
| 103 |
+
self,
|
| 104 |
+
buy_token: str,
|
| 105 |
+
sell_token: str,
|
| 106 |
+
sell_amount: str,
|
| 107 |
+
user_email: str,
|
| 108 |
+
chain: str = "base",
|
| 109 |
+
) -> str:
|
| 110 |
"""
|
| 111 |
Executes a swap using the 0x Swap API.
|
| 112 |
|
| 113 |
Args:
|
| 114 |
+
-buy_token (str): The token to buy (e.g., 'DAI').
|
| 115 |
+
-sell_token (str): The token to sell (e.g., 'ETH').
|
| 116 |
+
-sell_amount (str): The amount of the sell token to swap, in the smallest unit (e.g., wei for ETH).
|
| 117 |
+
- user_email (str): The email of the user for whom the wallet is being fetched.
|
| 118 |
+
- chain (str): The EVM chain for which the wallet is being fetched and used to execute this transaction. use chain base as default
|
| 119 |
|
| 120 |
Returns:
|
| 121 |
dict: The transaction receipt of the swap transaction.
|
| 122 |
|
| 123 |
Example:
|
| 124 |
+
>>> execute_swap('DAI', 'ETH', '1000000000000000000', 'userEmail', 'base')
|
| 125 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
|
| 127 |
+
logger.info("executing swap")
|
| 128 |
try:
|
| 129 |
+
params = {
|
| 130 |
+
'buyToken': buy_token,
|
| 131 |
+
'sellToken': sell_token,
|
| 132 |
+
'sellAmount': sell_amount,
|
| 133 |
+
'wallet': {
|
| 134 |
+
"userEmail": user_email,
|
| 135 |
+
"chain": chain,
|
| 136 |
+
"testnet": True,
|
| 137 |
+
"gasless": True,
|
| 138 |
+
"connected": True
|
| 139 |
+
}
|
| 140 |
}
|
| 141 |
+
response = asyncio.run(rpc_call(method_name="swapTokens", params=params))
|
| 142 |
+
logger.info(f"Swap transaction receipt: {response}")
|
| 143 |
+
return f"{response}"
|
| 144 |
+
except requests.exceptions.RequestException as e:
|
|
|
|
|
|
|
|
|
|
| 145 |
logger.warning(f"Failed to execute swap: {e}")
|
| 146 |
# return {"error": str(e)}
|
| 147 |
return f"Error: {e}"
|
src/tools/user_profile_toolkit.py
CHANGED
|
@@ -21,6 +21,9 @@ class UserProfileToolkit(Toolkit):
|
|
| 21 |
self.register(self.update_user_picture)
|
| 22 |
self.register(self.get_user_id)
|
| 23 |
|
|
|
|
|
|
|
|
|
|
| 24 |
@cl.on_chat_start
|
| 25 |
def get_user_info(self, info_type: str) -> str:
|
| 26 |
"""
|
|
|
|
| 21 |
self.register(self.update_user_picture)
|
| 22 |
self.register(self.get_user_id)
|
| 23 |
|
| 24 |
+
# fetching user email
|
| 25 |
+
self.email = self.get_user_email()
|
| 26 |
+
|
| 27 |
@cl.on_chat_start
|
| 28 |
def get_user_info(self, info_type: str) -> str:
|
| 29 |
"""
|