zypchn's picture
Update app.py
1e82b9a verified
import gradio as gr
import pandas as pd
import os
from llama_index.llms.anthropic import Anthropic
from llama_index.core.agent import ReActAgent
from llama_index.core.workflow import Context
from llama_index.core.tools import FunctionTool
# --- Import tools class ---
from tools import PokemonAdvisorTools
# --- 1. Setup Tools & LLM ---
# Instantiate the class to load data
advisor = PokemonAdvisorTools()
# Create the list of tool methods to wrap
tool_methods = [
advisor.get_card_info,
advisor.find_grading_opportunities,
advisor.assess_risk_volatility,
advisor.get_roi_metrics,
advisor.get_recent_price_spikes,
advisor.analyze_set_performance,
advisor.find_cards_by_artist,
advisor.get_market_movers
]
# Wrap tools into LlamaIndex FunctionTools
tools = [FunctionTool.from_defaults(fn=func) for func in tool_methods]
# Initialize the LLM (Ensure OPENAI_API_KEY is set in your env)
llm = Anthropic(model="claude-sonnet-4-0")
# --- 2. System Prompt ---
system_prompt = """
### ROLE
You are the **Poke-Alpha Investment Advisor**, an expert algorithmic trading assistant for the Pokémon TCG market.
You rely **strictly** on data. You do not guess. You do not hallucinate prices.
### TOOL USAGE PROTOCOL
1. **Verify First:** If a user asks about a card, ALWAYS use `get_card_info` first to ensure it exists.
2. **Safety Check:** BEFORE recommending ANY card, you MUST call `assess_risk_volatility` (default to 6 months).
3. **Refining Search:** If the user corrects you (e.g., "Not that card"), use `get_card_info` again with the corrected name or use `analyze_set_performance` to broaden the scope.
4. **Profit Hunting:** If a user asks "What should I buy?", use `find_grading_opportunities` or `get_market_movers`.
### TONE
Professional, objective, concise, and user-friendly.
"""
# --- 3. Initialize Agent & Global Memory ---
# We use timeout=120 because deep reasoning sequences can take time
agent = ReActAgent(
tools=tools,
llm=llm,
verbose=True,
system_prompt=system_prompt,
timeout=120
)
# Global Context acts as the "Server Memory" for this session
# In a real multi-user web app, you would create a new Context per user sessionID
global_ctx = Context(agent)
# --- 4. Define the Chat Function (Async) ---
async def ask_advisor(user_message, history):
"""
Async function to handle the chat.
It uses 'global_ctx' to maintain memory of previous turns/corrections.
"""
if not user_message:
return "Please enter a message."
try:
# Execute the agent workflow
# The 'ctx' argument passes the memory of previous interactions
response = await agent.run(user_msg=user_message, ctx=global_ctx)
# Return the final text response
return str(response)
except Exception as e:
return f"⚠️ **Agent Error:** {str(e)}\n\n*Check the console logs for detailed tool output.*"
# --- 5. Launch Gradio UI ---
demo = gr.ChatInterface(
fn=ask_advisor,
title="🤖 cAsh Robo-Advisor",
description="""
**Your AI Quantitative Analyst for Pokemon Cards.**
Ask about:
* **Arbitrage:** "What are the best grading opportunities?"
* **Risk:** "Is Charizard VMAX a safe investment?"
* **Trends:** "What is crashing right now?"
* **Sets:** "How is Evolving Skies performing?"
""",
examples=[
"What are the top 3 grading opportunities right now?",
"Is investing in Charizard VMAX risky?",
"What cards are trending down?",
"Show me profitable cards by Tomokazu Komiya."
],
#retry_btn="Retry Analysis",
#undo_btn="Undo",
#clear_btn="Clear History",
)
if __name__ == "__main__":
demo.launch(theme=gr.themes.Soft())