Spaces:
Sleeping
Sleeping
| import os | |
| import requests | |
| import gradio as gr | |
| # --- CORRECTED LANGCHAIN IMPORTS --- | |
| # create_react_agent and AgentExecutor are now imported directly from langchain.agents | |
| from langchain.agents import AgentExecutor, create_react_agent | |
| from langchain.tools import Tool | |
| # We need to import the specific ReAct prompt template from the hub | |
| from langchain import hub | |
| from langchain_google_genai import ChatGoogleGenerativeAI | |
| from typing import List, Dict # Added for Gradio ChatInterface typing | |
| # --- Configuration and Environment Setup --- | |
| # IMPORTANT: Do NOT hardcode your API key. | |
| # Define GEMINI_API_KEY as a Space Secret in your Hugging Face Space Settings. | |
| GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY") | |
| if not GEMINI_API_KEY: | |
| # This message helps the user set up their Hugging Face Space correctly | |
| print("WARNING: GEMINI_API_KEY environment variable not set. Running without API key.") | |
| # We will raise a value error later during LLM initialization if it's actually needed. | |
| # Initialize Gemini LLM | |
| try: | |
| llm = ChatGoogleGenerativeAI( | |
| model="gemini-2.5-flash", | |
| temperature=0.3, | |
| google_api_key=GEMINI_API_KEY | |
| ) | |
| except Exception as e: | |
| # Graceful exit if API key is missing during initialization | |
| raise RuntimeError( | |
| "Could not initialize ChatGoogleGenerativeAI. " | |
| "Ensure GEMINI_API_KEY is set as a Space Secret." | |
| ) from e | |
| # --- Tool Definition --- | |
| def get_crypto_price(symbol: str) -> str: | |
| """Fetches the current price of a cryptocurrency symbol.""" | |
| try: | |
| # Use lowercase symbol for CoinGecko API lookup | |
| lookup_symbol = symbol.lower() | |
| url = f"https://api.coingecko.com/api/v3/simple/price?ids={lookup_symbol}&vs_currencies=usd" | |
| res = requests.get(url).json() | |
| # Check if the symbol exists in the response | |
| price = res.get(lookup_symbol, {}).get('usd') | |
| if price: | |
| return f"💰 The current price of {symbol.capitalize()} is ${price:,.2f}" | |
| else: | |
| # Check for common partial matches as suggestions | |
| if not res and len(lookup_symbol) > 3: | |
| return f"❌ Could not find price for symbol '{symbol}'. Try the full name (e.g., 'bitcoin', 'ethereum')." | |
| return f"❌ Could not find price for symbol '{symbol}'." | |
| except Exception as e: | |
| return f"⚠️ Error fetching price: {str(e)}" | |
| # Create a Tool for the Agent | |
| crypto_tool = Tool( | |
| name="Crypto Price Checker", | |
| func=get_crypto_price, | |
| description="Fetches the current cryptocurrency price using CoinGecko. Use this tool ONLY when the user asks for a specific crypto price (e.g., 'bitcoin', 'ethereum')." | |
| ) | |
| # List of tools | |
| tools = [crypto_tool] | |
| # --- Agent Initialization (CORRECTED) --- | |
| # 1. CORRECTED PROMPT: Pull the standard ReAct prompt from LangChain Hub. | |
| # This prompt is guaranteed to have the required '{tools}' and '{tool_names}' variables. | |
| prompt = hub.pull("hwchase17/react") | |
| # 2. Create the Agent | |
| # This uses the corrected 'create_react_agent' import | |
| agent = create_react_agent(llm, tools, prompt) | |
| # 3. Create the Agent Executor | |
| # This uses the corrected 'AgentExecutor' import | |
| agent_executor = AgentExecutor( | |
| agent=agent, | |
| tools=tools, | |
| verbose=True, | |
| handle_parsing_errors=True # Good practice for ReAct agents | |
| ) | |
| # --- Gradio Interface Function --- | |
| # Added 'history' for ChatInterface compatibility | |
| def run_agent(user_query: str, history: List[List[str]]) -> str: | |
| """The main function called by Gradio to run the agent.""" | |
| if not user_query: | |
| return "Please enter a question for the agent." | |
| try: | |
| # Use the AgentExecutor's invoke method | |
| # The input must be a dictionary | |
| response: Dict = agent_executor.invoke({"input": user_query}) | |
| # Extract the final answer text | |
| return response.get("output", "Agent could not find a clear answer.") | |
| except Exception as e: | |
| # Catch and report any runtime errors gracefully | |
| return f"An error occurred while running the agent: {str(e)}" | |
| # --- Gradio App Setup (Using ChatInterface for better UX) --- | |
| gr.ChatInterface( | |
| fn=run_agent, | |
| title="💰 Gemini Crypto Price Agent (ReAct Pattern)", | |
| description="Ask the agent to check the current price of cryptocurrencies (e.g., bitcoin, ethereum). This agent uses the modern LangChain ReAct pattern (v0.1.0+).", | |
| examples=[ | |
| ["What is the current price of Bitcoin?"], | |
| ["How much is Ethereum?"], | |
| ["What about solana?"] | |
| ] | |
| ).launch() | |