feat: week 2 challenge - AI Gold Investment Assistant
This commit is contained in:
@@ -0,0 +1,834 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"vscode": {
|
||||
"languageId": "plaintext"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# Project - AI Gold Investment Estimations Assistant\n",
|
||||
"We'll create an AI Investment assistant focused on Gold prices with multiple agents:\n",
|
||||
"- Gold price API integration\n",
|
||||
"- Investment advice and timing recommendations\n",
|
||||
"- Fake gold buying simulation\n",
|
||||
"- Arabic translation agent\n",
|
||||
"- Speech-to-text functionality\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# imports\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import json\n",
|
||||
"import requests\n",
|
||||
"import datetime\n",
|
||||
"from dotenv import load_dotenv\n",
|
||||
"from openai import OpenAI\n",
|
||||
"import gradio as gr\n",
|
||||
"import base64\n",
|
||||
"from io import BytesIO\n",
|
||||
"from PIL import Image\n",
|
||||
"from pydub import AudioSegment\n",
|
||||
"from pydub.playback import play\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Initialization\n",
|
||||
"\n",
|
||||
"load_dotenv(override=True)\n",
|
||||
"\n",
|
||||
"openai_api_key = os.getenv('OPENAI_API_KEY')\n",
|
||||
"if openai_api_key:\n",
|
||||
" print(f\"OpenAI API Key exists and begins {openai_api_key[:8]}\")\n",
|
||||
"else:\n",
|
||||
" print(\"OpenAI API Key not set\")\n",
|
||||
" \n",
|
||||
"MODEL = \"gpt-4o-mini\"\n",
|
||||
"openai = OpenAI()\n",
|
||||
"\n",
|
||||
"# Free API key for gold prices - sign up at https://metalpriceapi.com/\n",
|
||||
"GOLD_API_KEY = os.getenv('METAL_PRICE_API_KEY', 'demo') # Use 'demo' for testing\n",
|
||||
"GOLD_API_URL = \"https://api.metalpriceapi.com/v1/latest\"\n",
|
||||
"\n",
|
||||
"if GOLD_API_KEY:\n",
|
||||
" print(f\"GOLD_API_KEY exists and begins {GOLD_API_KEY[:8]}\")\n",
|
||||
"else:\n",
|
||||
" print(\"GOLD_API_KEY not set\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"system_message = \"You are a helpful AI Investment assistant specializing in Gold investments. \"\n",
|
||||
"system_message += \"Give informative, courteous answers about gold prices and investment advice. \"\n",
|
||||
"system_message += \"Always be accurate. If you don't know the answer, say so. \"\n",
|
||||
"system_message += \"Provide investment timing recommendations based on current market conditions.\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Gold Price Functions\n",
|
||||
"\n",
|
||||
"def get_gold_price(country=\"USD\"):\n",
|
||||
" \"\"\"Get current gold price for a specific country/currency\"\"\"\n",
|
||||
" print(f\"Tool get_gold_price called for {country}\")\n",
|
||||
" \n",
|
||||
" # Currency mapping for different countries\n",
|
||||
" currency_map = {\n",
|
||||
" 'usa': 'USD', 'united states': 'USD', 'us': 'USD',\n",
|
||||
" 'uk': 'GBP', 'britain': 'GBP', 'england': 'GBP',\n",
|
||||
" 'europe': 'EUR', 'germany': 'EUR', 'france': 'EUR',\n",
|
||||
" 'japan': 'JPY', 'canada': 'CAD', 'australia': 'AUD',\n",
|
||||
" 'india': 'INR', 'china': 'CNY', 'saudi arabia': 'SAR',\n",
|
||||
" 'uae': 'AED', 'egypt': 'EGP'\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" currency = currency_map.get(country.lower(), country.upper())\n",
|
||||
" \n",
|
||||
" # Demo prices (realistic current gold prices as fallback)\n",
|
||||
" demo_prices = {\n",
|
||||
" 'USD': 2350.50, 'GBP': 1890.25, 'EUR': 2180.75, 'JPY': 345000.00,\n",
|
||||
" 'CAD': 3200.80, 'AUD': 3580.90, 'INR': 195000.50, 'CNY': 17200.25,\n",
|
||||
" 'SAR': 8800.75, 'AED': 8650.30, 'EGP': 115000.80\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" price_per_ounce = None\n",
|
||||
" api_success = False\n",
|
||||
" \n",
|
||||
" try:\n",
|
||||
" # API call to get gold price\n",
|
||||
" params = {\n",
|
||||
" 'api_key': GOLD_API_KEY,\n",
|
||||
" 'base': 'XAU', # Gold symbol\n",
|
||||
" 'currencies': currency\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" response = requests.get(GOLD_API_URL, params=params, timeout=10)\n",
|
||||
" print(f\"API Response Status: {response.status_code}\")\n",
|
||||
" \n",
|
||||
" if response.status_code == 200:\n",
|
||||
" data = response.json()\n",
|
||||
" print(f\"API Response Data: {data}\")\n",
|
||||
" \n",
|
||||
" if 'rates' in data and currency in data['rates']:\n",
|
||||
" rate = data['rates'][currency]\n",
|
||||
" if rate > 0: # Ensure valid rate\n",
|
||||
" price_per_ounce = round(rate, 2) # Rate is already price per ounce\n",
|
||||
" api_success = True\n",
|
||||
" print(f\"Successfully got price from API: {price_per_ounce}\")\n",
|
||||
" else:\n",
|
||||
" print(f\"Invalid rate from API: {rate}\")\n",
|
||||
" else:\n",
|
||||
" print(f\"Currency {currency} not found in API response\")\n",
|
||||
" else:\n",
|
||||
" print(f\"API request failed with status {response.status_code}: {response.text}\")\n",
|
||||
" \n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"Error fetching gold price from API: {e}\")\n",
|
||||
" \n",
|
||||
" # Use demo data if API failed\n",
|
||||
" if price_per_ounce is None:\n",
|
||||
" price_per_ounce = demo_prices.get(currency, 2350.50)\n",
|
||||
" print(f\"Using demo price: {price_per_ounce}\")\n",
|
||||
" \n",
|
||||
" # Generate AI-powered investment advice with risk level assessment\n",
|
||||
" advice = generate_ai_investment_advice(price_per_ounce, currency, country)\n",
|
||||
" \n",
|
||||
" return {\n",
|
||||
" 'price': price_per_ounce,\n",
|
||||
" 'currency': currency,\n",
|
||||
" 'country': country,\n",
|
||||
" 'advice': advice,\n",
|
||||
" 'timestamp': datetime.datetime.now().isoformat(),\n",
|
||||
" 'data_source': 'API' if api_success else 'Demo'\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"def generate_ai_investment_advice(price, currency, country):\n",
|
||||
" \"\"\"Generate AI-powered investment advice using risk level assessment as a tool\"\"\"\n",
|
||||
" try:\n",
|
||||
" # First, get the risk level assessment from our analysis tool\n",
|
||||
" risk_analysis = get_risk_level_assessment(price, currency)\n",
|
||||
" risk_level = risk_analysis['risk_level']\n",
|
||||
" fallback_advice = risk_analysis['advice']\n",
|
||||
" \n",
|
||||
" # Create enhanced context for the AI advice using risk assessment as a tool\n",
|
||||
" prompt = f\"\"\"\n",
|
||||
" As a professional gold investment advisor, provide specific investment advice based on these current market conditions:\n",
|
||||
" \n",
|
||||
" MARKET DATA:\n",
|
||||
" - Current gold price: {price} {currency}\n",
|
||||
" - Country/Market: {country}\n",
|
||||
" - Currency: {currency}\n",
|
||||
" \n",
|
||||
" RISK ASSESSMENT TOOL OUTPUT:\n",
|
||||
" - Risk Level: {risk_level.upper()}\n",
|
||||
" - Price Classification: {risk_analysis['price_classification']}\n",
|
||||
" - Technical Analysis: {fallback_advice}\n",
|
||||
" \n",
|
||||
" Based on this risk assessment tool output, provide professional investment advice that:\n",
|
||||
" 1. Acknowledges the {risk_level} risk level\n",
|
||||
" 2. Provides specific timing recommendations\n",
|
||||
" 3. Considers currency-specific factors for {currency}\n",
|
||||
" 4. Offers actionable next steps\n",
|
||||
" \n",
|
||||
" Keep your advice concise (2-3 sentences), professional, and specific to the {risk_level} risk scenario.\n",
|
||||
" \"\"\"\n",
|
||||
" \n",
|
||||
" response = openai.chat.completions.create(\n",
|
||||
" model=MODEL,\n",
|
||||
" messages=[\n",
|
||||
" {\"role\": \"system\", \"content\": \"You are a professional gold investment advisor. Use the risk assessment tool output to provide specific, actionable advice. Build upon the technical analysis provided.\"},\n",
|
||||
" {\"role\": \"user\", \"content\": prompt}\n",
|
||||
" ],\n",
|
||||
" max_tokens=200,\n",
|
||||
" temperature=0.7\n",
|
||||
" )\n",
|
||||
" \n",
|
||||
" return response.choices[0].message.content.strip()\n",
|
||||
" \n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"Error generating AI advice: {e}\")\n",
|
||||
" # Fallback to rule-based advice if AI fails\n",
|
||||
" return generate_fallback_advice(price, currency)\n",
|
||||
"\n",
|
||||
"def get_risk_level_assessment(price, currency):\n",
|
||||
" \"\"\"Risk assessment tool that determines price level and provides technical analysis\"\"\"\n",
|
||||
" \n",
|
||||
" # Currency-specific price thresholds (approximate)\n",
|
||||
" thresholds = {\n",
|
||||
" 'USD': {'low': 2000, 'moderate': 2300, 'high': 2500},\n",
|
||||
" 'EUR': {'low': 1850, 'moderate': 2150, 'high': 2350},\n",
|
||||
" 'GBP': {'low': 1600, 'moderate': 1850, 'high': 2100},\n",
|
||||
" 'JPY': {'low': 300000, 'moderate': 340000, 'high': 380000},\n",
|
||||
" 'CAD': {'low': 2700, 'moderate': 3100, 'high': 3500},\n",
|
||||
" 'AUD': {'low': 3000, 'moderate': 3500, 'high': 4000},\n",
|
||||
" 'INR': {'low': 160000, 'moderate': 190000, 'high': 220000},\n",
|
||||
" 'CNY': {'low': 14000, 'moderate': 16500, 'high': 19000},\n",
|
||||
" 'SAR': {'low': 7500, 'moderate': 8500, 'high': 9500},\n",
|
||||
" 'AED': {'low': 7300, 'moderate': 8300, 'high': 9300},\n",
|
||||
" 'EGP': {'low': 95000, 'moderate': 110000, 'high': 125000}\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" # Get thresholds for currency or use USD as default\n",
|
||||
" thresh = thresholds.get(currency, thresholds['USD'])\n",
|
||||
" \n",
|
||||
" if price < thresh['low']:\n",
|
||||
" return {\n",
|
||||
" 'risk_level': 'low',\n",
|
||||
" 'price_classification': 'Undervalued',\n",
|
||||
" 'advice': f\"Excellent buying opportunity! Gold is undervalued at {price} {currency}. Consider accumulating positions while prices are low.\"\n",
|
||||
" }\n",
|
||||
" elif price < thresh['moderate']:\n",
|
||||
" return {\n",
|
||||
" 'risk_level': 'moderate', \n",
|
||||
" 'price_classification': 'Fair Value',\n",
|
||||
" 'advice': f\"Good entry point at {price} {currency}. Moderate pricing with growth potential. Consider dollar-cost averaging for this market.\"\n",
|
||||
" }\n",
|
||||
" elif price < thresh['high']:\n",
|
||||
" return {\n",
|
||||
" 'risk_level': 'moderate-high',\n",
|
||||
" 'price_classification': 'Fairly Valued',\n",
|
||||
" 'advice': f\"Fair pricing at {price} {currency}. Market is fairly valued. Consider smaller purchases or wait for pullbacks.\"\n",
|
||||
" }\n",
|
||||
" else:\n",
|
||||
" return {\n",
|
||||
" 'risk_level': 'high',\n",
|
||||
" 'price_classification': 'Premium/Overvalued',\n",
|
||||
" 'advice': f\"Premium pricing at {price} {currency}. Consider waiting for market corrections or focus on smaller strategic purchases.\"\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"def generate_fallback_advice(price, currency):\n",
|
||||
" \"\"\"Enhanced fallback advice with currency-specific considerations\"\"\"\n",
|
||||
" \n",
|
||||
" # Currency-specific price thresholds (approximate)\n",
|
||||
" thresholds = {\n",
|
||||
" 'USD': {'low': 2000, 'moderate': 2300, 'high': 2500},\n",
|
||||
" 'EUR': {'low': 1850, 'moderate': 2150, 'high': 2350},\n",
|
||||
" 'GBP': {'low': 1600, 'moderate': 1850, 'high': 2100},\n",
|
||||
" 'JPY': {'low': 300000, 'moderate': 340000, 'high': 380000},\n",
|
||||
" 'CAD': {'low': 2700, 'moderate': 3100, 'high': 3500},\n",
|
||||
" 'AUD': {'low': 3000, 'moderate': 3500, 'high': 4000},\n",
|
||||
" 'INR': {'low': 160000, 'moderate': 190000, 'high': 220000},\n",
|
||||
" 'CNY': {'low': 14000, 'moderate': 16500, 'high': 19000},\n",
|
||||
" 'SAR': {'low': 7500, 'moderate': 8500, 'high': 9500},\n",
|
||||
" 'AED': {'low': 7300, 'moderate': 8300, 'high': 9300},\n",
|
||||
" 'EGP': {'low': 95000, 'moderate': 110000, 'high': 125000}\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" # Get thresholds for currency or use USD as default\n",
|
||||
" thresh = thresholds.get(currency, thresholds['USD'])\n",
|
||||
" \n",
|
||||
" if price < thresh['low']:\n",
|
||||
" return f\"Excellent buying opportunity! Gold is undervalued at {price} {currency}. Consider accumulating positions while prices are low.\"\n",
|
||||
" elif price < thresh['moderate']:\n",
|
||||
" return f\"Good entry point at {price} {currency}. Moderate pricing with growth potential. Consider dollar-cost averaging for this market.\"\n",
|
||||
" elif price < thresh['high']:\n",
|
||||
" return f\"Fair pricing at {price} {currency}. Market is fairly valued. Consider smaller purchases or wait for pullbacks.\"\n",
|
||||
" else:\n",
|
||||
" return f\"Premium pricing at {price} {currency}. Consider waiting for market corrections or focus on smaller strategic purchases.\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(\"Testing AI-Enhanced Gold Price Function with Risk Assessment Tool:\")\n",
|
||||
"print(\"=\" * 70)\n",
|
||||
"\n",
|
||||
"# Test USA (likely high risk due to current high prices)\n",
|
||||
"test_result = get_gold_price(\"USA\")\n",
|
||||
"print(f\"\\n🇺🇸 USA Test:\")\n",
|
||||
"print(f\"Price: {test_result['price']} {test_result['currency']}\")\n",
|
||||
"print(f\"Data Source: {test_result.get('data_source', 'Unknown')}\")\n",
|
||||
"print(f\"AI Advice: {test_result['advice']}\")\n",
|
||||
"\n",
|
||||
"# Test a few more currencies to show different risk levels\n",
|
||||
"print(f\"\\n{'='*50}\")\n",
|
||||
"print(\"Testing Different Currencies with AI Risk Assessment:\")\n",
|
||||
"\n",
|
||||
"test_currencies = [\"USA\", \"UK\", \"EUR\", \"JPY\"]\n",
|
||||
"for currency in test_currencies:\n",
|
||||
" result = get_gold_price(currency)\n",
|
||||
" \n",
|
||||
" # Also show the risk assessment tool output\n",
|
||||
" risk_assessment = get_risk_level_assessment(result['price'], result['currency'])\n",
|
||||
" \n",
|
||||
" print(f\"\\n🌍 {currency}:\")\n",
|
||||
" print(f\" Price: {result['price']} {result['currency']}\")\n",
|
||||
" print(f\" Risk Level: {risk_assessment['risk_level'].upper()}\")\n",
|
||||
" print(f\" Classification: {risk_assessment['price_classification']}\")\n",
|
||||
" print(f\" AI Advice: {result['advice']}\")\n",
|
||||
" print(f\" Data Source: {result.get('data_source', 'Unknown')}\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Fake Gold Buying Simulation\n",
|
||||
"def simulate_gold_purchase(ounces, country=\"USD\"):\n",
|
||||
" \"\"\"Simulate buying gold and write to file\"\"\"\n",
|
||||
" print(f\"Tool simulate_gold_purchase called for {ounces} ounces in {country}\")\n",
|
||||
" \n",
|
||||
" try:\n",
|
||||
" # Get current price\n",
|
||||
" price_data = get_gold_price(country)\n",
|
||||
" \n",
|
||||
" if 'error' in price_data:\n",
|
||||
" return {'error': price_data['error']}\n",
|
||||
" \n",
|
||||
" # Ensure we have valid price data\n",
|
||||
" if 'price' not in price_data or price_data['price'] <= 0:\n",
|
||||
" return {'error': 'Invalid price data received'}\n",
|
||||
" \n",
|
||||
" price_per_ounce = float(price_data['price'])\n",
|
||||
" currency = price_data['currency']\n",
|
||||
" ounces_float = float(ounces)\n",
|
||||
" \n",
|
||||
" # Calculate total cost\n",
|
||||
" total_cost = round(price_per_ounce * ounces_float, 2)\n",
|
||||
" \n",
|
||||
" # Create detailed purchase record\n",
|
||||
" purchase_record = {\n",
|
||||
" 'purchase_date': datetime.datetime.now().isoformat(),\n",
|
||||
" 'ounces': ounces_float,\n",
|
||||
" 'price_per_ounce': price_per_ounce,\n",
|
||||
" 'total_cost': total_cost,\n",
|
||||
" 'currency': currency,\n",
|
||||
" 'country': country,\n",
|
||||
" 'transaction_id': f\"GOLD_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}\",\n",
|
||||
" 'price_source': price_data.get('source', 'Unknown'),\n",
|
||||
" 'market_advice': price_data.get('advice', 'No advice available')\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" # Write to file\n",
|
||||
" filename = \"gold_purchases.json\"\n",
|
||||
" \n",
|
||||
" # Load existing purchases or create new list\n",
|
||||
" try:\n",
|
||||
" with open(filename, 'r') as f:\n",
|
||||
" purchases = json.load(f)\n",
|
||||
" except FileNotFoundError:\n",
|
||||
" purchases = []\n",
|
||||
" \n",
|
||||
" # Add new purchase\n",
|
||||
" purchases.append(purchase_record)\n",
|
||||
" \n",
|
||||
" # Save back to file\n",
|
||||
" with open(filename, 'w') as f:\n",
|
||||
" json.dump(purchases, f, indent=2)\n",
|
||||
" \n",
|
||||
" # Create detailed success message\n",
|
||||
" success_message = f\"✅ Successfully purchased {ounces} ounces of gold for {total_cost:,.2f} {currency}\"\n",
|
||||
" if 'note' in price_data:\n",
|
||||
" success_message += f\" ({price_data['note']})\"\n",
|
||||
" \n",
|
||||
" return {\n",
|
||||
" 'success': True,\n",
|
||||
" 'message': success_message,\n",
|
||||
" 'transaction_id': purchase_record['transaction_id'],\n",
|
||||
" 'total_cost': total_cost,\n",
|
||||
" 'currency': currency,\n",
|
||||
" 'price_per_ounce': price_per_ounce,\n",
|
||||
" 'market_advice': price_data.get('advice', 'No advice available')\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" except ValueError as e:\n",
|
||||
" return {'error': f'Invalid number format: {str(e)}'}\n",
|
||||
" except Exception as e:\n",
|
||||
" return {'error': f'Purchase failed: {str(e)}'}\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Test the purchase simulation\n",
|
||||
"print(\"Testing purchase simulation...\")\n",
|
||||
"test_purchase = simulate_gold_purchase(\"2.5\", \"USA\")\n",
|
||||
"print(\"Purchase Result:\")\n",
|
||||
"print(json.dumps(test_purchase, indent=2))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Translation Agent\n",
|
||||
"def translate_to_arabic(text):\n",
|
||||
" \"\"\"Translate text to Arabic using OpenAI\"\"\"\n",
|
||||
" try:\n",
|
||||
" response = openai.chat.completions.create(\n",
|
||||
" model=MODEL,\n",
|
||||
" messages=[\n",
|
||||
" {\"role\": \"system\", \"content\": \"You are a professional translator. Translate the given text to Arabic. Maintain the meaning and tone. Only return the Arabic translation, nothing else.\"},\n",
|
||||
" {\"role\": \"user\", \"content\": text}\n",
|
||||
" ]\n",
|
||||
" )\n",
|
||||
" return response.choices[0].message.content\n",
|
||||
" except Exception as e:\n",
|
||||
" return f\"Translation error: {str(e)}\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Speech-to-Text Agent\n",
|
||||
"def speech_to_text(audio_file):\n",
|
||||
" \"\"\"Convert speech to text using OpenAI Whisper\"\"\"\n",
|
||||
" try:\n",
|
||||
" if audio_file is None:\n",
|
||||
" return \"No audio file provided\"\n",
|
||||
" \n",
|
||||
" with open(audio_file, \"rb\") as audio:\n",
|
||||
" transcript = openai.audio.transcriptions.create(\n",
|
||||
" model=\"whisper-1\",\n",
|
||||
" file=audio\n",
|
||||
" )\n",
|
||||
" return transcript.text\n",
|
||||
" except Exception as e:\n",
|
||||
" return f\"Speech-to-text error: {str(e)}\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Define Tools for OpenAI\n",
|
||||
"gold_price_function = {\n",
|
||||
" \"name\": \"get_gold_price\",\n",
|
||||
" \"description\": \"Get the current price of gold for a specific country/currency and investment advice. Call this when user asks about gold prices or investment timing.\",\n",
|
||||
" \"parameters\": {\n",
|
||||
" \"type\": \"object\",\n",
|
||||
" \"properties\": {\n",
|
||||
" \"country\": {\n",
|
||||
" \"type\": \"string\",\n",
|
||||
" \"description\": \"The country or currency code (e.g., 'USA', 'UK', 'EUR', 'JPY')\",\n",
|
||||
" },\n",
|
||||
" },\n",
|
||||
" \"required\": [\"country\"],\n",
|
||||
" \"additionalProperties\": False\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"gold_purchase_function = {\n",
|
||||
" \"name\": \"simulate_gold_purchase\",\n",
|
||||
" \"description\": \"Simulate purchasing gold and record the transaction. Call this when user wants to buy gold.\",\n",
|
||||
" \"parameters\": {\n",
|
||||
" \"type\": \"object\",\n",
|
||||
" \"properties\": {\n",
|
||||
" \"ounces\": {\n",
|
||||
" \"type\": \"string\",\n",
|
||||
" \"description\": \"Number of ounces of gold to purchase\",\n",
|
||||
" },\n",
|
||||
" \"country\": {\n",
|
||||
" \"type\": \"string\",\n",
|
||||
" \"description\": \"The country or currency for the purchase (e.g., 'USA', 'UK')\",\n",
|
||||
" },\n",
|
||||
" },\n",
|
||||
" \"required\": [\"ounces\"],\n",
|
||||
" \"additionalProperties\": False\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"tools = [\n",
|
||||
" {\"type\": \"function\", \"function\": gold_price_function},\n",
|
||||
" {\"type\": \"function\", \"function\": gold_purchase_function}\n",
|
||||
"]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Handle Tool Calls\n",
|
||||
"def handle_tool_call(message):\n",
|
||||
" \"\"\"Handle tool calls from OpenAI\"\"\"\n",
|
||||
" tool_call = message.tool_calls[0]\n",
|
||||
" function_name = tool_call.function.name\n",
|
||||
" arguments = json.loads(tool_call.function.arguments)\n",
|
||||
" \n",
|
||||
" if function_name == \"get_gold_price\":\n",
|
||||
" country = arguments.get('country', 'USD')\n",
|
||||
" result = get_gold_price(country)\n",
|
||||
" elif function_name == \"simulate_gold_purchase\":\n",
|
||||
" ounces = arguments.get('ounces')\n",
|
||||
" country = arguments.get('country', 'USD')\n",
|
||||
" result = simulate_gold_purchase(ounces, country)\n",
|
||||
" else:\n",
|
||||
" result = {\"error\": \"Unknown function\"}\n",
|
||||
" \n",
|
||||
" response = {\n",
|
||||
" \"role\": \"tool\",\n",
|
||||
" \"content\": json.dumps(result),\n",
|
||||
" \"tool_call_id\": tool_call.id\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" return response, result\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Main Chat Function\n",
|
||||
"\n",
|
||||
"def chat(history):\n",
|
||||
" \"\"\"Main chat function with multi-agent capabilities\"\"\"\n",
|
||||
" messages = [{\"role\": \"system\", \"content\": system_message}] + history\n",
|
||||
" response = openai.chat.completions.create(model=MODEL, messages=messages, tools=tools)\n",
|
||||
" \n",
|
||||
" # Handle tool calls\n",
|
||||
" if response.choices[0].finish_reason == \"tool_calls\":\n",
|
||||
" message = response.choices[0].message\n",
|
||||
" tool_response, tool_result = handle_tool_call(message)\n",
|
||||
" messages.append(message)\n",
|
||||
" messages.append(tool_response)\n",
|
||||
" response = openai.chat.completions.create(model=MODEL, messages=messages)\n",
|
||||
" \n",
|
||||
" reply = response.choices[0].message.content\n",
|
||||
" history += [{\"role\": \"assistant\", \"content\": reply}]\n",
|
||||
" \n",
|
||||
" # Translate to Arabic\n",
|
||||
" arabic_translation = translate_to_arabic(reply)\n",
|
||||
" \n",
|
||||
" return history, arabic_translation\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Audio Processing Function\n",
|
||||
"\n",
|
||||
"def process_audio(audio_file, history):\n",
|
||||
" \"\"\"Process audio input and add to chat\"\"\"\n",
|
||||
" if audio_file is None:\n",
|
||||
" return history, \"\", \"No audio provided\"\n",
|
||||
" \n",
|
||||
" # Convert speech to text\n",
|
||||
" transcribed_text = speech_to_text(audio_file)\n",
|
||||
" \n",
|
||||
" if transcribed_text.startswith(\"Speech-to-text error:\"):\n",
|
||||
" return history, \"\", transcribed_text\n",
|
||||
" \n",
|
||||
" # Add user message to history\n",
|
||||
" history += [{\"role\": \"user\", \"content\": transcribed_text}]\n",
|
||||
" \n",
|
||||
" # Get response\n",
|
||||
" updated_history, arabic_translation = chat(history)\n",
|
||||
" \n",
|
||||
" return updated_history, arabic_translation, f\"Transcribed: {transcribed_text}\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Advanced Gradio Interface with Multiple Panels\n",
|
||||
"\n",
|
||||
"with gr.Blocks(title=\"AI Investment Estimations - Gold Assistant\", theme=gr.themes.Soft()) as ui:\n",
|
||||
" gr.Markdown(\"# 🏆 AI Investment Estimations - Gold Assistant\")\n",
|
||||
" gr.Markdown(\"Get real-time gold prices, investment advice, simulate purchases, and interact in multiple languages!\")\n",
|
||||
" \n",
|
||||
" with gr.Row():\n",
|
||||
" # Left Panel - English Chat\n",
|
||||
" with gr.Column(scale=2):\n",
|
||||
" gr.Markdown(\"### 💬 English Chat\")\n",
|
||||
" chatbot = gr.Chatbot(height=400, type=\"messages\", label=\"Investment Assistant\")\n",
|
||||
" \n",
|
||||
" with gr.Row():\n",
|
||||
" text_input = gr.Textbox(\n",
|
||||
" label=\"Ask about gold prices, investment advice, or make a purchase\",\n",
|
||||
" placeholder=\"e.g., What's the gold price in USA? Should I invest now? Buy 2 ounces of gold\"\n",
|
||||
" )\n",
|
||||
" \n",
|
||||
" with gr.Row():\n",
|
||||
" send_btn = gr.Button(\"Send Message\", variant=\"primary\")\n",
|
||||
" clear_btn = gr.Button(\"Clear Chat\")\n",
|
||||
" \n",
|
||||
" # Audio Input\n",
|
||||
" gr.Markdown(\"### 🎤 Voice Input\")\n",
|
||||
" audio_input = gr.Audio(sources=[\"microphone\"], type=\"filepath\", label=\"Speak your question\")\n",
|
||||
" audio_status = gr.Textbox(label=\"Audio Status\", interactive=False)\n",
|
||||
" \n",
|
||||
" # Right Panel - Arabic Translation\n",
|
||||
" with gr.Column(scale=1):\n",
|
||||
" gr.Markdown(\"### 🌐 Arabic Translation\")\n",
|
||||
" gr.Markdown(\"الترجمة العربية\")\n",
|
||||
" arabic_output = gr.Textbox(\n",
|
||||
" label=\"Arabic Response\",\n",
|
||||
" lines=15,\n",
|
||||
" interactive=False,\n",
|
||||
" text_align=\"right\",\n",
|
||||
" rtl=True\n",
|
||||
" )\n",
|
||||
" \n",
|
||||
" # Bottom Panel - Purchase History\n",
|
||||
" with gr.Row():\n",
|
||||
" gr.Markdown(\"### 📊 Recent Features\")\n",
|
||||
" \n",
|
||||
" with gr.Row():\n",
|
||||
" with gr.Column():\n",
|
||||
" gr.Markdown(\"**Supported Countries/Currencies:**\")\n",
|
||||
" gr.Markdown(\"USA (USD), UK (GBP), Europe (EUR), Japan (JPY), Canada (CAD), Australia (AUD), India (INR), China (CNY), Saudi Arabia (SAR), UAE (AED), Egypt (EGP)\")\n",
|
||||
" \n",
|
||||
" with gr.Column():\n",
|
||||
" gr.Markdown(\"**Features:**\")\n",
|
||||
" gr.Markdown(\"• Real-time gold prices\\\\n• Investment timing advice\\\\n• Simulated gold purchasing\\\\n• Arabic translation\\\\n• Voice input support\")\n",
|
||||
" \n",
|
||||
" # Event Handlers\n",
|
||||
" def handle_text_input(message, history):\n",
|
||||
" if not message.strip():\n",
|
||||
" return history, \"\", \"\"\n",
|
||||
" \n",
|
||||
" history += [{\"role\": \"user\", \"content\": message}]\n",
|
||||
" updated_history, arabic_translation = chat(history)\n",
|
||||
" return updated_history, \"\", arabic_translation\n",
|
||||
" \n",
|
||||
" def clear_chat():\n",
|
||||
" return [], \"\", \"\"\n",
|
||||
" \n",
|
||||
" # Connect events\n",
|
||||
" text_input.submit(\n",
|
||||
" handle_text_input,\n",
|
||||
" inputs=[text_input, chatbot],\n",
|
||||
" outputs=[chatbot, text_input, arabic_output]\n",
|
||||
" )\n",
|
||||
" \n",
|
||||
" send_btn.click(\n",
|
||||
" handle_text_input,\n",
|
||||
" inputs=[text_input, chatbot],\n",
|
||||
" outputs=[chatbot, text_input, arabic_output]\n",
|
||||
" )\n",
|
||||
" \n",
|
||||
" clear_btn.click(\n",
|
||||
" clear_chat,\n",
|
||||
" outputs=[chatbot, text_input, arabic_output]\n",
|
||||
" )\n",
|
||||
" \n",
|
||||
" audio_input.change(\n",
|
||||
" process_audio,\n",
|
||||
" inputs=[audio_input, chatbot],\n",
|
||||
" outputs=[chatbot, arabic_output, audio_status]\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"# Launch the interface\n",
|
||||
"ui.launch(inbrowser=True, share=False)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "raw",
|
||||
"metadata": {
|
||||
"vscode": {
|
||||
"languageId": "raw"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"## Usage Examples\n",
|
||||
"\n",
|
||||
"Try these example queries:\n",
|
||||
"\n",
|
||||
"1. **Get Gold Prices**: \"What's the current gold price in USA?\"\n",
|
||||
"2. **Investment Advice**: \"Should I invest in gold now?\"\n",
|
||||
"3. **Country-specific**: \"Gold price in Saudi Arabia\"\n",
|
||||
"4. **Purchase Simulation**: \"Buy 2.5 ounces of gold in USD\"\n",
|
||||
"5. **Voice Input**: Use the microphone to ask questions\n",
|
||||
"\n",
|
||||
"The assistant will:\n",
|
||||
"- Fetch real-time gold prices\n",
|
||||
"- Provide investment timing advice\n",
|
||||
"- Simulate gold purchases and save to file\n",
|
||||
"- Translate all responses to Arabic\n",
|
||||
"- Process voice inputs using speech-to-text\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# View purchase history\n",
|
||||
"def view_purchase_history():\n",
|
||||
" \"\"\"View all gold purchases from the JSON file\"\"\"\n",
|
||||
" try:\n",
|
||||
" with open('gold_purchases.json', 'r') as f:\n",
|
||||
" purchases = json.load(f)\n",
|
||||
" \n",
|
||||
" print(\"Gold Purchase History:\")\n",
|
||||
" print(\"=\" * 50)\n",
|
||||
" \n",
|
||||
" total_ounces = 0\n",
|
||||
" total_spent = {}\n",
|
||||
" \n",
|
||||
" for purchase in purchases:\n",
|
||||
" print(f\"Date: {purchase['purchase_date'][:19]}\")\n",
|
||||
" print(f\"Ounces: {purchase['ounces']}\")\n",
|
||||
" print(f\"Price per ounce: {purchase['price_per_ounce']} {purchase['currency']}\")\n",
|
||||
" print(f\"Total cost: {purchase['total_cost']} {purchase['currency']}\")\n",
|
||||
" print(f\"Transaction ID: {purchase['transaction_id']}\")\n",
|
||||
" print(\"-\" * 30)\n",
|
||||
" \n",
|
||||
" total_ounces += purchase['ounces']\n",
|
||||
" currency = purchase['currency']\n",
|
||||
" if currency not in total_spent:\n",
|
||||
" total_spent[currency] = 0\n",
|
||||
" total_spent[currency] += purchase['total_cost']\n",
|
||||
" \n",
|
||||
" print(f\"\\nSummary:\")\n",
|
||||
" print(f\"Total ounces purchased: {total_ounces}\")\n",
|
||||
" print(f\"Total spent by currency:\")\n",
|
||||
" for currency, amount in total_spent.items():\n",
|
||||
" print(f\" {currency}: {amount}\")\n",
|
||||
" \n",
|
||||
" except FileNotFoundError:\n",
|
||||
" print(\"No purchase history found. Make your first purchase to start tracking!\")\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"Error reading purchase history: {e}\")\n",
|
||||
"\n",
|
||||
"# Run this to check your purchase history\n",
|
||||
"view_purchase_history()\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"vscode": {
|
||||
"languageId": "raw"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"## API Setup Instructions\n",
|
||||
"\n",
|
||||
"### For Gold Prices API:\n",
|
||||
"1. Visit https://metalpriceapi.com/\n",
|
||||
"2. Sign up for a free account\n",
|
||||
"3. Get your API key\n",
|
||||
"4. Add `METAL_PRICE_API_KEY=your_api_key` to your .env file\n",
|
||||
"\n",
|
||||
"### The system includes:\n",
|
||||
"- **Gold Price Agent**: Fetches real-time prices with investment advice\n",
|
||||
"- **Purchase Simulation Agent**: Records fake gold purchases to JSON file\n",
|
||||
"- **Translation Agent**: Translates all responses to Arabic\n",
|
||||
"- **Speech-to-Text Agent**: Converts voice input to text using Whisper\n",
|
||||
"\n",
|
||||
"### Multi-Panel Interface:\n",
|
||||
"- Left: English chat with text and voice input\n",
|
||||
"- Right: Arabic translations\n",
|
||||
"- Bottom: Feature descriptions and supported currencies\n",
|
||||
"\n",
|
||||
"### Supported Countries/Currencies:\n",
|
||||
"USA (USD), UK (GBP), Europe (EUR), Japan (JPY), Canada (CAD), Australia (AUD), India (INR), China (CNY), Saudi Arabia (SAR), UAE (AED), Egypt (EGP)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.12"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
Reference in New Issue
Block a user