fixed swap and bridging
Browse files- .gitattributes +35 -0
- Dockerfile +16 -7
- README.md +22 -18
- chatxbt-assistant.py +29 -15
- docker-compose.yml +1 -1
- pip +0 -0
- requirements.txt +21 -3
- src/config/nemoguardrails/config.yml +27 -0
- src/config/portkey_config.py +108 -0
- src/libs/rpc_client.py +4 -4
- src/tools/crypto_bridge_toolkit.py +18 -9
- src/tools/crypto_evm_wallet_toolkit.py +56 -17
- src/tools/crypto_swap_toolkit.py +42 -14
- src/tools/user_confirmation_pin_toolkit.py +107 -0
- src/tools/user_profile_toolkit.py +30 -3
.gitattributes
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
Dockerfile
CHANGED
|
@@ -1,25 +1,34 @@
|
|
| 1 |
# Use an official Python runtime as a parent image
|
| 2 |
FROM python:3.11-slim
|
| 3 |
|
|
|
|
|
|
|
|
|
|
| 4 |
# Set the working directory in the container
|
| 5 |
WORKDIR /app
|
| 6 |
|
| 7 |
-
# Install
|
|
|
|
| 8 |
RUN apt-get update && apt-get install -y \
|
|
|
|
| 9 |
libpq-dev \
|
| 10 |
gcc \
|
| 11 |
&& rm -rf /var/lib/apt/lists/*
|
| 12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
# Copy the rest of the application code into the container
|
| 14 |
-
COPY . .
|
| 15 |
|
| 16 |
# Install any needed packages specified in requirements.txt
|
| 17 |
RUN pip install --no-cache-dir -r requirements.txt
|
| 18 |
|
| 19 |
-
#
|
| 20 |
-
|
| 21 |
-
EXPOSE 8080
|
| 22 |
|
| 23 |
# Run chainlit when the container launches
|
| 24 |
-
CMD ["python", "-m", "chainlit", "run", "chatxbt-assistant.py", "-h", "--port", "
|
| 25 |
-
|
|
|
|
| 1 |
# Use an official Python runtime as a parent image
|
| 2 |
FROM python:3.11-slim
|
| 3 |
|
| 4 |
+
# Create a user and set permissions
|
| 5 |
+
RUN useradd -m -u 1000 user
|
| 6 |
+
|
| 7 |
# Set the working directory in the container
|
| 8 |
WORKDIR /app
|
| 9 |
|
| 10 |
+
# Install system dependencies
|
| 11 |
+
USER root
|
| 12 |
RUN apt-get update && apt-get install -y \
|
| 13 |
+
python3-dev \
|
| 14 |
libpq-dev \
|
| 15 |
gcc \
|
| 16 |
&& rm -rf /var/lib/apt/lists/*
|
| 17 |
|
| 18 |
+
# Ensure .files directory exists and is writable
|
| 19 |
+
RUN mkdir -p /app/.files && chown -R user:user /app/.files
|
| 20 |
+
|
| 21 |
+
# Switch back to the non-root user
|
| 22 |
+
USER user
|
| 23 |
+
|
| 24 |
# Copy the rest of the application code into the container
|
| 25 |
+
COPY --chown=user . .
|
| 26 |
|
| 27 |
# Install any needed packages specified in requirements.txt
|
| 28 |
RUN pip install --no-cache-dir -r requirements.txt
|
| 29 |
|
| 30 |
+
# Expose port 8080 to the world outside this container
|
| 31 |
+
EXPOSE 7860
|
|
|
|
| 32 |
|
| 33 |
# Run chainlit when the container launches
|
| 34 |
+
CMD ["python", "-m", "chainlit", "run", "chatxbt-assistant.py", "-h", "--port", "7860"]
|
|
|
README.md
CHANGED
|
@@ -1,11 +1,21 @@
|
|
| 1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
AI-powered unification and execution protocol for web3 applications
|
| 4 |
|
| 5 |
-
|
| 6 |
## Requirements
|
| 7 |
|
| 8 |
-
The list below contains all the requirements needed to have a complete developer environment to
|
| 9 |
Follow the links to install or update these tools on your machine.
|
| 10 |
|
| 11 |
1. [Python 3.12+](https://www.python.org/downloads/release/python-3120/)
|
|
@@ -13,17 +23,15 @@ Follow the links to install or update these tools on your machine.
|
|
| 13 |
3. [Pip Installer](https://pip.pypa.io/en/stable/installation/)
|
| 14 |
4. [Python Venv](https://docs.python.org/3/library/venv.html)
|
| 15 |
|
| 16 |
-
|
| 17 |
## Installation
|
| 18 |
|
| 19 |
1. Clone the repository: `git clone https://github.com/ChatXBT/chatxbt-web3-ai-assistant.git`
|
| 20 |
-
2. Get a copy of the
|
| 21 |
3. Create a virtual environment: `python -m venv env`
|
| 22 |
4. Activate the virtual environment: `source env/bin/activate`
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
|
| 28 |
## Project Overview
|
| 29 |
|
|
@@ -36,17 +44,15 @@ The project is structured as follows:
|
|
| 36 |
5. src/search_services: `a list of search services that can be used to retrieve data for the AI assistant.`
|
| 37 |
6. src/tools: `a list of tools that can be used to extend the functionality of the AI assistant.`
|
| 38 |
|
| 39 |
-
|
| 40 |
## Guides
|
| 41 |
|
| 42 |
1. Follow the development, structure and documentation patterns of the `src/tools/coin_data_toolkit.py` to build custom toolkits
|
| 43 |
2. Follow the development, structure and documentation patterns of the `src/tools/coin_data_toolkit.py` to build classes
|
| 44 |
-
3. Pay attention to the `constants` variables and `caching` decorators to optimize
|
| 45 |
4. Create new classes in the appropriate folders to maintain an organized codebase and project
|
| 46 |
5. After installing any new package run `` to update the dependency requirements list
|
| 47 |
6. Expose RPC functions for SDKs that do not support python runtime. use [DeepKit](https://deepkit.io/documentation/rpc) and [BunJS](https://bun.sh/) if possible.
|
| 48 |
|
| 49 |
-
|
| 50 |
## Git Workflow
|
| 51 |
|
| 52 |
For this project, we will be using a very simple version of the Gitflow workflow. This workflow is designed to manage the development, release, and maintenance of software projects. It provides a clear and structured approach to managing branches, releases, and feature development.
|
|
@@ -68,21 +74,19 @@ For this project, we will be using a very simple version of the Gitflow workflow
|
|
| 68 |
3. Push your changes to the remote repository: `git push origin bugfix/my-bugfix`
|
| 69 |
4. Open a pull request on GitHub and request a review from a team member.
|
| 70 |
5. Deploy the bugfix branch to a staging environment for testing.
|
| 71 |
-
6. Once testing is finished, merge the pull
|
| 72 |
7. Once the pull request is approved, merge it into the main branch.
|
| 73 |
8. Delete the bugfix branch: `git branch -d bugfix/my-bugfix`
|
| 74 |
9. Update your local main branch: `git checkout main && git pull origin main`
|
| 75 |
|
| 76 |
-
|
| 77 |
-
## Deplopyment to producton
|
| 78 |
|
| 79 |
To be finalised and added
|
| 80 |
|
| 81 |
-
|
| 82 |
## TODO
|
| 83 |
|
| 84 |
1. Add deployment instructions
|
| 85 |
2. Setup CI/CD pipelines for automatic deployment
|
| 86 |
3. Setup and integrate `LiteLLM` instance for LLM service high availability
|
| 87 |
-
4. Add RPC class for
|
| 88 |
-
5. Write enough unit
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: ChatXBT
|
| 3 |
+
emoji: 💬
|
| 4 |
+
colorFrom: purple
|
| 5 |
+
colorTo: pink
|
| 6 |
+
sdk: docker
|
| 7 |
+
sdk_version: "latest"
|
| 8 |
+
app_file: chatxbt-assistant.py
|
| 9 |
+
pinned: false
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
# ChatXBT Web3 AI Assistant Service
|
| 13 |
|
| 14 |
AI-powered unification and execution protocol for web3 applications
|
| 15 |
|
|
|
|
| 16 |
## Requirements
|
| 17 |
|
| 18 |
+
The list below contains all the requirements needed to have a complete developer environment to start working on this project.
|
| 19 |
Follow the links to install or update these tools on your machine.
|
| 20 |
|
| 21 |
1. [Python 3.12+](https://www.python.org/downloads/release/python-3120/)
|
|
|
|
| 23 |
3. [Pip Installer](https://pip.pypa.io/en/stable/installation/)
|
| 24 |
4. [Python Venv](https://docs.python.org/3/library/venv.html)
|
| 25 |
|
|
|
|
| 26 |
## Installation
|
| 27 |
|
| 28 |
1. Clone the repository: `git clone https://github.com/ChatXBT/chatxbt-web3-ai-assistant.git`
|
| 29 |
+
2. Get a copy of the `.env` file from the project manager
|
| 30 |
3. Create a virtual environment: `python -m venv env`
|
| 31 |
4. Activate the virtual environment: `source env/bin/activate`
|
| 32 |
+
5. Install the dependencies: `pip install -r requirements.txt`
|
| 33 |
+
6. Run the application: `chainlit run chatxbt-assistant.py -w`
|
| 34 |
+
7. Open the application in your browser: `http://localhost:8000`
|
|
|
|
| 35 |
|
| 36 |
## Project Overview
|
| 37 |
|
|
|
|
| 44 |
5. src/search_services: `a list of search services that can be used to retrieve data for the AI assistant.`
|
| 45 |
6. src/tools: `a list of tools that can be used to extend the functionality of the AI assistant.`
|
| 46 |
|
|
|
|
| 47 |
## Guides
|
| 48 |
|
| 49 |
1. Follow the development, structure and documentation patterns of the `src/tools/coin_data_toolkit.py` to build custom toolkits
|
| 50 |
2. Follow the development, structure and documentation patterns of the `src/tools/coin_data_toolkit.py` to build classes
|
| 51 |
+
3. Pay attention to the `constants` variables and `caching` decorators to optimize performance of class functions/methods across the project
|
| 52 |
4. Create new classes in the appropriate folders to maintain an organized codebase and project
|
| 53 |
5. After installing any new package run `` to update the dependency requirements list
|
| 54 |
6. Expose RPC functions for SDKs that do not support python runtime. use [DeepKit](https://deepkit.io/documentation/rpc) and [BunJS](https://bun.sh/) if possible.
|
| 55 |
|
|
|
|
| 56 |
## Git Workflow
|
| 57 |
|
| 58 |
For this project, we will be using a very simple version of the Gitflow workflow. This workflow is designed to manage the development, release, and maintenance of software projects. It provides a clear and structured approach to managing branches, releases, and feature development.
|
|
|
|
| 74 |
3. Push your changes to the remote repository: `git push origin bugfix/my-bugfix`
|
| 75 |
4. Open a pull request on GitHub and request a review from a team member.
|
| 76 |
5. Deploy the bugfix branch to a staging environment for testing.
|
| 77 |
+
6. Once testing is finished, merge the pull request into the main branch.
|
| 78 |
7. Once the pull request is approved, merge it into the main branch.
|
| 79 |
8. Delete the bugfix branch: `git branch -d bugfix/my-bugfix`
|
| 80 |
9. Update your local main branch: `git checkout main && git pull origin main`
|
| 81 |
|
| 82 |
+
## Deployment to production
|
|
|
|
| 83 |
|
| 84 |
To be finalised and added
|
| 85 |
|
|
|
|
| 86 |
## TODO
|
| 87 |
|
| 88 |
1. Add deployment instructions
|
| 89 |
2. Setup CI/CD pipelines for automatic deployment
|
| 90 |
3. Setup and integrate `LiteLLM` instance for LLM service high availability
|
| 91 |
+
4. Add RPC class for remote method calls to other ChatXBT services written in other languages such as `JS`, `TS` & `GO`
|
| 92 |
+
5. Write enough unit tests to ensure class and function input and output correctness
|
chatxbt-assistant.py
CHANGED
|
@@ -1,23 +1,28 @@
|
|
| 1 |
-
import os
|
| 2 |
from typing import Optional, Dict
|
| 3 |
from dotenv import load_dotenv
|
|
|
|
| 4 |
load_dotenv()
|
| 5 |
|
| 6 |
import chainlit as cl
|
| 7 |
from phi.assistant import Assistant
|
| 8 |
from phi.llm.openai import OpenAIChat
|
|
|
|
| 9 |
from phi.llm.groq import Groq
|
| 10 |
from phi.tools.duckduckgo import DuckDuckGo
|
| 11 |
from phi.tools.yfinance import YFinanceTools
|
| 12 |
from src.databases.postgres import sqlalchemy_engine
|
|
|
|
| 13 |
from src.tools.crypto_swap_toolkit import CryptoSwapTools
|
| 14 |
from src.tools.crypto_bridge_toolkit import CrossChainSwapTools
|
| 15 |
from src.tools.crypto_data_toolkit import CryptoDataTools
|
| 16 |
-
from
|
|
|
|
| 17 |
from src.tools.user_profile_toolkit import UserProfileToolkit
|
| 18 |
from phi.storage.assistant.postgres import PgAssistantStorage
|
| 19 |
-
from src.
|
| 20 |
-
from src.
|
|
|
|
| 21 |
|
| 22 |
storage = PgAssistantStorage(
|
| 23 |
# stores runs in the ai.assistant_runs table
|
|
@@ -87,19 +92,22 @@ async def set_starters():
|
|
| 87 |
async def start():
|
| 88 |
is_dev_mode = True if os.getenv("DEV_MODE") else False
|
| 89 |
|
|
|
|
|
|
|
|
|
|
| 90 |
# Initialize the assistant
|
| 91 |
cxbt_assistant = Assistant(
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
llm=Groq(model="llama3-70b-8192"),
|
| 96 |
tools=[
|
| 97 |
-
UserProfileToolkit(),
|
| 98 |
DuckDuckGo(),
|
| 99 |
CryptoDataTools(),
|
| 100 |
CryptoSwapTools(),
|
| 101 |
CrossChainSwapTools(),
|
|
|
|
| 102 |
CryptoEVMWalletTools(),
|
|
|
|
| 103 |
YFinanceTools(stock_price=True)
|
| 104 |
],
|
| 105 |
show_tool_calls=is_dev_mode,
|
|
@@ -109,7 +117,9 @@ async def start():
|
|
| 109 |
search_knowledge=True,
|
| 110 |
read_chat_history=True,
|
| 111 |
add_references_to_prompt=True,
|
| 112 |
-
add_chat_history_to_prompt=True
|
|
|
|
|
|
|
| 113 |
)
|
| 114 |
cxbt_assistant.knowledge_base.load(recreate=False)
|
| 115 |
|
|
@@ -119,16 +129,20 @@ async def start():
|
|
| 119 |
@cl.on_message
|
| 120 |
async def main(message: cl.Message):
|
| 121 |
|
|
|
|
|
|
|
|
|
|
| 122 |
# Retrieve the assistant from the user session
|
| 123 |
agent = cl.user_session.get("agent")
|
| 124 |
|
| 125 |
# Process the user message using the assistant
|
| 126 |
-
response = ""
|
| 127 |
for delta in agent.run(message.content, stream=True):
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
|
|
|
|
|
|
| 132 |
|
| 133 |
# Run the Chainlit application
|
| 134 |
if __name__ == "__main__":
|
|
|
|
| 1 |
+
import os, json
|
| 2 |
from typing import Optional, Dict
|
| 3 |
from dotenv import load_dotenv
|
| 4 |
+
|
| 5 |
load_dotenv()
|
| 6 |
|
| 7 |
import chainlit as cl
|
| 8 |
from phi.assistant import Assistant
|
| 9 |
from phi.llm.openai import OpenAIChat
|
| 10 |
+
from phi.llm.ollama import Ollama
|
| 11 |
from phi.llm.groq import Groq
|
| 12 |
from phi.tools.duckduckgo import DuckDuckGo
|
| 13 |
from phi.tools.yfinance import YFinanceTools
|
| 14 |
from src.databases.postgres import sqlalchemy_engine
|
| 15 |
+
from src.knowledge_bases.combined import knowledge_base
|
| 16 |
from src.tools.crypto_swap_toolkit import CryptoSwapTools
|
| 17 |
from src.tools.crypto_bridge_toolkit import CrossChainSwapTools
|
| 18 |
from src.tools.crypto_data_toolkit import CryptoDataTools
|
| 19 |
+
from portkey_ai import PORTKEY_GATEWAY_URL, createHeaders
|
| 20 |
+
from src.config.portkey_config import generate_portkey_config
|
| 21 |
from src.tools.user_profile_toolkit import UserProfileToolkit
|
| 22 |
from phi.storage.assistant.postgres import PgAssistantStorage
|
| 23 |
+
from src.tools.crypto_evm_wallet_toolkit import CryptoEVMWalletTools
|
| 24 |
+
from src.tools.user_confirmation_pin_toolkit import UserConfirmationPinToolkit
|
| 25 |
+
|
| 26 |
|
| 27 |
storage = PgAssistantStorage(
|
| 28 |
# stores runs in the ai.assistant_runs table
|
|
|
|
| 92 |
async def start():
|
| 93 |
is_dev_mode = True if os.getenv("DEV_MODE") else False
|
| 94 |
|
| 95 |
+
portkey_local_gateway = True if os.getenv("PORTKEY_LOCAL_GATEWAY_URL") else False
|
| 96 |
+
portkey_config = generate_portkey_config(local=portkey_local_gateway)
|
| 97 |
+
|
| 98 |
# Initialize the assistant
|
| 99 |
cxbt_assistant = Assistant(
|
| 100 |
+
# llm=OpenAIChat(),
|
| 101 |
+
# llm=Groq(model="llama3-70b-8192"),
|
| 102 |
+
llm=Ollama(model="llama3"),
|
|
|
|
| 103 |
tools=[
|
|
|
|
| 104 |
DuckDuckGo(),
|
| 105 |
CryptoDataTools(),
|
| 106 |
CryptoSwapTools(),
|
| 107 |
CrossChainSwapTools(),
|
| 108 |
+
UserProfileToolkit(),
|
| 109 |
CryptoEVMWalletTools(),
|
| 110 |
+
UserConfirmationPinToolkit(),
|
| 111 |
YFinanceTools(stock_price=True)
|
| 112 |
],
|
| 113 |
show_tool_calls=is_dev_mode,
|
|
|
|
| 117 |
search_knowledge=True,
|
| 118 |
read_chat_history=True,
|
| 119 |
add_references_to_prompt=True,
|
| 120 |
+
add_chat_history_to_prompt=True,
|
| 121 |
+
prevent_hallucinations=True,
|
| 122 |
+
prevent_prompt_injection=True
|
| 123 |
)
|
| 124 |
cxbt_assistant.knowledge_base.load(recreate=False)
|
| 125 |
|
|
|
|
| 129 |
@cl.on_message
|
| 130 |
async def main(message: cl.Message):
|
| 131 |
|
| 132 |
+
msg = cl.Message(content="")
|
| 133 |
+
await msg.send()
|
| 134 |
+
|
| 135 |
# Retrieve the assistant from the user session
|
| 136 |
agent = cl.user_session.get("agent")
|
| 137 |
|
| 138 |
# Process the user message using the assistant
|
|
|
|
| 139 |
for delta in agent.run(message.content, stream=True):
|
| 140 |
+
for part in delta:
|
| 141 |
+
if token := part or "":
|
| 142 |
+
# Send the response back to the user
|
| 143 |
+
await msg.stream_token(token)
|
| 144 |
+
|
| 145 |
+
await msg.update()
|
| 146 |
|
| 147 |
# Run the Chainlit application
|
| 148 |
if __name__ == "__main__":
|
docker-compose.yml
CHANGED
|
@@ -3,7 +3,7 @@ services:
|
|
| 3 |
image: chatxbt-web3-ai-assistant
|
| 4 |
build: .
|
| 5 |
ports:
|
| 6 |
-
- "
|
| 7 |
env_file:
|
| 8 |
- .env
|
| 9 |
depends_on:
|
|
|
|
| 3 |
image: chatxbt-web3-ai-assistant
|
| 4 |
build: .
|
| 5 |
ports:
|
| 6 |
+
- "7860:7860"
|
| 7 |
env_file:
|
| 8 |
- .env
|
| 9 |
depends_on:
|
pip
ADDED
|
File without changes
|
requirements.txt
CHANGED
|
@@ -8,12 +8,14 @@ anthropic==0.28.0
|
|
| 8 |
anyio==3.7.1
|
| 9 |
appdirs==1.4.4
|
| 10 |
appnope==0.1.4
|
|
|
|
| 11 |
asgiref==3.8.1
|
| 12 |
asttokens==2.4.1
|
| 13 |
async-timeout==4.0.3
|
| 14 |
asyncer==0.0.2
|
| 15 |
attrs==23.2.0
|
| 16 |
backcall==0.2.0
|
|
|
|
| 17 |
baize==0.20.8
|
| 18 |
beautifulsoup4==4.12.3
|
| 19 |
bidict==0.23.1
|
|
@@ -21,22 +23,26 @@ bitarray==2.9.2
|
|
| 21 |
bleach==6.1.0
|
| 22 |
boto3==1.34.106
|
| 23 |
botocore==1.34.106
|
|
|
|
| 24 |
certifi==2024.6.2
|
|
|
|
| 25 |
chainlit==1.1.300
|
| 26 |
charset-normalizer==3.3.2
|
| 27 |
-
psycopg2-binary==2.9.9
|
| 28 |
chevron==0.14.0
|
| 29 |
ckzg==1.0.2
|
| 30 |
click==8.1.7
|
| 31 |
coingecko==0.13
|
|
|
|
| 32 |
cytoolz==0.12.3
|
| 33 |
dataclasses-json==0.5.14
|
| 34 |
decorator==5.1.1
|
| 35 |
defusedxml==0.7.1
|
| 36 |
Deprecated==1.2.14
|
| 37 |
distro==1.9.0
|
|
|
|
| 38 |
docopt==0.6.2
|
| 39 |
duckduckgo_search==6.1.6
|
|
|
|
| 40 |
eth-account==0.11.2
|
| 41 |
eth-hash==0.7.0
|
| 42 |
eth-keyfile==0.8.1
|
|
@@ -47,7 +53,9 @@ eth-utils==4.1.1
|
|
| 47 |
eth_abi==5.1.0
|
| 48 |
exceptiongroup==1.2.1
|
| 49 |
executing==2.0.1
|
| 50 |
-
fastapi==0.
|
|
|
|
|
|
|
| 51 |
fastjsonschema==2.19.1
|
| 52 |
filelock==3.15.1
|
| 53 |
filetype==1.2.0
|
|
@@ -62,10 +70,12 @@ google_search_results==2.4.2
|
|
| 62 |
googleapis-common-protos==1.63.1
|
| 63 |
greenlet==3.0.3
|
| 64 |
grpcio==1.64.1
|
|
|
|
| 65 |
h11==0.14.0
|
| 66 |
hexbytes==0.3.1
|
| 67 |
html5lib==1.1
|
| 68 |
httpcore==1.0.5
|
|
|
|
| 69 |
httpx==0.27.0
|
| 70 |
huggingface-hub==0.23.3
|
| 71 |
idna==3.7
|
|
@@ -92,6 +102,7 @@ langchainhub==0.1.20
|
|
| 92 |
langgraph==0.0.68
|
| 93 |
langsmith==0.1.77
|
| 94 |
Lazify==0.4.0
|
|
|
|
| 95 |
literalai==0.0.604
|
| 96 |
logfire==0.42.0
|
| 97 |
lru-dict==1.2.0
|
|
@@ -104,6 +115,7 @@ mdurl==0.1.2
|
|
| 104 |
mistune==3.0.2
|
| 105 |
multidict==6.0.5
|
| 106 |
multitasking==0.0.11
|
|
|
|
| 107 |
mypy-extensions==1.0.0
|
| 108 |
nbclient==0.10.0
|
| 109 |
nbconvert==7.16.4
|
|
@@ -111,6 +123,7 @@ nbformat==5.10.4
|
|
| 111 |
nest-asyncio==1.6.0
|
| 112 |
numexpr==2.10.0
|
| 113 |
numpy==1.26.4
|
|
|
|
| 114 |
openai==1.34.0
|
| 115 |
opentelemetry-api==1.25.0
|
| 116 |
opentelemetry-exporter-otlp==1.25.0
|
|
@@ -142,6 +155,7 @@ pickleshare==0.7.5
|
|
| 142 |
pipdeptree==2.22.0
|
| 143 |
pipreqs==0.5.0
|
| 144 |
platformdirs==4.2.2
|
|
|
|
| 145 |
prompt_toolkit==3.0.47
|
| 146 |
protobuf==4.25.3
|
| 147 |
psutil==5.9.8
|
|
@@ -149,6 +163,7 @@ psycopg==3.1.19
|
|
| 149 |
psycopg2==2.9.9
|
| 150 |
ptyprocess==0.7.0
|
| 151 |
pure-eval==0.2.2
|
|
|
|
| 152 |
pycryptodome==3.20.0
|
| 153 |
pydantic==2.7.4
|
| 154 |
pydantic-settings==2.3.3
|
|
@@ -175,6 +190,7 @@ rich==13.7.1
|
|
| 175 |
rlp==4.0.1
|
| 176 |
rpc.py==0.6.0
|
| 177 |
rpds-py==0.18.1
|
|
|
|
| 178 |
s3fs==2024.6.0
|
| 179 |
s3transfer==0.10.1
|
| 180 |
shellingham==1.5.4
|
|
@@ -202,11 +218,13 @@ types-requests==2.32.0.20240602
|
|
| 202 |
typing-inspect==0.9.0
|
| 203 |
typing_extensions==4.12.2
|
| 204 |
tzdata==2024.1
|
|
|
|
| 205 |
ulid==1.1
|
| 206 |
upstash-redis==1.1.0
|
| 207 |
uptrace==1.24.0
|
| 208 |
urllib3==2.2.1
|
| 209 |
-
uvicorn==0.
|
|
|
|
| 210 |
watchfiles==0.20.0
|
| 211 |
wcwidth==0.2.13
|
| 212 |
web3==6.19.0
|
|
|
|
| 8 |
anyio==3.7.1
|
| 9 |
appdirs==1.4.4
|
| 10 |
appnope==0.1.4
|
| 11 |
+
APScheduler==3.10.4
|
| 12 |
asgiref==3.8.1
|
| 13 |
asttokens==2.4.1
|
| 14 |
async-timeout==4.0.3
|
| 15 |
asyncer==0.0.2
|
| 16 |
attrs==23.2.0
|
| 17 |
backcall==0.2.0
|
| 18 |
+
backoff==2.2.1
|
| 19 |
baize==0.20.8
|
| 20 |
beautifulsoup4==4.12.3
|
| 21 |
bidict==0.23.1
|
|
|
|
| 23 |
bleach==6.1.0
|
| 24 |
boto3==1.34.106
|
| 25 |
botocore==1.34.106
|
| 26 |
+
cached-property==1.5.2
|
| 27 |
certifi==2024.6.2
|
| 28 |
+
cffi==1.16.0
|
| 29 |
chainlit==1.1.300
|
| 30 |
charset-normalizer==3.3.2
|
|
|
|
| 31 |
chevron==0.14.0
|
| 32 |
ckzg==1.0.2
|
| 33 |
click==8.1.7
|
| 34 |
coingecko==0.13
|
| 35 |
+
cryptography==42.0.8
|
| 36 |
cytoolz==0.12.3
|
| 37 |
dataclasses-json==0.5.14
|
| 38 |
decorator==5.1.1
|
| 39 |
defusedxml==0.7.1
|
| 40 |
Deprecated==1.2.14
|
| 41 |
distro==1.9.0
|
| 42 |
+
dnspython==2.6.1
|
| 43 |
docopt==0.6.2
|
| 44 |
duckduckgo_search==6.1.6
|
| 45 |
+
email_validator==2.2.0
|
| 46 |
eth-account==0.11.2
|
| 47 |
eth-hash==0.7.0
|
| 48 |
eth-keyfile==0.8.1
|
|
|
|
| 53 |
eth_abi==5.1.0
|
| 54 |
exceptiongroup==1.2.1
|
| 55 |
executing==2.0.1
|
| 56 |
+
fastapi==0.111.1
|
| 57 |
+
fastapi-cli==0.0.4
|
| 58 |
+
fastapi-sso==0.10.0
|
| 59 |
fastjsonschema==2.19.1
|
| 60 |
filelock==3.15.1
|
| 61 |
filetype==1.2.0
|
|
|
|
| 70 |
googleapis-common-protos==1.63.1
|
| 71 |
greenlet==3.0.3
|
| 72 |
grpcio==1.64.1
|
| 73 |
+
gunicorn==22.0.0
|
| 74 |
h11==0.14.0
|
| 75 |
hexbytes==0.3.1
|
| 76 |
html5lib==1.1
|
| 77 |
httpcore==1.0.5
|
| 78 |
+
httptools==0.6.1
|
| 79 |
httpx==0.27.0
|
| 80 |
huggingface-hub==0.23.3
|
| 81 |
idna==3.7
|
|
|
|
| 102 |
langgraph==0.0.68
|
| 103 |
langsmith==0.1.77
|
| 104 |
Lazify==0.4.0
|
| 105 |
+
litellm==1.41.21
|
| 106 |
literalai==0.0.604
|
| 107 |
logfire==0.42.0
|
| 108 |
lru-dict==1.2.0
|
|
|
|
| 115 |
mistune==3.0.2
|
| 116 |
multidict==6.0.5
|
| 117 |
multitasking==0.0.11
|
| 118 |
+
mypy==1.10.1
|
| 119 |
mypy-extensions==1.0.0
|
| 120 |
nbclient==0.10.0
|
| 121 |
nbconvert==7.16.4
|
|
|
|
| 123 |
nest-asyncio==1.6.0
|
| 124 |
numexpr==2.10.0
|
| 125 |
numpy==1.26.4
|
| 126 |
+
oauthlib==3.2.2
|
| 127 |
openai==1.34.0
|
| 128 |
opentelemetry-api==1.25.0
|
| 129 |
opentelemetry-exporter-otlp==1.25.0
|
|
|
|
| 155 |
pipdeptree==2.22.0
|
| 156 |
pipreqs==0.5.0
|
| 157 |
platformdirs==4.2.2
|
| 158 |
+
portkey-ai==1.7.0
|
| 159 |
prompt_toolkit==3.0.47
|
| 160 |
protobuf==4.25.3
|
| 161 |
psutil==5.9.8
|
|
|
|
| 163 |
psycopg2==2.9.9
|
| 164 |
ptyprocess==0.7.0
|
| 165 |
pure-eval==0.2.2
|
| 166 |
+
pycparser==2.22
|
| 167 |
pycryptodome==3.20.0
|
| 168 |
pydantic==2.7.4
|
| 169 |
pydantic-settings==2.3.3
|
|
|
|
| 190 |
rlp==4.0.1
|
| 191 |
rpc.py==0.6.0
|
| 192 |
rpds-py==0.18.1
|
| 193 |
+
rq==1.16.2
|
| 194 |
s3fs==2024.6.0
|
| 195 |
s3transfer==0.10.1
|
| 196 |
shellingham==1.5.4
|
|
|
|
| 218 |
typing-inspect==0.9.0
|
| 219 |
typing_extensions==4.12.2
|
| 220 |
tzdata==2024.1
|
| 221 |
+
tzlocal==5.2
|
| 222 |
ulid==1.1
|
| 223 |
upstash-redis==1.1.0
|
| 224 |
uptrace==1.24.0
|
| 225 |
urllib3==2.2.1
|
| 226 |
+
uvicorn==0.22.0
|
| 227 |
+
uvloop==0.19.0
|
| 228 |
watchfiles==0.20.0
|
| 229 |
wcwidth==0.2.13
|
| 230 |
web3==6.19.0
|
src/config/nemoguardrails/config.yml
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# config.yml
|
| 2 |
+
models:
|
| 3 |
+
- type: main
|
| 4 |
+
engine: openai
|
| 5 |
+
model: gpt-3.5-turbo-instruct
|
| 6 |
+
|
| 7 |
+
rails:
|
| 8 |
+
# Input rails are invoked when new input from the user is received.
|
| 9 |
+
input:
|
| 10 |
+
flows:
|
| 11 |
+
- check jailbreak
|
| 12 |
+
- mask sensitive data on input
|
| 13 |
+
|
| 14 |
+
# Output rails are triggered after a bot message has been generated.
|
| 15 |
+
output:
|
| 16 |
+
flows:
|
| 17 |
+
- self check facts
|
| 18 |
+
- self check hallucination
|
| 19 |
+
- activefence moderation
|
| 20 |
+
|
| 21 |
+
config:
|
| 22 |
+
# Configure the types of entities that should be masked on user input.
|
| 23 |
+
sensitive_data_detection:
|
| 24 |
+
input:
|
| 25 |
+
entities:
|
| 26 |
+
- PERSON
|
| 27 |
+
- EMAIL_ADDRESS
|
src/config/portkey_config.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
def generate_portkey_config(local: bool = True):
|
| 5 |
+
if local:
|
| 6 |
+
config = {
|
| 7 |
+
"strategy": {
|
| 8 |
+
"mode": "fallback"
|
| 9 |
+
},
|
| 10 |
+
"cache": {
|
| 11 |
+
"mode": "semantic",
|
| 12 |
+
"max_age": 10000
|
| 13 |
+
},
|
| 14 |
+
"retry": {
|
| 15 |
+
"attempts": 3,
|
| 16 |
+
"on_status_codes": [429]
|
| 17 |
+
},
|
| 18 |
+
"targets": [
|
| 19 |
+
# {
|
| 20 |
+
# "provider": "mistral-ai",
|
| 21 |
+
# "api_key": os.getenv("MISTRAL_API_KEY"),
|
| 22 |
+
# "override_params": {
|
| 23 |
+
# "model": "codestral-latest",
|
| 24 |
+
# "max_tokens": 1024,
|
| 25 |
+
# "temperature": 0
|
| 26 |
+
# }
|
| 27 |
+
# },
|
| 28 |
+
{
|
| 29 |
+
"provider": "anthropic",
|
| 30 |
+
"api_key": os.getenv("ANTHROPIC_API_KEY"),
|
| 31 |
+
"override_params": {
|
| 32 |
+
"model": "claude-3-5-sonnet-20240620",
|
| 33 |
+
"max_tokens": 1024,
|
| 34 |
+
"temperature": 0
|
| 35 |
+
}
|
| 36 |
+
},
|
| 37 |
+
{
|
| 38 |
+
"provider": "openai",
|
| 39 |
+
"api_key": os.getenv("OPENAI_API_KEY"),
|
| 40 |
+
"override_params": {
|
| 41 |
+
"model": "gpt-4o",
|
| 42 |
+
"max_tokens": 1024,
|
| 43 |
+
"temperature": 0
|
| 44 |
+
}
|
| 45 |
+
},
|
| 46 |
+
{
|
| 47 |
+
"provider": "anthropic",
|
| 48 |
+
"api_key": os.getenv("ANTHROPIC_API_KEY"),
|
| 49 |
+
"override_params": {
|
| 50 |
+
"model": "claude-3-opus-20240229",
|
| 51 |
+
"max_tokens": 1024,
|
| 52 |
+
"temperature": 0
|
| 53 |
+
}
|
| 54 |
+
}
|
| 55 |
+
]
|
| 56 |
+
}
|
| 57 |
+
else:
|
| 58 |
+
config = {
|
| 59 |
+
"strategy": {
|
| 60 |
+
"mode": "fallback"
|
| 61 |
+
},
|
| 62 |
+
"cache": {
|
| 63 |
+
"mode": "semantic",
|
| 64 |
+
"max_age": 10000
|
| 65 |
+
},
|
| 66 |
+
"retry": {
|
| 67 |
+
"attempts": 3,
|
| 68 |
+
"on_status_codes": [429]
|
| 69 |
+
},
|
| 70 |
+
"targets": [
|
| 71 |
+
|
| 72 |
+
{
|
| 73 |
+
"virtual_key": os.getenv("PORTKEY_OPENAI_VIRTUAL_KEY"),
|
| 74 |
+
"override_params": {
|
| 75 |
+
"model": "gpt-4o",
|
| 76 |
+
"max_tokens": 1024,
|
| 77 |
+
"temperature": 0
|
| 78 |
+
}
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
"provider": "anthropic",
|
| 82 |
+
"api_key": os.getenv("POETRY_ANTHROPIC_API_KEY"),
|
| 83 |
+
"override_params": {
|
| 84 |
+
"model": "claude-3-5-sonnet-20240620",
|
| 85 |
+
"max_tokens": 1024,
|
| 86 |
+
"temperature": 0
|
| 87 |
+
}
|
| 88 |
+
},
|
| 89 |
+
{
|
| 90 |
+
"virtual_key": os.getenv("PORTKEY_ANTHROPIC_API_KEY"),
|
| 91 |
+
"override_params": {
|
| 92 |
+
"model": "claude-3-opus-20240229",
|
| 93 |
+
"max_tokens": 1024,
|
| 94 |
+
"temperature": 0
|
| 95 |
+
}
|
| 96 |
+
},
|
| 97 |
+
{
|
| 98 |
+
"virtual_key": os.getenv("PORTKEY_MISTRAL_API_KEY"),
|
| 99 |
+
"override_params": {
|
| 100 |
+
"model": "codestral-latest",
|
| 101 |
+
"max_tokens": 1024,
|
| 102 |
+
"temperature": 0
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
]
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
return json.dumps(config)
|
src/libs/rpc_client.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
| 1 |
import httpx, uuid, os
|
| 2 |
from typing import Optional, Union
|
| 3 |
from dotenv import load_dotenv
|
| 4 |
-
from src.libs.logger import logger
|
| 5 |
|
| 6 |
load_dotenv()
|
| 7 |
|
|
@@ -10,7 +9,8 @@ rpc_server_url = os.getenv('CHATXBT_RPC_SERVER_URL')
|
|
| 10 |
async def rpc_call(
|
| 11 |
method_name: str, # The name of the RPC method to be called
|
| 12 |
params: Optional[Union[dict, list]] = None, # Optional parameters for the RPC method
|
| 13 |
-
url: str = rpc_server_url # The URL of the RPC server
|
|
|
|
| 14 |
) -> dict: # Returns the JSON response from the RPC server
|
| 15 |
"""
|
| 16 |
This function makes an RPC call to the specified URL with the given method name and parameters.
|
|
@@ -44,10 +44,10 @@ async def rpc_call(
|
|
| 44 |
}
|
| 45 |
|
| 46 |
try:
|
| 47 |
-
async with httpx.AsyncClient() as client:
|
| 48 |
response = await client.post(url, json=payload, headers=headers, auth=auth)
|
| 49 |
response.raise_for_status()
|
| 50 |
return response.json()
|
| 51 |
except httpx.RequestError as e:
|
| 52 |
print(f"Error making RPC call: {e}")
|
| 53 |
-
|
|
|
|
| 1 |
import httpx, uuid, os
|
| 2 |
from typing import Optional, Union
|
| 3 |
from dotenv import load_dotenv
|
|
|
|
| 4 |
|
| 5 |
load_dotenv()
|
| 6 |
|
|
|
|
| 9 |
async def rpc_call(
|
| 10 |
method_name: str, # The name of the RPC method to be called
|
| 11 |
params: Optional[Union[dict, list]] = None, # Optional parameters for the RPC method
|
| 12 |
+
url: str = rpc_server_url, # The URL of the RPC server
|
| 13 |
+
timeout: int = 60 # Timeout in seconds
|
| 14 |
) -> dict: # Returns the JSON response from the RPC server
|
| 15 |
"""
|
| 16 |
This function makes an RPC call to the specified URL with the given method name and parameters.
|
|
|
|
| 44 |
}
|
| 45 |
|
| 46 |
try:
|
| 47 |
+
async with httpx.AsyncClient(timeout=timeout) as client:
|
| 48 |
response = await client.post(url, json=payload, headers=headers, auth=auth)
|
| 49 |
response.raise_for_status()
|
| 50 |
return response.json()
|
| 51 |
except httpx.RequestError as e:
|
| 52 |
print(f"Error making RPC call: {e}")
|
| 53 |
+
raise ValueError(f"Error making RPC call: {e}")
|
src/tools/crypto_bridge_toolkit.py
CHANGED
|
@@ -33,20 +33,22 @@ class CrossChainSwapTools(Toolkit):
|
|
| 33 |
chainId: int,
|
| 34 |
amountLD: str,
|
| 35 |
recipient: str,
|
| 36 |
-
|
| 37 |
-
tokenIn:
|
| 38 |
-
tokenOut:
|
|
|
|
| 39 |
) -> str:
|
| 40 |
"""
|
| 41 |
-
Performs a cross-chain token swap.
|
| 42 |
|
| 43 |
Parameters:
|
| 44 |
- chainId (int): The ID of the chain.
|
| 45 |
- amountLD (str): The amount to be swapped, in lowest denomination (e.g., wei for ETH).
|
| 46 |
- recipient (str): The recipient address.
|
| 47 |
-
-
|
| 48 |
-
- tokenIn (TokenParams): The input token parameters.
|
| 49 |
-
- tokenOut (TokenParams): The output token parameters.
|
|
|
|
| 50 |
|
| 51 |
Returns:
|
| 52 |
- str: A string representation of the response from the RPC call.
|
|
@@ -63,7 +65,13 @@ class CrossChainSwapTools(Toolkit):
|
|
| 63 |
'chainId': chainId,
|
| 64 |
'amountLD': amountLD,
|
| 65 |
'recipient': recipient,
|
| 66 |
-
'wallet':
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
'tokenIn': tokenIn,
|
| 68 |
'tokenOut': tokenOut,
|
| 69 |
}
|
|
@@ -95,7 +103,8 @@ class CrossChainSwapTools(Toolkit):
|
|
| 95 |
|
| 96 |
def get_cross_chain_swap_token_list(self, chainId: int) -> str:
|
| 97 |
"""
|
| 98 |
-
Fetches the list of supported cross-chain swap tokens on the specified chainId.
|
|
|
|
| 99 |
|
| 100 |
Parameters:
|
| 101 |
- chainId (int): The ID of the chain.
|
|
|
|
| 33 |
chainId: int,
|
| 34 |
amountLD: str,
|
| 35 |
recipient: str,
|
| 36 |
+
user_email: str,
|
| 37 |
+
tokenIn: str,
|
| 38 |
+
tokenOut: str,
|
| 39 |
+
chain: str = "base",
|
| 40 |
) -> str:
|
| 41 |
"""
|
| 42 |
+
Performs a cross-chain token swap. this is a sensitive function, show a preview and allow user to give final permission to execute function
|
| 43 |
|
| 44 |
Parameters:
|
| 45 |
- chainId (int): The ID of the chain.
|
| 46 |
- amountLD (str): The amount to be swapped, in lowest denomination (e.g., wei for ETH).
|
| 47 |
- recipient (str): The recipient address.
|
| 48 |
+
- user_email (str): The email of the user for whom the wallet is being fetched and used to sign the transaction.
|
| 49 |
+
- tokenIn (TokenParams): The input token parameters as structured from: get_cross_chain_swap_token_list. stringify object
|
| 50 |
+
- tokenOut (TokenParams): The output token parameters as structured from: get_cross_chain_swap_token_list. stringify object
|
| 51 |
+
- chain (str): The EVM chain for which the wallet is being fetched and used to execute this transaction. use chain base as default
|
| 52 |
|
| 53 |
Returns:
|
| 54 |
- str: A string representation of the response from the RPC call.
|
|
|
|
| 65 |
'chainId': chainId,
|
| 66 |
'amountLD': amountLD,
|
| 67 |
'recipient': recipient,
|
| 68 |
+
'wallet': {
|
| 69 |
+
"userEmail": user_email,
|
| 70 |
+
"chain": chain,
|
| 71 |
+
"testnet": True,
|
| 72 |
+
"gasless": True,
|
| 73 |
+
"connected": True
|
| 74 |
+
},
|
| 75 |
'tokenIn': tokenIn,
|
| 76 |
'tokenOut': tokenOut,
|
| 77 |
}
|
|
|
|
| 103 |
|
| 104 |
def get_cross_chain_swap_token_list(self, chainId: int) -> str:
|
| 105 |
"""
|
| 106 |
+
Fetches the list of supported cross-chain swap tokens on the specified chainId. always call before executing
|
| 107 |
+
cross_chain_swap to get accurate tokenIn and tokenOut data
|
| 108 |
|
| 109 |
Parameters:
|
| 110 |
- chainId (int): The ID of the chain.
|
src/tools/crypto_evm_wallet_toolkit.py
CHANGED
|
@@ -9,9 +9,12 @@ class CryptoEVMWalletTools(Toolkit):
|
|
| 9 |
super().__init__(name="crypto_evm_wallet_tools")
|
| 10 |
|
| 11 |
# Registering methods to make them accessible via the toolkit
|
| 12 |
-
self.register(self.get_evm_wallet_address)
|
| 13 |
self.register(self.get_supported_evm_chains)
|
| 14 |
self.register(self.get_evm_smart_wallet_address)
|
|
|
|
|
|
|
|
|
|
| 15 |
self.chains = self.get_supported_evm_chains()
|
| 16 |
|
| 17 |
def get_supported_evm_chains(self) -> list[str]:
|
|
@@ -30,14 +33,50 @@ class CryptoEVMWalletTools(Toolkit):
|
|
| 30 |
response = asyncio.run(rpc_call(method_name="getEVMSupportedChains", params=params))
|
| 31 |
return f"{response}"
|
| 32 |
|
| 33 |
-
def get_evm_wallet_address(self, user_email: str, chain: str, testnet: bool = True) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
"""
|
| 35 |
-
Fetches
|
| 36 |
-
Creates and returns
|
| 37 |
|
| 38 |
Parameters:
|
| 39 |
-
- user_email (str): The email of the user for whom the wallet is being
|
| 40 |
- chain (ethereum | binance | base | polygon): The EVM chain for which the wallet is being fetched.
|
|
|
|
| 41 |
- testnet (bool, optional): A flag indicating whether the wallet should be on the testnet. Defaults to `True`.
|
| 42 |
|
| 43 |
Returns:
|
|
@@ -47,37 +86,37 @@ class CryptoEVMWalletTools(Toolkit):
|
|
| 47 |
None
|
| 48 |
|
| 49 |
Note:
|
| 50 |
-
This method uses asyncio.run() to run the asynchronous RPC call.
|
| 51 |
"""
|
| 52 |
-
logger.info(f"
|
| 53 |
|
| 54 |
params = {
|
| 55 |
'chain': chain,
|
|
|
|
| 56 |
'testnet': testnet,
|
| 57 |
'userEmail': user_email,
|
| 58 |
}
|
| 59 |
-
response = asyncio.run(rpc_call(method_name="
|
| 60 |
return f"{response}"
|
| 61 |
|
| 62 |
-
def
|
| 63 |
self,
|
|
|
|
| 64 |
user_email: str,
|
| 65 |
chain: str,
|
| 66 |
-
gasless: bool = True,
|
| 67 |
testnet: bool = True
|
| 68 |
) -> str:
|
| 69 |
"""
|
| 70 |
-
Fetches a smart EVM wallet address for the given user email and supported chain.
|
| 71 |
-
Creates and returns a smart EVM wallet address for the given user email and supported chain.
|
| 72 |
|
| 73 |
Parameters:
|
|
|
|
| 74 |
- user_email (str): The email of the user for whom the wallet is being fetched.
|
| 75 |
-
- chain (
|
| 76 |
-
- gasless (bool, optional): A flag indicating whether the wallet should be gasless. Defaults to `True`.
|
| 77 |
- testnet (bool, optional): A flag indicating whether the wallet should be on the testnet. Defaults to `True`.
|
| 78 |
|
| 79 |
Returns:
|
| 80 |
-
- str: A string representation of the response from the RPC call.
|
| 81 |
|
| 82 |
Raises:
|
| 83 |
None
|
|
@@ -89,9 +128,9 @@ class CryptoEVMWalletTools(Toolkit):
|
|
| 89 |
|
| 90 |
params = {
|
| 91 |
'chain': chain,
|
| 92 |
-
'
|
| 93 |
'testnet': testnet,
|
| 94 |
'userEmail': user_email,
|
| 95 |
}
|
| 96 |
-
response = asyncio.run(rpc_call(method_name="
|
| 97 |
return f"{response}"
|
|
|
|
| 9 |
super().__init__(name="crypto_evm_wallet_tools")
|
| 10 |
|
| 11 |
# Registering methods to make them accessible via the toolkit
|
| 12 |
+
# self.register(self.get_evm_wallet_address)
|
| 13 |
self.register(self.get_supported_evm_chains)
|
| 14 |
self.register(self.get_evm_smart_wallet_address)
|
| 15 |
+
self.register(self.get_evm_smart_wallet_balances)
|
| 16 |
+
|
| 17 |
+
# Fetching the list of supported EVM chains
|
| 18 |
self.chains = self.get_supported_evm_chains()
|
| 19 |
|
| 20 |
def get_supported_evm_chains(self) -> list[str]:
|
|
|
|
| 33 |
response = asyncio.run(rpc_call(method_name="getEVMSupportedChains", params=params))
|
| 34 |
return f"{response}"
|
| 35 |
|
| 36 |
+
# def get_evm_wallet_address(self, user_email: str, chain: str, testnet: bool = True) -> str:
|
| 37 |
+
# """
|
| 38 |
+
# Fetches an EVM wallet address for the given user email and supported chain.
|
| 39 |
+
# Creates and returns an EVM wallet address for the given user email and supported chain.
|
| 40 |
+
|
| 41 |
+
# Parameters:
|
| 42 |
+
# - user_email (str): The email of the user for whom the wallet is being created.
|
| 43 |
+
# - chain (ethereum | binance | base | polygon): The EVM chain for which the wallet is being fetched.
|
| 44 |
+
# - testnet (bool, optional): A flag indicating whether the wallet should be on the testnet. Defaults to `True`.
|
| 45 |
+
|
| 46 |
+
# Returns:
|
| 47 |
+
# - str: A string representation of the response from the RPC call.
|
| 48 |
+
|
| 49 |
+
# Raises:
|
| 50 |
+
# None
|
| 51 |
+
|
| 52 |
+
# Note:
|
| 53 |
+
# This method uses asyncio.run() to run the asynchronous RPC call.
|
| 54 |
+
# """
|
| 55 |
+
# logger.info(f"Creating crypto wallet account for {user_email}")
|
| 56 |
+
|
| 57 |
+
# params = {
|
| 58 |
+
# 'chain': chain,
|
| 59 |
+
# 'testnet': testnet,
|
| 60 |
+
# 'userEmail': user_email,
|
| 61 |
+
# }
|
| 62 |
+
# response = asyncio.run(rpc_call(method_name="getEVMWallet", params=params))
|
| 63 |
+
# return f"{response}"
|
| 64 |
+
|
| 65 |
+
def get_evm_smart_wallet_address(
|
| 66 |
+
self,
|
| 67 |
+
user_email: str,
|
| 68 |
+
chain: str,
|
| 69 |
+
gasless: bool = True,
|
| 70 |
+
testnet: bool = True
|
| 71 |
+
) -> str:
|
| 72 |
"""
|
| 73 |
+
Fetches a smart EVM wallet address for the given user email and supported chain.
|
| 74 |
+
Creates and returns a smart EVM wallet address for the given user email and supported chain.
|
| 75 |
|
| 76 |
Parameters:
|
| 77 |
+
- user_email (str): The email of the user for whom the wallet is being fetched.
|
| 78 |
- chain (ethereum | binance | base | polygon): The EVM chain for which the wallet is being fetched.
|
| 79 |
+
- gasless (bool, optional): A flag indicating whether the wallet should be gasless. Defaults to `True`.
|
| 80 |
- testnet (bool, optional): A flag indicating whether the wallet should be on the testnet. Defaults to `True`.
|
| 81 |
|
| 82 |
Returns:
|
|
|
|
| 86 |
None
|
| 87 |
|
| 88 |
Note:
|
| 89 |
+
This method uses `asyncio.run()` to run the asynchronous RPC call.
|
| 90 |
"""
|
| 91 |
+
logger.info(f"Fetching crypto wallet account for {user_email}")
|
| 92 |
|
| 93 |
params = {
|
| 94 |
'chain': chain,
|
| 95 |
+
'gasless': gasless,
|
| 96 |
'testnet': testnet,
|
| 97 |
'userEmail': user_email,
|
| 98 |
}
|
| 99 |
+
response = asyncio.run(rpc_call(method_name="getEVMSmartWallet", params=params))
|
| 100 |
return f"{response}"
|
| 101 |
|
| 102 |
+
def get_evm_smart_wallet_balances(
|
| 103 |
self,
|
| 104 |
+
address: str,
|
| 105 |
user_email: str,
|
| 106 |
chain: str,
|
|
|
|
| 107 |
testnet: bool = True
|
| 108 |
) -> str:
|
| 109 |
"""
|
| 110 |
+
Fetches the balances of a smart EVM wallet address for the given user email and supported chain.
|
|
|
|
| 111 |
|
| 112 |
Parameters:
|
| 113 |
+
- address (str): The address of the smart EVM wallet for which the balances are being fetched.
|
| 114 |
- user_email (str): The email of the user for whom the wallet is being fetched.
|
| 115 |
+
- chain (str): The EVM chain for which the wallet is being fetched.
|
|
|
|
| 116 |
- testnet (bool, optional): A flag indicating whether the wallet should be on the testnet. Defaults to `True`.
|
| 117 |
|
| 118 |
Returns:
|
| 119 |
+
- str: A string representation of the response from the RPC call containing the balances of the smart EVM wallet address.
|
| 120 |
|
| 121 |
Raises:
|
| 122 |
None
|
|
|
|
| 128 |
|
| 129 |
params = {
|
| 130 |
'chain': chain,
|
| 131 |
+
'address': address,
|
| 132 |
'testnet': testnet,
|
| 133 |
'userEmail': user_email,
|
| 134 |
}
|
| 135 |
+
response = asyncio.run(rpc_call(method_name="getEVMSmartWalletAddressBalances", params=params))
|
| 136 |
return f"{response}"
|
src/tools/crypto_swap_toolkit.py
CHANGED
|
@@ -26,7 +26,7 @@ class CryptoSwapTools(Toolkit):
|
|
| 26 |
self.register(self.get_swap_sources)
|
| 27 |
self.register(self.execute_swap)
|
| 28 |
|
| 29 |
-
def get_swap_quote(self, buy_token: str, sell_token: str, sell_amount: str) -> str:
|
| 30 |
"""
|
| 31 |
Fetches a swap quote from the 0x Swap API.
|
| 32 |
|
|
@@ -46,7 +46,14 @@ class CryptoSwapTools(Toolkit):
|
|
| 46 |
params = {
|
| 47 |
'buyToken': buy_token,
|
| 48 |
'sellToken': sell_token,
|
| 49 |
-
'sellAmount': sell_amount
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
}
|
| 51 |
response = asyncio.run(rpc_call(method_name="getSwapQuote", params=params))
|
| 52 |
return f"{response}"
|
|
@@ -55,7 +62,7 @@ class CryptoSwapTools(Toolkit):
|
|
| 55 |
# return {"error": str(e)}
|
| 56 |
return f"Error: {e}"
|
| 57 |
|
| 58 |
-
def get_swap_price(self, buy_token: str, sell_token: str, buy_amount: str) -> str:
|
| 59 |
"""
|
| 60 |
Fetches the price for a swap from the 0x Swap API.
|
| 61 |
|
|
@@ -75,7 +82,14 @@ class CryptoSwapTools(Toolkit):
|
|
| 75 |
params = {
|
| 76 |
'buyToken': buy_token,
|
| 77 |
'sellToken': sell_token,
|
| 78 |
-
'buyAmount': buy_amount
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
}
|
| 80 |
response = asyncio.run(rpc_call(method_name="getSwapPrice", params=params))
|
| 81 |
return f"{response}"
|
|
@@ -99,35 +113,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 |
-
|
|
|
|
| 119 |
try:
|
| 120 |
params = {
|
| 121 |
'buyToken': buy_token,
|
| 122 |
'sellToken': sell_token,
|
| 123 |
'sellAmount': sell_amount,
|
| 124 |
'wallet': {
|
| 125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
}
|
| 127 |
}
|
| 128 |
response = asyncio.run(rpc_call(method_name="swapTokens", params=params))
|
|
|
|
| 129 |
return f"{response}"
|
| 130 |
except requests.exceptions.RequestException as e:
|
| 131 |
-
logger.warning(f"Failed to swap
|
| 132 |
# return {"error": str(e)}
|
| 133 |
return f"Error: {e}"
|
|
|
|
| 26 |
self.register(self.get_swap_sources)
|
| 27 |
self.register(self.execute_swap)
|
| 28 |
|
| 29 |
+
def get_swap_quote(self, buy_token: str, sell_token: str, sell_amount: str, chain: str = "base") -> str:
|
| 30 |
"""
|
| 31 |
Fetches a swap quote from the 0x Swap API.
|
| 32 |
|
|
|
|
| 46 |
params = {
|
| 47 |
'buyToken': buy_token,
|
| 48 |
'sellToken': sell_token,
|
| 49 |
+
'sellAmount': sell_amount,
|
| 50 |
+
'wallet': {
|
| 51 |
+
"userEmail": "none",
|
| 52 |
+
"chain": chain,
|
| 53 |
+
"testnet": True,
|
| 54 |
+
"gasless": True,
|
| 55 |
+
"connected": True
|
| 56 |
+
}
|
| 57 |
}
|
| 58 |
response = asyncio.run(rpc_call(method_name="getSwapQuote", params=params))
|
| 59 |
return f"{response}"
|
|
|
|
| 62 |
# return {"error": str(e)}
|
| 63 |
return f"Error: {e}"
|
| 64 |
|
| 65 |
+
def get_swap_price(self, buy_token: str, sell_token: str, buy_amount: str, chain: str = "base") -> str:
|
| 66 |
"""
|
| 67 |
Fetches the price for a swap from the 0x Swap API.
|
| 68 |
|
|
|
|
| 82 |
params = {
|
| 83 |
'buyToken': buy_token,
|
| 84 |
'sellToken': sell_token,
|
| 85 |
+
'buyAmount': buy_amount,
|
| 86 |
+
'wallet': {
|
| 87 |
+
"userEmail": "none",
|
| 88 |
+
"chain": chain,
|
| 89 |
+
"testnet": True,
|
| 90 |
+
"gasless": True,
|
| 91 |
+
"connected": True
|
| 92 |
+
}
|
| 93 |
}
|
| 94 |
response = asyncio.run(rpc_call(method_name="getSwapPrice", params=params))
|
| 95 |
return f"{response}"
|
|
|
|
| 113 |
response = asyncio.run(rpc_call(method_name="getSwapSources"))
|
| 114 |
return f"{response}"
|
| 115 |
|
| 116 |
+
def execute_swap(
|
| 117 |
+
self,
|
| 118 |
+
buy_token: str,
|
| 119 |
+
sell_token: str,
|
| 120 |
+
sell_amount: str,
|
| 121 |
+
user_email: str,
|
| 122 |
+
chain: str = "base",
|
| 123 |
+
) -> str:
|
| 124 |
"""
|
| 125 |
+
Executes a swap using the 0x Swap API. this is a sensitive function, show a preview and allow user to give final permission to execute function
|
| 126 |
|
| 127 |
Args:
|
| 128 |
+
-buy_token (str): The token to buy (e.g., 'DAI').
|
| 129 |
+
-sell_token (str): The token to sell (e.g., 'ETH').
|
| 130 |
+
-sell_amount (str): The amount of the sell token to swap, in the smallest unit (e.g., wei for ETH).
|
| 131 |
+
- user_email (str): The email of the user for whom the wallet is being fetched.
|
| 132 |
+
- chain (str): The EVM chain for which the wallet is being fetched and used to execute this transaction. use chain base as default
|
| 133 |
|
| 134 |
Returns:
|
| 135 |
dict: The transaction receipt of the swap transaction.
|
| 136 |
|
| 137 |
Example:
|
| 138 |
+
>>> execute_swap('DAI', 'ETH', '1000000000000000000', 'userEmail', 'base')
|
| 139 |
"""
|
| 140 |
+
|
| 141 |
+
logger.info("executing swap")
|
| 142 |
try:
|
| 143 |
params = {
|
| 144 |
'buyToken': buy_token,
|
| 145 |
'sellToken': sell_token,
|
| 146 |
'sellAmount': sell_amount,
|
| 147 |
'wallet': {
|
| 148 |
+
"userEmail": user_email,
|
| 149 |
+
"chain": chain,
|
| 150 |
+
"testnet": True,
|
| 151 |
+
"gasless": True,
|
| 152 |
+
"connected": True
|
| 153 |
}
|
| 154 |
}
|
| 155 |
response = asyncio.run(rpc_call(method_name="swapTokens", params=params))
|
| 156 |
+
logger.info(f"Swap transaction receipt: {response}")
|
| 157 |
return f"{response}"
|
| 158 |
except requests.exceptions.RequestException as e:
|
| 159 |
+
logger.warning(f"Failed to execute swap: {e}")
|
| 160 |
# return {"error": str(e)}
|
| 161 |
return f"Error: {e}"
|
src/tools/user_confirmation_pin_toolkit.py
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import asyncio
|
| 2 |
+
import chainlit as cl
|
| 3 |
+
from phi.tools import Toolkit
|
| 4 |
+
from phi.utils.log import logger
|
| 5 |
+
|
| 6 |
+
from src.libs.rpc_client import rpc_call
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class UserConfirmationPinToolkit(Toolkit):
|
| 10 |
+
def __init__(self):
|
| 11 |
+
super().__init__(name="user_confirmation_pin_toolkit")
|
| 12 |
+
|
| 13 |
+
# Registering methods to make them accessible via the toolkit
|
| 14 |
+
self.register(self.has_user_confirmation_pin)
|
| 15 |
+
self.register(self.set_user_confirmation_pin)
|
| 16 |
+
self.register(self.update_user_confirmation_pin)
|
| 17 |
+
self.register(self.verify_user_confirmation_pin)
|
| 18 |
+
|
| 19 |
+
def has_user_confirmation_pin(self, user_id: str) -> str:
|
| 20 |
+
"""
|
| 21 |
+
Checks if a user has a confirmation PIN.
|
| 22 |
+
|
| 23 |
+
This method takes a user's ID and checks if the user has a confirmation
|
| 24 |
+
PIN via a remote procedure call (RPC).
|
| 25 |
+
|
| 26 |
+
Args:
|
| 27 |
+
user_id (str): The ID of the user to check for a confirmation PIN.
|
| 28 |
+
|
| 29 |
+
Returns:
|
| 30 |
+
str: The response from the RPC call indicating if the user has a PIN.
|
| 31 |
+
"""
|
| 32 |
+
logger.info("Checking if user has confirmation pin")
|
| 33 |
+
|
| 34 |
+
params = {
|
| 35 |
+
"userId": user_id,
|
| 36 |
+
}
|
| 37 |
+
response = asyncio.run(rpc_call(method_name="hasUserPin", params=params))
|
| 38 |
+
return f"{response}"
|
| 39 |
+
|
| 40 |
+
def set_user_confirmation_pin(self, user_id: str, pin: str) -> str:
|
| 41 |
+
"""
|
| 42 |
+
Sets a user's confirmation PIN.
|
| 43 |
+
|
| 44 |
+
This method takes a user's ID and a new PIN, and sets the user's PIN
|
| 45 |
+
via a remote procedure call (RPC).
|
| 46 |
+
|
| 47 |
+
Args:
|
| 48 |
+
user_id (str): The ID of the user whose PIN is to be set.
|
| 49 |
+
pin (str): The new confirmation PIN to be set.
|
| 50 |
+
|
| 51 |
+
Returns:
|
| 52 |
+
str: The response from the RPC call setting the PIN.
|
| 53 |
+
"""
|
| 54 |
+
logger.info("Setting user confirmation pin")
|
| 55 |
+
|
| 56 |
+
params = {
|
| 57 |
+
"userId": user_id,
|
| 58 |
+
"pin": pin
|
| 59 |
+
}
|
| 60 |
+
response = asyncio.run(rpc_call(method_name="setUserPin", params=params))
|
| 61 |
+
return f"{response}"
|
| 62 |
+
|
| 63 |
+
def update_user_confirmation_pin(self, user_id: str, pin: str) -> str:
|
| 64 |
+
"""
|
| 65 |
+
Updates a user's confirmation PIN.
|
| 66 |
+
|
| 67 |
+
This method takes a user's ID and a new PIN, and updates the user's PIN
|
| 68 |
+
via a remote procedure call (RPC).
|
| 69 |
+
|
| 70 |
+
Args:
|
| 71 |
+
user_id (str): The ID of the user whose PIN is to be updated.
|
| 72 |
+
pin (str): The new confirmation PIN to be set.
|
| 73 |
+
|
| 74 |
+
Returns:
|
| 75 |
+
str: The response from the RPC call updating the PIN.
|
| 76 |
+
"""
|
| 77 |
+
logger.info("Updating user confirmation pin")
|
| 78 |
+
|
| 79 |
+
params = {
|
| 80 |
+
"userId": user_id,
|
| 81 |
+
"pin": pin
|
| 82 |
+
}
|
| 83 |
+
response = asyncio.run(rpc_call(method_name="updateUserPin", params=params))
|
| 84 |
+
return f"{response}"
|
| 85 |
+
|
| 86 |
+
def verify_user_confirmation_pin(self, user_id: str, pin: str) -> str:
|
| 87 |
+
"""
|
| 88 |
+
Verifies a user's confirmation PIN.
|
| 89 |
+
|
| 90 |
+
This method takes a user's ID and a PIN, converts the email to lowercase,
|
| 91 |
+
and verifies the PIN via a remote procedure call (RPC).
|
| 92 |
+
|
| 93 |
+
Args:
|
| 94 |
+
user_id (str): The ID of the user whose PIN is to be verified.
|
| 95 |
+
pin (str): The confirmation PIN to be verified.
|
| 96 |
+
|
| 97 |
+
Returns:
|
| 98 |
+
str: The response from the RPC call verifying the PIN.
|
| 99 |
+
"""
|
| 100 |
+
logger.info("Verifying user confirmation pin")
|
| 101 |
+
|
| 102 |
+
params = {
|
| 103 |
+
"userId": user_id,
|
| 104 |
+
"pin": pin
|
| 105 |
+
}
|
| 106 |
+
response = asyncio.run(rpc_call(method_name="verifyUserPin", params=params))
|
| 107 |
+
return f"{response}"
|
src/tools/user_profile_toolkit.py
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
|
|
| 1 |
import chainlit as cl
|
| 2 |
from phi.tools import Toolkit
|
| 3 |
from phi.utils.log import logger
|
| 4 |
|
|
|
|
|
|
|
| 5 |
|
| 6 |
class UserProfileToolkit(Toolkit):
|
| 7 |
def __init__(self):
|
|
@@ -16,10 +19,13 @@ class UserProfileToolkit(Toolkit):
|
|
| 16 |
self.register(self.update_user_name)
|
| 17 |
self.register(self.update_user_email)
|
| 18 |
self.register(self.update_user_picture)
|
| 19 |
-
self.
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
@cl.on_chat_start
|
| 22 |
-
def get_user_info(self, info_type: str
|
| 23 |
"""
|
| 24 |
Fetches user information from the Chainlit user session.
|
| 25 |
|
|
@@ -164,7 +170,7 @@ class UserProfileToolkit(Toolkit):
|
|
| 164 |
str: Confirmation message.
|
| 165 |
|
| 166 |
Example:
|
| 167 |
-
>>> update_user_email('jane.doe@
|
| 168 |
"""
|
| 169 |
response = self.update_user_info('email', email)
|
| 170 |
return f"{response}"
|
|
@@ -184,3 +190,24 @@ class UserProfileToolkit(Toolkit):
|
|
| 184 |
"""
|
| 185 |
response = self.update_user_info('picture', picture)
|
| 186 |
return f"{response}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import asyncio
|
| 2 |
import chainlit as cl
|
| 3 |
from phi.tools import Toolkit
|
| 4 |
from phi.utils.log import logger
|
| 5 |
|
| 6 |
+
from src.libs.rpc_client import rpc_call
|
| 7 |
+
|
| 8 |
|
| 9 |
class UserProfileToolkit(Toolkit):
|
| 10 |
def __init__(self):
|
|
|
|
| 19 |
self.register(self.update_user_name)
|
| 20 |
self.register(self.update_user_email)
|
| 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 |
"""
|
| 30 |
Fetches user information from the Chainlit user session.
|
| 31 |
|
|
|
|
| 170 |
str: Confirmation message.
|
| 171 |
|
| 172 |
Example:
|
| 173 |
+
>>> update_user_email('jane.doe@chatxbt.com')
|
| 174 |
"""
|
| 175 |
response = self.update_user_info('email', email)
|
| 176 |
return f"{response}"
|
|
|
|
| 190 |
"""
|
| 191 |
response = self.update_user_info('picture', picture)
|
| 192 |
return f"{response}"
|
| 193 |
+
|
| 194 |
+
def get_user_id(self, user_email: str) -> str:
|
| 195 |
+
"""
|
| 196 |
+
Fetches the ChatXBT ID of the user associated with the given email.
|
| 197 |
+
|
| 198 |
+
Args:
|
| 199 |
+
user_email (str): The email address of the user whose ChatXBT ID needs to be fetched.
|
| 200 |
+
|
| 201 |
+
Returns:
|
| 202 |
+
str]: A string containing the ChatXBT ID of the user. If the user is not found, an empty string is returned.
|
| 203 |
+
|
| 204 |
+
Example:
|
| 205 |
+
>>> get_user_id('jane.doe@chatxbt.com')
|
| 206 |
+
"""
|
| 207 |
+
logger.info("Fetching user ChatXBT ID")
|
| 208 |
+
|
| 209 |
+
params = {
|
| 210 |
+
"userEmail": user_email.lower()
|
| 211 |
+
}
|
| 212 |
+
response = asyncio.run(rpc_call(method_name="getUserId", params=params))
|
| 213 |
+
return f"{response}"
|