File size: 6,645 Bytes
25d025b
f53da68
d068566
 
 
 
383415a
d068566
383415a
66bc554
cbb819c
0ad2f68
1b4c441
66bc554
 
a8e2f82
383415a
66bc554
 
 
25d025b
 
d068566
25d025b
383415a
 
 
 
f53da68
25d025b
f53da68
25d025b
a8e2f82
 
 
 
25d025b
a8e2f82
 
25d025b
a8e2f82
25d025b
a8e2f82
 
 
 
 
 
 
 
25d025b
f53da68
25d025b
2fddb4d
 
 
 
 
ae917b6
2fddb4d
 
 
 
25d025b
2fddb4d
25d025b
2fddb4d
 
25d025b
2fddb4d
25d025b
2fddb4d
 
 
 
25d025b
 
2fddb4d
25d025b
d068566
da5e53f
25d025b
 
66bc554
 
575618b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d068566
 
25d025b
05b7f8b
575618b
0ad2f68
 
 
 
 
 
 
05b7f8b
da5e53f
 
575618b
da5e53f
0ad2f68
66bc554
75bb6d0
0ad2f68
575618b
da5e53f
575618b
0ad2f68
d068566
2267d03
383415a
 
 
 
66bc554
 
25d025b
 
d068566
2267d03
d068566
 
 
 
25d025b
d068566
 
cd787aa
 
d068566
 
 
 
25d025b
 
 
 
 
 
 
 
cd787aa
25d025b
d068566
 
 
25d025b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import os
from typing import Optional, Dict
from dotenv import load_dotenv
import chainlit as cl
from phi.assistant import Assistant
from phi.llm.openai import OpenAIChat
from phi.tools.duckduckgo import DuckDuckGo
from phi.tools.yfinance import YFinanceTools
from src.databases.postgres import sqlalchemy_engine
from src.knowledge_bases.combined import knowledge_base
from src.tools.crypto_swap_toolkit import CryptoSwapTools
from src.tools.crypto_bridge_toolkit import CrossChainSwapTools
from src.tools.crypto_data_toolkit import CryptoDataTools
from portkey_ai import PORTKEY_GATEWAY_URL, createHeaders
from src.config.portkey_config import generate_portkey_config
from src.tools.user_profile_toolkit import UserProfileToolkit
from phi.storage.assistant.postgres import PgAssistantStorage
from src.tools.crypto_evm_wallet_toolkit import CryptoEVMWalletTools
from src.tools.user_confirmation_pin_toolkit import UserConfirmationPinToolkit

# Load environment variables
load_dotenv()

# Initialize storage
storage = PgAssistantStorage(
    table_name="assistant_runs",
    db_engine=sqlalchemy_engine
)

# OAuth callback
@cl.oauth_callback
def oauth_callback(provider_id: str, token: str, raw_user_data: Dict[str, str], default_user: cl.User) -> Optional[cl.User]:
    return cl.User(
        identifier=raw_user_data.get('email'),
        email=raw_user_data.get('email'),
        name=raw_user_data.get('name'),
        metadata={**raw_user_data, **({'image': default_user.metadata.get('image')})}
    )

# Password authentication callback
@cl.password_auth_callback
def auth_callback(username: str, password: str) -> Optional[cl.User]:
    if (username, password) == ("admin", "admin"):
        user = {
            "identifier": "admin", "email": username, "metadata": {"role": "admin", "provider": "credentials"}
        }
        cl.user_session.set("user_profile", user)
        return cl.User(
            identifier="admin", email=username, metadata={"role": "admin", "provider": "credentials"}
        )
    return None

# Set starters
@cl.set_starters
async def set_starters():
    return [
        cl.Starter(
            label="Create a crypto wallet for me",
            message="create an evm crypto wallet for me",
            icon="/public/wallet-svgrepo-com.svg",
        ),
        cl.Starter(
            label="Latest News on defi, crypto and solana",
            message="What news are currently trending on defi.",
            icon="/public/news-svgrepo-com.svg",
        ),
        cl.Starter(
            label="Get price of BTC, ETH and PEPE",
            message="Get me the price of BTC, ETH and PEPE",
            icon="/public/coins-electronics-svgrepo-com.svg",
        ),
        cl.Starter(
            label="Get trending stocks",
            message="Get latest stock",
            icon="/public/stockchart-svgrepo-com.svg",
        )
    ]

