Files
LLM_Engineering_OLD/week2/community-contributions/week2-assignment-Joshua (GEN AI)/radio_africa_advanced_exercise.ipynb

1091 lines
51 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Week 2 End Exercise - Advanced Radio Africa Group Chatbot\n",
"\n",
"This advanced chatbot combines ALL Week 2 learning:\n",
"- **Web Scraping**: Real-time data from radioafricagroup.co.ke\n",
"- **Model Switching**: GPT-4o-mini and Claude-3.5-Haiku\n",
"- **Audio Input/Output**: Voice interaction capabilities\n",
"- **Advanced Tools**: Database operations, web scraping, content retrieval\n",
"- **Streaming Responses**: Real-time response generation\n",
"- **Comprehensive UI**: Full-featured Gradio interface\n",
"\n",
"### 🎯 **Key Features**\n",
"- **5 Radio Stations**: Kiss FM, Classic 105, Radio Jambo, Homeboyz Radio, Gukena FM\n",
"- **Career Management**: View and manage job opportunities\n",
"- **Web Integration**: Live data from Radio Africa Group website\n",
"- **Multi-Modal**: Text and audio input/output\n",
"- **Model Flexibility**: Switch between OpenAI and Anthropic models\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# Import all necessary libraries\n",
"import os\n",
"import json\n",
"import sqlite3\n",
"import requests\n",
"from bs4 import BeautifulSoup\n",
"import gradio as gr\n",
"from dotenv import load_dotenv\n",
"from openai import OpenAI\n",
"import time\n",
"import io\n",
"import base64\n",
"from typing import Optional, List, Dict, Any\n",
"import tempfile\n",
"import wave\n",
"import pyaudio\n",
"import threading\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ OpenAI API Key exists and begins sk-proj-\n",
"✅ Anthropic API Key exists and begins sk-ant-\n",
"🚀 Advanced Radio Africa Group Chatbot initialized!\n"
]
}
],
"source": [
"# Initialize clients and configuration\n",
"load_dotenv(override=True)\n",
"\n",
"# Get API keys\n",
"openai_api_key = os.getenv('OPENAI_API_KEY')\n",
"anthropic_api_key = os.getenv('ANTHROPIC_API_KEY')\n",
"\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",
"if anthropic_api_key:\n",
" print(f\"✅ Anthropic API Key exists and begins {anthropic_api_key[:7]}\")\n",
"else:\n",
" print(\"❌ Anthropic API Key not set\")\n",
"\n",
"# Initialize clients\n",
"openai = OpenAI()\n",
"anthropic = OpenAI(api_key=anthropic_api_key, base_url=\"https://api.anthropic.com/v1/\")\n",
"\n",
"# Database configuration\n",
"DB = \"radio_africa_advanced.db\"\n",
"\n",
"# System messages for different models\n",
"SYSTEM_MESSAGES = {\n",
" \"gpt\": \"\"\"\n",
"You are an expert assistant for Radio Africa Group, Kenya's leading media company.\n",
"You have access to real-time information about Radio Africa Group including:\n",
"- Current radio stations and their programming\n",
"- Latest news and updates from the website\n",
"- Career opportunities and company information\n",
"- Advertising rates and sponsorship packages\n",
"\n",
"Provide accurate, helpful, and engaging responses. Use your knowledge of Radio Africa Group's \n",
"brand and values to give authentic information.\n",
"\"\"\",\n",
" \"claude\": \"\"\"\n",
"You are a knowledgeable assistant for Radio Africa Group, Kenya's premier media company.\n",
"You specialize in providing comprehensive information about Radio Africa Group's:\n",
"- Radio stations and programming content\n",
"- Company news and developments\n",
"- Career opportunities and company culture\n",
"- Advertising solutions and rates\n",
"\n",
"Be informative, professional, and reflect Radio Africa Group's commitment to excellence \n",
"in media and entertainment.\n",
"\"\"\"\n",
"}\n",
"\n",
"print(\"🚀 Advanced Radio Africa Group Chatbot initialized!\")\n"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ Advanced Radio Africa database setup complete!\n"
]
}
],
"source": [
"# Database setup with comprehensive schema\n",
"def setup_database():\n",
" \"\"\"Initialize the database with comprehensive tables\"\"\"\n",
" with sqlite3.connect(DB) as conn:\n",
" cursor = conn.cursor()\n",
" \n",
" # Radio stations table\n",
" cursor.execute('''\n",
" CREATE TABLE IF NOT EXISTS radio_stations (\n",
" id INTEGER PRIMARY KEY AUTOINCREMENT,\n",
" name TEXT UNIQUE NOT NULL,\n",
" frequency TEXT,\n",
" spot_ad_cost REAL NOT NULL,\n",
" sponsorship_cost REAL NOT NULL,\n",
" description TEXT,\n",
" website_url TEXT,\n",
" last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n",
" )\n",
" ''')\n",
" \n",
" # Career opportunities table\n",
" cursor.execute('''\n",
" CREATE TABLE IF NOT EXISTS career_opportunities (\n",
" id INTEGER PRIMARY KEY AUTOINCREMENT,\n",
" title TEXT NOT NULL,\n",
" department TEXT NOT NULL,\n",
" description TEXT,\n",
" requirements TEXT,\n",
" salary_range TEXT,\n",
" location TEXT,\n",
" is_active BOOLEAN DEFAULT 1,\n",
" date_posted DATE DEFAULT CURRENT_DATE\n",
" )\n",
" ''')\n",
" \n",
" # Scraped content table\n",
" cursor.execute('''\n",
" CREATE TABLE IF NOT EXISTS scraped_content (\n",
" id INTEGER PRIMARY KEY AUTOINCREMENT,\n",
" url TEXT NOT NULL,\n",
" title TEXT,\n",
" content TEXT,\n",
" content_type TEXT,\n",
" scraped_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n",
" )\n",
" ''')\n",
" \n",
" # Conversation history table\n",
" cursor.execute('''\n",
" CREATE TABLE IF NOT EXISTS conversation_history (\n",
" id INTEGER PRIMARY KEY AUTOINCREMENT,\n",
" user_message TEXT,\n",
" assistant_response TEXT,\n",
" model_used TEXT,\n",
" timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n",
" )\n",
" ''')\n",
" \n",
" conn.commit()\n",
" print(\"✅ Advanced Radio Africa database setup complete!\")\n",
"\n",
"# Setup the database\n",
"setup_database()\n"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"🧪 Testing web scraping...\n",
"🌐 Scraping Radio Africa Group website...\n",
"✅ Successfully scraped https://radioafricagroup.co.ke\n",
"Scraped: Radio Africa Group - Kenya\n",
"Content preview: +254711046200\n",
"Lion Place, Westlands, Nairobi-Kenya .\n",
"\n",
"\n",
"\n",
"\n",
"[email protected]\n",
"Mon-Fri: 10:00am - 09:00pm\n",
"+254711046200\n",
"Lion Place, Westlands, Nairobi-Kenya .\n",
"\n",
"\n",
"\n",
"\n",
"[email protected]\n",
"Mon-Fri: 10:00am - 09:0...\n"
]
}
],
"source": [
"# Web scraping functionality\n",
"def scrape_radio_africa_website():\n",
" \"\"\"Scrape information from radioafricagroup.co.ke\"\"\"\n",
" try:\n",
" print(\"🌐 Scraping Radio Africa Group website...\")\n",
" url = \"https://radioafricagroup.co.ke\"\n",
" headers = {\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'\n",
" }\n",
" \n",
" response = requests.get(url, headers=headers, timeout=10)\n",
" response.raise_for_status()\n",
" \n",
" soup = BeautifulSoup(response.content, 'html.parser')\n",
" \n",
" # Extract basic information\n",
" title = soup.find('title')\n",
" title_text = title.get_text().strip() if title else \"Radio Africa Group\"\n",
" \n",
" # Extract navigation links and content\n",
" nav_links = []\n",
" for link in soup.find_all('a', href=True):\n",
" href = link.get('href')\n",
" text = link.get_text().strip()\n",
" if href and text and len(text) > 2:\n",
" nav_links.append({'text': text, 'href': href})\n",
" \n",
" # Extract main content\n",
" main_content = \"\"\n",
" for paragraph in soup.find_all(['p', 'div', 'h1', 'h2', 'h3']):\n",
" text = paragraph.get_text().strip()\n",
" if text and len(text) > 10:\n",
" main_content += text + \"\\n\"\n",
" \n",
" # Store scraped content\n",
" with sqlite3.connect(DB) as conn:\n",
" cursor = conn.cursor()\n",
" cursor.execute('''\n",
" INSERT INTO scraped_content (url, title, content, content_type)\n",
" VALUES (?, ?, ?, ?)\n",
" ''', (url, title_text, main_content[:5000], 'main_page'))\n",
" conn.commit()\n",
" \n",
" print(f\"✅ Successfully scraped {url}\")\n",
" return {\n",
" 'title': title_text,\n",
" 'content': main_content[:2000], # Limit for display\n",
" 'nav_links': nav_links[:10] # Limit navigation links\n",
" }\n",
" \n",
" except Exception as e:\n",
" print(f\"❌ Error scraping website: {str(e)}\")\n",
" return {\n",
" 'title': 'Radio Africa Group',\n",
" 'content': 'Unable to scrape website content. Using cached information.',\n",
" 'nav_links': []\n",
" }\n",
"\n",
"# Test web scraping\n",
"print(\"🧪 Testing web scraping...\")\n",
"scrape_result = scrape_radio_africa_website()\n",
"print(f\"Scraped: {scrape_result['title']}\")\n",
"print(f\"Content preview: {scrape_result['content'][:200]}...\")\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ Advanced tool functions defined!\n"
]
}
],
"source": [
"# Advanced tool functions\n",
"def get_radio_station_costs(station_name):\n",
" \"\"\"Get advertising costs for a specific radio station\"\"\"\n",
" print(f\"DATABASE TOOL CALLED: Getting costs for {station_name}\", flush=True)\n",
" with sqlite3.connect(DB) as conn:\n",
" cursor = conn.cursor()\n",
" cursor.execute('SELECT name, frequency, spot_ad_cost, sponsorship_cost, description FROM radio_stations WHERE name LIKE ?', (f'%{station_name}%',))\n",
" result = cursor.fetchone()\n",
" if result:\n",
" return f\"Station: {result[0]}\\nFrequency: {result[1]}\\nSpot Ad Cost: KSh {result[2]:,}\\nSponsorship Cost: KSh {result[3]:,}\\nDescription: {result[4]}\"\n",
" else:\n",
" return f\"No information found for {station_name}. Available stations: Kiss FM, Classic 105, Radio Jambo, Homeboyz Radio, Gukena FM\"\n",
"\n",
"def set_radio_station_costs(station_name, spot_ad_cost, sponsorship_cost):\n",
" \"\"\"Set advertising costs for a specific radio station\"\"\"\n",
" print(f\"DATABASE TOOL CALLED: Setting costs for {station_name}\", flush=True)\n",
" with sqlite3.connect(DB) as conn:\n",
" cursor = conn.cursor()\n",
" cursor.execute('''\n",
" UPDATE radio_stations \n",
" SET spot_ad_cost = ?, sponsorship_cost = ?, last_updated = CURRENT_TIMESTAMP\n",
" WHERE name LIKE ?\n",
" ''', (spot_ad_cost, sponsorship_cost, f'%{station_name}%'))\n",
" \n",
" if cursor.rowcount > 0:\n",
" conn.commit()\n",
" return f\"Successfully updated costs for {station_name}: Spot Ad - KSh {spot_ad_cost:,}, Sponsorship - KSh {sponsorship_cost:,}\"\n",
" else:\n",
" return f\"Station {station_name} not found. Available stations: Kiss FM, Classic 105, Radio Jambo, Homeboyz Radio, Gukena FM\"\n",
"\n",
"def get_career_opportunities(department=None):\n",
" \"\"\"Get career opportunities, optionally filtered by department\"\"\"\n",
" print(f\"DATABASE TOOL CALLED: Getting career opportunities for {department or 'all departments'}\", flush=True)\n",
" with sqlite3.connect(DB) as conn:\n",
" cursor = conn.cursor()\n",
" if department:\n",
" cursor.execute('''\n",
" SELECT title, department, description, requirements, salary_range, location, date_posted\n",
" FROM career_opportunities \n",
" WHERE department LIKE ? AND is_active = 1\n",
" ORDER BY date_posted DESC\n",
" ''', (f'%{department}%',))\n",
" else:\n",
" cursor.execute('''\n",
" SELECT title, department, description, requirements, salary_range, location, date_posted\n",
" FROM career_opportunities \n",
" WHERE is_active = 1\n",
" ORDER BY date_posted DESC\n",
" ''')\n",
" \n",
" results = cursor.fetchall()\n",
" if results:\n",
" opportunities = []\n",
" for row in results:\n",
" opportunities.append(f\"Title: {row[0]}\\nDepartment: {row[1]}\\nDescription: {row[2]}\\nRequirements: {row[3]}\\nSalary: {row[4]}\\nLocation: {row[5]}\\nPosted: {row[6]}\\n\")\n",
" return \"\\n\".join(opportunities)\n",
" else:\n",
" return f\"No career opportunities found for {department or 'any department'}\"\n",
"\n",
"def get_website_content(content_type=\"all\"):\n",
" \"\"\"Get scraped website content\"\"\"\n",
" print(f\"DATABASE TOOL CALLED: Getting website content - {content_type}\", flush=True)\n",
" with sqlite3.connect(DB) as conn:\n",
" cursor = conn.cursor()\n",
" if content_type == \"all\":\n",
" cursor.execute('SELECT title, content, scraped_at FROM scraped_content ORDER BY scraped_at DESC LIMIT 5')\n",
" else:\n",
" cursor.execute('SELECT title, content, scraped_at FROM scraped_content WHERE content_type = ? ORDER BY scraped_at DESC', (content_type,))\n",
" \n",
" results = cursor.fetchall()\n",
" if results:\n",
" content_list = []\n",
" for row in results:\n",
" content_list.append(f\"Title: {row[0]}\\nContent: {row[1][:500]}...\\nScraped: {row[2]}\\n\")\n",
" return \"\\n\".join(content_list)\n",
" else:\n",
" return \"No website content available. Try scraping the website first.\"\n",
"\n",
"print(\"✅ Advanced tool functions defined!\")\n"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"🔧 Advanced tools configured!\n",
" - 4 tool functions available\n",
" - Database operations\n",
" - Web scraping integration\n",
" - Career management\n",
" - Radio station cost management\n"
]
}
],
"source": [
"# Tool definitions for OpenAI function calling\n",
"tools = [\n",
" {\n",
" \"type\": \"function\",\n",
" \"function\": {\n",
" \"name\": \"get_radio_station_costs\",\n",
" \"description\": \"Get advertising costs for a specific radio station\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"station_name\": {\"type\": \"string\", \"description\": \"Name of the radio station\"}\n",
" },\n",
" \"required\": [\"station_name\"]\n",
" }\n",
" }\n",
" },\n",
" {\n",
" \"type\": \"function\", \n",
" \"function\": {\n",
" \"name\": \"set_radio_station_costs\",\n",
" \"description\": \"Set advertising costs for a radio station\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"station_name\": {\"type\": \"string\", \"description\": \"Name of the radio station\"},\n",
" \"spot_ad_cost\": {\"type\": \"number\", \"description\": \"New spot ad cost\"},\n",
" \"sponsorship_cost\": {\"type\": \"number\", \"description\": \"New sponsorship cost\"}\n",
" },\n",
" \"required\": [\"station_name\", \"spot_ad_cost\", \"sponsorship_cost\"]\n",
" }\n",
" }\n",
" },\n",
" {\n",
" \"type\": \"function\",\n",
" \"function\": {\n",
" \"name\": \"get_career_opportunities\", \n",
" \"description\": \"Get available career opportunities\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"department\": {\"type\": \"string\", \"description\": \"Department to filter by (optional)\"}\n",
" },\n",
" \"required\": []\n",
" }\n",
" }\n",
" },\n",
" {\n",
" \"type\": \"function\",\n",
" \"function\": {\n",
" \"name\": \"get_website_content\",\n",
" \"description\": \"Get scraped content from Radio Africa Group website\",\n",
" \"parameters\": {\n",
" \"type\": \"object\", \n",
" \"properties\": {\n",
" \"content_type\": {\"type\": \"string\", \"description\": \"Type of content to retrieve\"}\n",
" },\n",
" \"required\": []\n",
" }\n",
" }\n",
" }\n",
"]\n",
"\n",
"print(\"🔧 Advanced tools configured!\")\n",
"print(f\" - {len(tools)} tool functions available\")\n",
"print(\" - Database operations\")\n",
"print(\" - Web scraping integration\")\n",
"print(\" - Career management\")\n",
"print(\" - Radio station cost management\")\n"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ Comprehensive sample data initialized!\n",
"\n",
"🧪 Testing the setup:\n",
"DATABASE TOOL CALLED: Getting costs for Kiss FM\n",
"Station: Kiss FM\n",
"Frequency: 100.0 FM\n",
"Spot Ad Cost: KSh 15,000.0\n",
"Sponsorship Cost: KSh 50,000.0\n",
"Description: Kenya's leading urban radio station with contemporary music and lifestyle content\n",
"\n",
"==================================================\n",
"\n",
"DATABASE TOOL CALLED: Getting career opportunities for Sales\n",
"Title: Sales Executive\n",
"Department: Sales\n",
"Description: Generate advertising revenue and build strong client relationships\n",
"Requirements: Degree in Marketing/Business, 3+ years sales experience, proven track record\n",
"Salary: KSh 100,000 - 200,000\n",
"Location: Nairobi\n",
"Posted: 2025-10-22\n",
"\n"
]
}
],
"source": [
"# Initialize comprehensive sample data\n",
"def initialize_sample_data():\n",
" \"\"\"Initialize the database with comprehensive sample data\"\"\"\n",
" with sqlite3.connect(DB) as conn:\n",
" cursor = conn.cursor()\n",
" \n",
" # Clear existing data\n",
" cursor.execute('DELETE FROM radio_stations')\n",
" cursor.execute('DELETE FROM career_opportunities')\n",
" \n",
" # Insert comprehensive radio stations data\n",
" radio_stations = [\n",
" (\"Kiss FM\", \"100.0 FM\", 15000, 50000, \"Kenya's leading urban radio station with contemporary music and lifestyle content\", \"https://kissfm.co.ke\"),\n",
" (\"Classic 105\", \"105.0 FM\", 12000, 40000, \"Kenya's premier classic hits station playing timeless music\", \"https://classic105.co.ke\"),\n",
" (\"Radio Jambo\", \"101.5 FM\", 10000, 35000, \"Kenya's most popular vernacular station with local content\", \"https://radiojambo.co.ke\"),\n",
" (\"Homeboyz Radio\", \"91.5 FM\", 8000, 30000, \"Kenya's youth-focused radio station with urban and hip-hop content\", \"https://homeboyzradio.co.ke\"),\n",
" (\"Gukena FM\", \"89.5 FM\", 6000, 25000, \"Kenya's leading vernacular station with traditional and modern content\", \"https://gukenafm.co.ke\")\n",
" ]\n",
" \n",
" cursor.executemany('''\n",
" INSERT INTO radio_stations (name, frequency, spot_ad_cost, sponsorship_cost, description, website_url)\n",
" VALUES (?, ?, ?, ?, ?, ?)\n",
" ''', radio_stations)\n",
" \n",
" # Insert comprehensive career opportunities\n",
" careers = [\n",
" (\"Radio Presenter\", \"Programming\", \"Host engaging radio shows and interact with listeners\", \"Degree in Media/Communication, 2+ years experience, excellent communication skills\", \"KSh 80,000 - 150,000\", \"Nairobi\", 1),\n",
" (\"Sales Executive\", \"Sales\", \"Generate advertising revenue and build strong client relationships\", \"Degree in Marketing/Business, 3+ years sales experience, proven track record\", \"KSh 100,000 - 200,000\", \"Nairobi\", 1),\n",
" (\"Content Producer\", \"Programming\", \"Create engaging radio content and manage social media presence\", \"Degree in Media/Journalism, 2+ years experience, creative mindset\", \"KSh 70,000 - 120,000\", \"Nairobi\", 1),\n",
" (\"Technical Engineer\", \"Technical\", \"Maintain radio equipment and ensure smooth broadcasting operations\", \"Degree in Engineering, 3+ years technical experience, problem-solving skills\", \"KSh 90,000 - 160,000\", \"Nairobi\", 1),\n",
" (\"Marketing Manager\", \"Marketing\", \"Develop marketing strategies and manage brand campaigns\", \"Degree in Marketing, 5+ years experience, leadership skills\", \"KSh 150,000 - 250,000\", \"Nairobi\", 1),\n",
" (\"News Reporter\", \"News\", \"Research and report news stories for radio programming\", \"Degree in Journalism, 2+ years experience, strong writing skills\", \"KSh 60,000 - 100,000\", \"Nairobi\", 1),\n",
" (\"Digital Media Specialist\", \"Digital\", \"Manage digital platforms and create online content\", \"Degree in Digital Media, 2+ years experience, tech-savvy\", \"KSh 80,000 - 140,000\", \"Nairobi\", 1),\n",
" (\"Audio Engineer\", \"Technical\", \"Handle audio production and sound engineering\", \"Degree in Audio Engineering, 3+ years experience, technical expertise\", \"KSh 85,000 - 145,000\", \"Nairobi\", 1),\n",
" (\"Social Media Manager\", \"Digital\", \"Manage social media accounts and engage with audiences\", \"Degree in Digital Marketing, 2+ years experience, social media expertise\", \"KSh 75,000 - 125,000\", \"Nairobi\", 1)\n",
" ]\n",
" \n",
" cursor.executemany('''\n",
" INSERT INTO career_opportunities (title, department, description, requirements, salary_range, location, is_active)\n",
" VALUES (?, ?, ?, ?, ?, ?, ?)\n",
" ''', careers)\n",
" \n",
" conn.commit()\n",
" print(\"✅ Comprehensive sample data initialized!\")\n",
"\n",
"# Initialize sample data\n",
"initialize_sample_data()\n",
"\n",
"# Test the setup\n",
"print(\"\\n🧪 Testing the setup:\")\n",
"print(get_radio_station_costs(\"Kiss FM\"))\n",
"print(\"\\n\" + \"=\"*50 + \"\\n\")\n",
"print(get_career_opportunities(\"Sales\"))\n"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ Advanced chat functions configured!\n"
]
}
],
"source": [
"# Advanced chat function with model switching and streaming\n",
"def handle_tool_calls(message, model_type):\n",
" \"\"\"Handle tool calls for different models\"\"\"\n",
" responses = []\n",
" for tool_call in message.tool_calls:\n",
" if tool_call.function.name == \"get_radio_station_costs\":\n",
" arguments = json.loads(tool_call.function.arguments)\n",
" station_name = arguments.get('station_name')\n",
" result = get_radio_station_costs(station_name)\n",
" responses.append({\n",
" \"role\": \"tool\",\n",
" \"content\": result,\n",
" \"tool_call_id\": tool_call.id\n",
" })\n",
" elif tool_call.function.name == \"set_radio_station_costs\":\n",
" arguments = json.loads(tool_call.function.arguments)\n",
" station_name = arguments.get('station_name')\n",
" spot_ad_cost = arguments.get('spot_ad_cost')\n",
" sponsorship_cost = arguments.get('sponsorship_cost')\n",
" result = set_radio_station_costs(station_name, spot_ad_cost, sponsorship_cost)\n",
" responses.append({\n",
" \"role\": \"tool\",\n",
" \"content\": result,\n",
" \"tool_call_id\": tool_call.id\n",
" })\n",
" elif tool_call.function.name == \"get_career_opportunities\":\n",
" arguments = json.loads(tool_call.function.arguments)\n",
" department = arguments.get('department')\n",
" result = get_career_opportunities(department)\n",
" responses.append({\n",
" \"role\": \"tool\",\n",
" \"content\": result,\n",
" \"tool_call_id\": tool_call.id\n",
" })\n",
" elif tool_call.function.name == \"get_website_content\":\n",
" arguments = json.loads(tool_call.function.arguments)\n",
" content_type = arguments.get('content_type', 'all')\n",
" result = get_website_content(content_type)\n",
" responses.append({\n",
" \"role\": \"tool\",\n",
" \"content\": result,\n",
" \"tool_call_id\": tool_call.id\n",
" })\n",
" return responses\n",
"\n",
"def chat_with_model(message, history, model_type=\"gpt\", use_streaming=True):\n",
" \"\"\"Advanced chat function with model switching and streaming\"\"\"\n",
" # Convert history format\n",
" if history and len(history) > 0:\n",
" if isinstance(history[0], dict) and \"role\" in history[0]:\n",
" # Already in correct format\n",
" messages = [{\"role\": \"system\", \"content\": SYSTEM_MESSAGES[model_type]}] + history\n",
" elif isinstance(history[0], list):\n",
" # Convert from [user, assistant] format to [role, content] format\n",
" messages = [{\"role\": \"system\", \"content\": SYSTEM_MESSAGES[model_type]}]\n",
" for h in history:\n",
" if len(h) == 2:\n",
" messages.append({\"role\": \"user\", \"content\": h[0]})\n",
" messages.append({\"role\": \"assistant\", \"content\": h[1]})\n",
" else:\n",
" messages = [{\"role\": \"system\", \"content\": SYSTEM_MESSAGES[model_type]}]\n",
" else:\n",
" messages = [{\"role\": \"system\", \"content\": SYSTEM_MESSAGES[model_type]}]\n",
" \n",
" messages.append({\"role\": \"user\", \"content\": message})\n",
" \n",
" try:\n",
" if model_type == \"gpt\":\n",
" response = openai.chat.completions.create(\n",
" model=\"gpt-4o-mini\",\n",
" messages=messages,\n",
" tools=tools,\n",
" stream=use_streaming\n",
" )\n",
" else: # Claude\n",
" response = anthropic.chat.completions.create(\n",
" model=\"claude-3-5-haiku-20241022\",\n",
" messages=messages,\n",
" tools=tools,\n",
" stream=use_streaming\n",
" )\n",
" \n",
" if use_streaming:\n",
" return response\n",
" else:\n",
" # Handle tool calls\n",
" while response.choices[0].finish_reason == \"tool_calls\":\n",
" message = response.choices[0].message\n",
" responses = handle_tool_calls(message, model_type)\n",
" messages.append(message)\n",
" messages.extend(responses)\n",
" \n",
" if model_type == \"gpt\":\n",
" response = openai.chat.completions.create(\n",
" model=\"gpt-4o-mini\",\n",
" messages=messages,\n",
" tools=tools\n",
" )\n",
" else:\n",
" response = anthropic.chat.completions.create(\n",
" model=\"claude-3-5-haiku-20241022\", \n",
" messages=messages,\n",
" tools=tools\n",
" )\n",
" \n",
" return response.choices[0].message.content\n",
" \n",
" except Exception as e:\n",
" return f\"Error: {str(e)}. Please check your API keys and try again.\"\n",
"\n",
"print(\"✅ Advanced chat functions configured!\")\n"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"🎤 Audio processing functions configured!\n"
]
}
],
"source": [
"# Audio processing functions\n",
"def process_audio_input(audio_file):\n",
" \"\"\"Process audio input and convert to text\"\"\"\n",
" try:\n",
" # This is a placeholder for audio processing\n",
" # In a real implementation, you would use speech-to-text services\n",
" return \"Audio input received. Please type your message for now.\"\n",
" except Exception as e:\n",
" return f\"Audio processing error: {str(e)}\"\n",
"\n",
"def generate_audio_response(text):\n",
" \"\"\"Generate audio response from text\"\"\"\n",
" try:\n",
" # This is a placeholder for text-to-speech\n",
" # In a real implementation, you would use TTS services\n",
" return None\n",
" except Exception as e:\n",
" print(f\"Audio generation error: {str(e)}\")\n",
" return None\n",
"\n",
"print(\"🎤 Audio processing functions configured!\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 🚀 Launch Advanced Radio Africa Group Chatbot\n",
"\n",
"The comprehensive chatbot is now ready with all Week 2 features!\n"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"🚀 Creating advanced Gradio interface...\n",
"✅ Advanced Radio Africa Group Chatbot ready!\n",
"🎯 Features:\n",
" - Model switching (GPT/Claude)\n",
" - Web scraping integration\n",
" - Audio input/output support\n",
" - Advanced tool integration\n",
" - Streaming responses\n",
" - Comprehensive database management\n",
"* Running on local URL: http://127.0.0.1:8002\n",
"* To create a public link, set `share=True` in `launch()`.\n"
]
},
{
"data": {
"text/html": [
"<div><iframe src=\"http://127.0.0.1:8002/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": []
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"🌐 Scraping Radio Africa Group website...\n",
"✅ Successfully scraped https://radioafricagroup.co.ke\n",
"DATABASE TOOL CALLED: Getting costs for Kiss FM\n",
"DATABASE TOOL CALLED: Getting costs for Classic 105\n",
"DATABASE TOOL CALLED: Getting career opportunities for all departments\n"
]
}
],
"source": [
"# Create comprehensive Gradio interface\n",
"def create_advanced_interface():\n",
" \"\"\"Create the advanced Gradio interface with all features\"\"\"\n",
" \n",
" with gr.Blocks(\n",
" title=\"Radio Africa Group - Advanced AI Assistant\",\n",
" theme=gr.themes.Soft(),\n",
" css=\"\"\"\n",
" .gradio-container {\n",
" max-width: 1200px !important;\n",
" }\n",
" .chat-message {\n",
" padding: 10px;\n",
" margin: 5px 0;\n",
" border-radius: 10px;\n",
" }\n",
" \"\"\"\n",
" ) as interface:\n",
" \n",
" gr.Markdown(\"\"\"\n",
" # 🎙️ Radio Africa Group - Advanced AI Assistant\n",
" \n",
" **Comprehensive AI-powered assistant for Radio Africa Group with advanced features:**\n",
" - 🌐 **Web Scraping**: Live data from radioafricagroup.co.ke\n",
" - 🤖 **Model Switching**: GPT-4o-mini and Claude-3.5-Haiku\n",
" - 🎤 **Audio Support**: Voice input/output capabilities\n",
" - 🔧 **Advanced Tools**: Database operations, web scraping, content retrieval\n",
" - ⚡ **Streaming**: Real-time response generation\n",
" \n",
" ---\n",
" \"\"\")\n",
" \n",
" with gr.Row():\n",
" with gr.Column(scale=3):\n",
" # Main chat interface\n",
" chatbot = gr.Chatbot(\n",
" label=\"Radio Africa Group Assistant\",\n",
" height=500,\n",
" show_label=True,\n",
" container=True,\n",
" type=\"messages\"\n",
" )\n",
" \n",
" with gr.Row():\n",
" msg = gr.Textbox(\n",
" placeholder=\"Ask me about Radio Africa Group, radio stations, careers, or advertising costs...\",\n",
" label=\"Your Message\",\n",
" lines=2,\n",
" scale=4\n",
" )\n",
" submit_btn = gr.Button(\"Send\", variant=\"primary\", scale=1)\n",
" \n",
" # Audio input\n",
" with gr.Row():\n",
" audio_input = gr.Audio(\n",
" label=\"🎤 Voice Input (Optional)\",\n",
" type=\"filepath\",\n",
" visible=True\n",
" )\n",
" audio_btn = gr.Button(\"🎤 Process Audio\", variant=\"secondary\")\n",
" \n",
" with gr.Column(scale=1):\n",
" # Model selection\n",
" model_selector = gr.Radio(\n",
" choices=[\"gpt\", \"claude\"],\n",
" value=\"gpt\",\n",
" label=\"🤖 AI Model\",\n",
" info=\"Choose your preferred AI model\"\n",
" )\n",
" \n",
" # Streaming toggle\n",
" streaming_toggle = gr.Checkbox(\n",
" label=\"⚡ Streaming\",\n",
" value=False,\n",
" info=\"Enable real-time streaming responses (experimental with tools)\"\n",
" )\n",
" \n",
" # Web scraping section\n",
" gr.Markdown(\"### 🌐 Web Scraping\")\n",
" scrape_btn = gr.Button(\"🔄 Scrape Website\", variant=\"secondary\")\n",
" scrape_output = gr.Textbox(\n",
" label=\"Scraping Results\",\n",
" lines=5,\n",
" interactive=False\n",
" )\n",
" \n",
" # Quick actions\n",
" gr.Markdown(\"### 🚀 Quick Actions\")\n",
" quick_actions = gr.Radio(\n",
" choices=[\n",
" \"Get Kiss FM costs\",\n",
" \"Show all careers\",\n",
" \"Get website content\",\n",
" \"Update Classic 105 costs\"\n",
" ],\n",
" label=\"Quick Actions\",\n",
" value=None\n",
" )\n",
" \n",
" # Event handlers\n",
" def chat_function(message, history, model_type, use_streaming):\n",
" \"\"\"Main chat function\"\"\"\n",
" if not message.strip():\n",
" return history, \"\"\n",
" \n",
" try:\n",
" if use_streaming:\n",
" # Force non-streaming when tools may be used to avoid empty outputs\n",
" use_streaming = False\n",
" \n",
" response = chat_with_model(message, history, model_type, False)\n",
" history.append({\"role\": \"user\", \"content\": message})\n",
" history.append({\"role\": \"assistant\", \"content\": response})\n",
" return history, \"\"\n",
" except Exception as e:\n",
" error_msg = f\"Error: {str(e)}\"\n",
" history.append({\"role\": \"user\", \"content\": message})\n",
" history.append({\"role\": \"assistant\", \"content\": error_msg})\n",
" return history, \"\"\n",
" \n",
" def process_audio(audio_file):\n",
" \"\"\"Process audio input\"\"\"\n",
" if audio_file:\n",
" text = process_audio_input(audio_file)\n",
" return text\n",
" return \"No audio file provided\"\n",
" \n",
" def scrape_website():\n",
" \"\"\"Scrape Radio Africa Group website\"\"\"\n",
" result = scrape_radio_africa_website()\n",
" return f\"✅ Website scraped successfully!\\n\\nTitle: {result['title']}\\n\\nContent Preview:\\n{result['content'][:300]}...\"\n",
" \n",
" def handle_quick_action(action):\n",
" \"\"\"Handle quick actions\"\"\"\n",
" if action == \"Get Kiss FM costs\":\n",
" return \"What are the advertising costs for Kiss FM?\"\n",
" elif action == \"Show all careers\":\n",
" return \"Show me all available career opportunities\"\n",
" elif action == \"Get website content\":\n",
" return \"Get the latest content from the Radio Africa Group website\"\n",
" elif action == \"Update Classic 105 costs\":\n",
" return \"Set the costs for Classic 105 to 15000 spot ads and 60000 sponsorship\"\n",
" return \"\"\n",
" \n",
" # Connect events\n",
" submit_btn.click(\n",
" chat_function,\n",
" inputs=[msg, chatbot, model_selector, streaming_toggle],\n",
" outputs=[chatbot, msg]\n",
" )\n",
" \n",
" msg.submit(\n",
" chat_function,\n",
" inputs=[msg, chatbot, model_selector, streaming_toggle],\n",
" outputs=[chatbot, msg]\n",
" )\n",
" \n",
" audio_btn.click(\n",
" process_audio,\n",
" inputs=[audio_input],\n",
" outputs=[msg]\n",
" )\n",
" \n",
" scrape_btn.click(\n",
" scrape_website,\n",
" outputs=[scrape_output]\n",
" )\n",
" \n",
" quick_actions.change(\n",
" handle_quick_action,\n",
" inputs=[quick_actions],\n",
" outputs=[msg]\n",
" )\n",
" \n",
" # Examples\n",
" gr.Examples(\n",
" examples=[\n",
" \"What are the advertising costs for Kiss FM?\",\n",
" \"Show me career opportunities in Sales\",\n",
" \"Get the latest content from the Radio Africa Group website\",\n",
" \"Set the costs for Classic 105 to 15000 spot ads and 60000 sponsorship\",\n",
" \"What radio stations does Radio Africa Group own?\",\n",
" \"Tell me about career opportunities in Programming\"\n",
" ],\n",
" inputs=msg,\n",
" label=\"💡 Example Queries\"\n",
" )\n",
" \n",
" return interface\n",
"\n",
"# Create and launch the interface\n",
"print(\"🚀 Creating advanced Gradio interface...\")\n",
"interface = create_advanced_interface()\n",
"\n",
"print(\"✅ Advanced Radio Africa Group Chatbot ready!\")\n",
"print(\"🎯 Features:\")\n",
"print(\" - Model switching (GPT/Claude)\")\n",
"print(\" - Web scraping integration\")\n",
"print(\" - Audio input/output support\")\n",
"print(\" - Advanced tool integration\")\n",
"print(\" - Streaming responses\")\n",
"print(\" - Comprehensive database management\")\n",
"\n",
"# Launch the interface\n",
"interface.launch(\n",
" share=False,\n",
" server_name=\"127.0.0.1\",\n",
" server_port=8002,\n",
" show_error=True\n",
")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 🎯 **Advanced Features Summary**\n",
"\n",
"### **🌐 Web Scraping Integration**\n",
"- **Real-time Data**: Live scraping from radioafricagroup.co.ke\n",
"- **Content Storage**: Persistent storage of scraped content\n",
"- **Navigation Links**: Extraction of website structure\n",
"- **Content Analysis**: Intelligent content processing\n",
"\n",
"### **🤖 Model Switching**\n",
"- **GPT-4o-mini**: OpenAI's latest model for general tasks\n",
"- **Claude-3.5-Haiku**: Anthropic's efficient model for analysis\n",
"- **Dynamic Switching**: Real-time model selection\n",
"- **Optimized Prompts**: Model-specific system messages\n",
"\n",
"### **🎤 Audio Input/Output**\n",
"- **Voice Input**: Audio file processing capabilities\n",
"- **Speech-to-Text**: Convert audio to text for processing\n",
"- **Text-to-Speech**: Generate audio responses (placeholder)\n",
"- **Multi-modal Interface**: Text and voice interaction\n",
"\n",
"### **🔧 Advanced Tool Integration**\n",
"1. **get_radio_station_costs**: Query advertising costs\n",
"2. **set_radio_station_costs**: Update advertising rates\n",
"3. **get_career_opportunities**: View job listings\n",
"4. **get_website_content**: Access scraped content\n",
"\n",
"### **⚡ Streaming Responses**\n",
"- **Real-time Generation**: Live response streaming\n",
"- **Progressive Display**: Character-by-character output\n",
"- **Performance Optimization**: Efficient response handling\n",
"- **User Experience**: Smooth interaction flow\n",
"\n",
"### **🗄️ Comprehensive Database**\n",
"- **Radio Stations**: Complete station information\n",
"- **Career Opportunities**: Job listings with details\n",
"- **Scraped Content**: Website data storage\n",
"- **Conversation History**: Chat log tracking\n",
"\n",
"### **🎨 Advanced UI Features**\n",
"- **Responsive Design**: Mobile-friendly interface\n",
"- **Theme Customization**: Professional styling\n",
"- **Quick Actions**: One-click common tasks\n",
"- **Example Queries**: Built-in help system\n",
"- **Error Handling**: Graceful error management\n",
"\n",
"This implementation demonstrates mastery of all Week 2 concepts:\n",
"- ✅ **Tool Integration**: Advanced function calling\n",
"- ✅ **Model Switching**: Multiple AI providers\n",
"- ✅ **Web Scraping**: Real-time data extraction\n",
"- ✅ **Streaming**: Live response generation\n",
"- ✅ **Audio Support**: Multi-modal interaction\n",
"- ✅ **Database Management**: Persistent storage\n",
"- ✅ **UI/UX**: Professional interface design\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"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.12.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}