# On chat start
@cl.on_chat_start
async def start():
    is_dev_mode = bool(os.getenv("DEV_MODE"))
    portkey_local_gateway = bool(os.getenv("PORTKEY_LOCAL_GATEWAY_URL"))
    portkey_config = generate_portkey_config(local=portkey_local_gateway)

    XBTfinancialmarketresearcher = Assistant(
        name="XBT-financial-market-researcher",
        llm=OpenAIChat(model="gpt-4o"),
        description="A specialized assistant for researching the financial market, with a focus on crypto, Web3, and DeFi news and trends.",
        instructions=[
            "Use DuckDuckGo for general web searches and recent news.",
            "Use YFinanceTools for obtaining stock prices and related financial data.",
            "Use CryptoDataTools for accessing cryptocurrency prices and market information.",
            "Incorporate relevant news and trends in crypto, Web3, and DeFi into your responses.",
            "Provide accurate and up-to-date information with citations when necessary.",
        ],
        markdown=True,
        role="Helps research the financial market and get news and trends on crypto, Web3, and DeFi",
        tools=[
            DuckDuckGo(),
            YFinanceTools(stock_price=True),
            CryptoDataTools(),
        ],
        show_tool_calls=is_dev_mode,
        knowledge_base=knowledge_base,
        storage=storage,
        search_knowledge=True,
        read_chat_history=True,
        add_references_to_prompt=True,
        add_chat_history_to_prompt=True,
    )

    # Initialize the assistant
    cxbt_assistant = Assistant(
        introduction="Hi, I'm ChatXBT, your AI assistant for Web3 and DeFi. I can help you with your queries related to Web3 and DeFi.",
        llm=OpenAIChat(
            model="gpt-4o"
            # api_key=os.getenv("PORTKEY_API_KEY"),
            # # base_url=os.getenv("PORTKEY_LOCAL_GATEWAY_URL") or PORTKEY_GATEWAY_URL,
            # base_url=PORTKEY_GATEWAY_URL,
            # default_headers=createHeaders(
            #     api_key=os.getenv("PORTKEY_API_KEY") or None,
            #     config=portkey_config
            # ),
        ),
        tools=[
            DuckDuckGo(),
            # CryptoDataTools(),
            CryptoSwapTools(),
            CrossChainSwapTools(),
            UserProfileToolkit(),
            CryptoEVMWalletTools(),
            # UserConfirmationPinToolkit(),
            # YFinanceTools(stock_price=True)
        ],
        team=[XBTfinancialmarketresearcher],
        show_tool_calls=False,
        markdown=True,
        knowledge_base=knowledge_base,
        storage=storage,
        search_knowledge=True,
        read_chat_history=True,
        add_references_to_prompt=True,
        add_chat_history_to_prompt=True,
        prevent_hallucinations=True,
        prevent_prompt_injection=True,
        add_datetime_to_instructions=True
    )
    cxbt_assistant.knowledge_base.load(recreate=False)

    # Set the assistant in the user session
    cl.user_session.set("agent", cxbt_assistant)

# On message
@cl.on_message
async def main(message: cl.Message):
    msg = cl.Message(content="")

    # Retrieve the assistant from the user session
    agent = cl.user_session.get("agent")

    # Process the user message using the assistant
    try:
        response_generator = agent.run(message=message.content, stream=True)
        for delta in response_generator:
            await msg.stream_token(str(delta))
    except TypeError as e:
        # Handle specific TypeError and log or print additional information for debugging
        print(f"Error occurred: {e}")
        await msg.stream_token(f"\n\n I encountetrd an error, please try again later.")

    await msg.send()

# Run the Chainlit application
if __name__ == "__main__":
    cl.run_sync()