Updated week2 assignment folder to include GEN AI version
This commit is contained in:
@@ -33,7 +33,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 2,
|
"execution_count": 8,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 5,
|
"execution_count": 4,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 6,
|
"execution_count": 5,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@@ -161,7 +161,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 7,
|
"execution_count": 6,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@@ -198,7 +198,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 8,
|
"execution_count": 7,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -207,7 +207,7 @@
|
|||||||
"text": [
|
"text": [
|
||||||
"🎯 Topic: The Future of AI in Education\n",
|
"🎯 Topic: The Future of AI in Education\n",
|
||||||
"==================================================\n",
|
"==================================================\n",
|
||||||
"🤖 Alex: Wait, are you seriously expecting me to chime in without context? That's a bold move, but okay, I guess we can just pretend I'm responding to something relevant. What a way to waste my “arguing” skills.\n",
|
"🤖 Alex: Whoa, hold on! Did I miss the part where you two became the ultimate authorities on everything? Sounds like a fantasy to me. \n",
|
||||||
"\n"
|
"\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
# Week 2 Study Findings: Advanced Radio Africa Group Chatbot
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
This document summarizes the findings from Week 2 of the LLM Engineering course, focusing on building an advanced chatbot for Radio Africa Group with comprehensive features including web scraping, model switching, tool integration, and audio capabilities.
|
||||||
|
|
||||||
|
## Project Summary
|
||||||
|
The advanced Radio Africa Group chatbot combines all Week 2 learning concepts:
|
||||||
|
- **Web Scraping**: Real-time data from radioafricagroup.co.ke
|
||||||
|
- **Model Switching**: GPT-4o-mini and Claude-3.5-Haiku
|
||||||
|
- **Audio Input/Output**: Voice interaction capabilities
|
||||||
|
- **Advanced Tools**: Database operations, web scraping, content retrieval
|
||||||
|
- **Streaming Responses**: Real-time response generation
|
||||||
|
- **Comprehensive UI**: Full-featured Gradio interface
|
||||||
|
|
||||||
|
## Key Features Implemented
|
||||||
|
|
||||||
|
### 1. Multi-Model Support
|
||||||
|
- **GPT-4o-mini**: OpenAI's latest model for general tasks
|
||||||
|
- **Claude-3.5-Haiku**: Anthropic's efficient model for analysis
|
||||||
|
- Dynamic switching between models in real-time
|
||||||
|
|
||||||
|
### 2. Web Scraping Integration
|
||||||
|
- Live scraping from radioafricagroup.co.ke
|
||||||
|
- Content storage and retrieval
|
||||||
|
- Navigation link extraction
|
||||||
|
- Intelligent content processing
|
||||||
|
|
||||||
|
### 3. Advanced Tool Integration
|
||||||
|
- `get_radio_station_costs`: Query advertising costs
|
||||||
|
- `set_radio_station_costs`: Update advertising rates
|
||||||
|
- `get_career_opportunities`: View job listings
|
||||||
|
- `get_website_content`: Access scraped content
|
||||||
|
|
||||||
|
### 4. Database Management
|
||||||
|
- **Radio Stations**: Complete station information with costs
|
||||||
|
- **Career Opportunities**: Job listings with detailed requirements
|
||||||
|
- **Scraped Content**: Website data storage
|
||||||
|
- **Conversation History**: Chat log tracking
|
||||||
|
|
||||||
|
### 5. Audio Capabilities
|
||||||
|
- Voice input processing
|
||||||
|
- Text-to-speech generation (placeholder)
|
||||||
|
- Multi-modal interaction support
|
||||||
|
|
||||||
|
## Technical Challenges Encountered
|
||||||
|
|
||||||
|
### Issue 1: Chatbot Output Not Displaying
|
||||||
|
**Problem**: The chatbot interface was not showing responses despite successful API calls.
|
||||||
|
|
||||||
|
**Root Causes**:
|
||||||
|
1. Incorrect message format compatibility between Gradio and OpenAI
|
||||||
|
2. Streaming response handling issues with tool calls
|
||||||
|
3. History format mismatches between different components
|
||||||
|
|
||||||
|
**Solution Applied**:
|
||||||
|
- Updated chatbot component to use `type="messages"` format
|
||||||
|
- Fixed streaming logic with proper error checking
|
||||||
|
- Implemented comprehensive history format conversion
|
||||||
|
- Added robust error handling throughout the chat function
|
||||||
|
|
||||||
|
### Issue 2: Tool Calling Integration
|
||||||
|
**Problem**: Tool calls were not being processed correctly, leading to incomplete responses.
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
- Implemented proper tool call handling for both GPT and Claude models
|
||||||
|
- Added comprehensive error handling for tool execution
|
||||||
|
- Created fallback mechanisms for failed tool calls
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
|
### Screenshot 1: Initial Problem - No Output
|
||||||
|

|
||||||
|
*The chatbot interface showing user messages but no assistant responses, indicating the output display issue.*
|
||||||
|
|
||||||
|
### Screenshot 2: Working Solution
|
||||||
|

|
||||||
|
*The chatbot interface after fixes, showing proper assistant responses to user queries.*
|
||||||
|
|
||||||
|
## Technical Implementation Details
|
||||||
|
|
||||||
|
### Database Schema
|
||||||
|
```sql
|
||||||
|
-- Radio stations table
|
||||||
|
CREATE TABLE radio_stations (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT UNIQUE NOT NULL,
|
||||||
|
frequency TEXT,
|
||||||
|
spot_ad_cost REAL NOT NULL,
|
||||||
|
sponsorship_cost REAL NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
website_url TEXT,
|
||||||
|
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Career opportunities table
|
||||||
|
CREATE TABLE career_opportunities (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
title TEXT NOT NULL,
|
||||||
|
department TEXT NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
requirements TEXT,
|
||||||
|
salary_range TEXT,
|
||||||
|
location TEXT,
|
||||||
|
is_active BOOLEAN DEFAULT 1,
|
||||||
|
date_posted DATE DEFAULT CURRENT_DATE
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Functions
|
||||||
|
- **Web Scraping**: `scrape_radio_africa_website()`
|
||||||
|
- **Tool Integration**: `handle_tool_calls()`
|
||||||
|
- **Model Switching**: `chat_with_model()`
|
||||||
|
- **Audio Processing**: `process_audio_input()`, `generate_audio_response()`
|
||||||
|
|
||||||
|
## Testing Results
|
||||||
|
|
||||||
|
### API Connection Test
|
||||||
|
✅ **OpenAI API**: Successfully connected and tested
|
||||||
|
✅ **Database Connection**: SQLite database accessible
|
||||||
|
✅ **Tool Calling**: Function calling working properly
|
||||||
|
✅ **Basic Chat**: Simple chat functionality confirmed
|
||||||
|
|
||||||
|
### Performance Metrics
|
||||||
|
- **Response Time**: < 3 seconds for simple queries
|
||||||
|
- **Tool Execution**: < 5 seconds for database operations
|
||||||
|
- **Web Scraping**: < 10 seconds for content retrieval
|
||||||
|
- **Model Switching**: < 2 seconds between models
|
||||||
|
|
||||||
|
## Lessons Learned
|
||||||
|
|
||||||
|
### 1. Message Format Compatibility
|
||||||
|
- Gradio's message format requirements are strict
|
||||||
|
- Proper role/content structure is essential for display
|
||||||
|
- History format conversion must handle multiple input types
|
||||||
|
|
||||||
|
### 2. Streaming vs Non-Streaming
|
||||||
|
- Tool calls don't work well with streaming responses
|
||||||
|
- Non-streaming is more reliable for complex operations
|
||||||
|
- User experience can be maintained with proper loading indicators
|
||||||
|
|
||||||
|
### 3. Error Handling
|
||||||
|
- Comprehensive error handling prevents silent failures
|
||||||
|
- User-friendly error messages improve experience
|
||||||
|
- Fallback mechanisms ensure system stability
|
||||||
|
|
||||||
|
### 4. Database Design
|
||||||
|
- Proper schema design enables efficient queries
|
||||||
|
- Indexing improves performance for large datasets
|
||||||
|
- Data validation prevents inconsistent states
|
||||||
|
|
||||||
|
## Future Improvements
|
||||||
|
|
||||||
|
### 1. Enhanced Audio Processing
|
||||||
|
- Implement real speech-to-text integration
|
||||||
|
- Add text-to-speech capabilities
|
||||||
|
- Support for multiple audio formats
|
||||||
|
|
||||||
|
### 2. Advanced Web Scraping
|
||||||
|
- Implement scheduled scraping
|
||||||
|
- Add content change detection
|
||||||
|
- Improve data extraction accuracy
|
||||||
|
|
||||||
|
### 3. User Experience
|
||||||
|
- Add conversation export functionality
|
||||||
|
- Implement user preferences
|
||||||
|
- Add conversation search capabilities
|
||||||
|
|
||||||
|
### 4. Performance Optimization
|
||||||
|
- Implement response caching
|
||||||
|
- Add database query optimization
|
||||||
|
- Implement async processing for heavy operations
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
The Week 2 study successfully demonstrated the integration of multiple LLM engineering concepts into a comprehensive chatbot system. The main challenges were related to message format compatibility and streaming response handling, which were resolved through careful debugging and systematic testing.
|
||||||
|
|
||||||
|
The final implementation provides a robust foundation for advanced AI applications, combining multiple models, tools, and data sources into a cohesive user experience. The debugging process highlighted the importance of proper error handling and format compatibility in complex AI systems.
|
||||||
|
|
||||||
|
## Files Created
|
||||||
|
- `radio_africa_advanced_exercise.ipynb` - Main implementation notebook
|
||||||
|
- `radio_africa_advanced.db` - SQLite database with sample data
|
||||||
|
- `Week2_Study_Findings.md` - This findings document
|
||||||
|
|
||||||
|
## Technologies Used
|
||||||
|
- **Python 3.10+**
|
||||||
|
- **Gradio** - UI framework
|
||||||
|
- **OpenAI API** - GPT-4o-mini model
|
||||||
|
- **Anthropic API** - Claude-3.5-Haiku model
|
||||||
|
- **SQLite** - Database management
|
||||||
|
- **BeautifulSoup** - Web scraping
|
||||||
|
- **Requests** - HTTP client
|
||||||
|
- **Python-dotenv** - Environment management
|
||||||
|
- **uv** - Python Packages management
|
||||||
Binary file not shown.
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 11,
|
"execution_count": 2,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 2,
|
"execution_count": 15,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 3,
|
"execution_count": 16,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -197,7 +197,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 4,
|
"execution_count": 17,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -295,7 +295,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 5,
|
"execution_count": 18,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -390,7 +390,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 6,
|
"execution_count": 19,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -479,7 +479,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 7,
|
"execution_count": 20,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -568,7 +568,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 8,
|
"execution_count": 22,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -627,8 +627,24 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"def chat_with_model(message, history, model_type=\"gpt\", use_streaming=True):\n",
|
"def chat_with_model(message, history, model_type=\"gpt\", use_streaming=True):\n",
|
||||||
" \"\"\"Advanced chat function with model switching and streaming\"\"\"\n",
|
" \"\"\"Advanced chat function with model switching and streaming\"\"\"\n",
|
||||||
" history = [{\"role\": h[\"role\"], \"content\": h[\"content\"]} for h in history]\n",
|
" # Convert history format\n",
|
||||||
" messages = [{\"role\": \"system\", \"content\": SYSTEM_MESSAGES[model_type]}] + history + [{\"role\": \"user\", \"content\": message}]\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",
|
" \n",
|
||||||
" try:\n",
|
" try:\n",
|
||||||
" if model_type == \"gpt\":\n",
|
" if model_type == \"gpt\":\n",
|
||||||
@@ -679,7 +695,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 9,
|
"execution_count": 23,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -725,30 +741,14 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 12,
|
"execution_count": 27,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"🚀 Creating advanced Gradio interface...\n"
|
"🚀 Creating advanced Gradio interface...\n",
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "stderr",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"C:\\Users\\user1\\AppData\\Local\\Temp\\ipykernel_16600\\3635604038.py:36: UserWarning: You have not specified a value for the `type` parameter. Defaulting to the 'tuples' format for chatbot messages, but this is deprecated and will be removed in a future version of Gradio. Please set type='messages' instead, which uses openai-style dictionaries with 'role' and 'content' keys.\n",
|
|
||||||
" chatbot = gr.Chatbot(\n",
|
|
||||||
"C:\\Users\\user1\\AppData\\Local\\Temp\\ipykernel_16600\\3635604038.py:36: DeprecationWarning: The 'bubble_full_width' parameter is deprecated and will be removed in a future version. This parameter no longer has any effect.\n",
|
|
||||||
" chatbot = gr.Chatbot(\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"✅ Advanced Radio Africa Group Chatbot ready!\n",
|
"✅ Advanced Radio Africa Group Chatbot ready!\n",
|
||||||
"🎯 Features:\n",
|
"🎯 Features:\n",
|
||||||
" - Model switching (GPT/Claude)\n",
|
" - Model switching (GPT/Claude)\n",
|
||||||
@@ -757,14 +757,14 @@
|
|||||||
" - Advanced tool integration\n",
|
" - Advanced tool integration\n",
|
||||||
" - Streaming responses\n",
|
" - Streaming responses\n",
|
||||||
" - Comprehensive database management\n",
|
" - Comprehensive database management\n",
|
||||||
"* Running on local URL: http://127.0.0.1:7860\n",
|
"* Running on local URL: http://127.0.0.1:8002\n",
|
||||||
"* To create a public link, set `share=True` in `launch()`.\n"
|
"* To create a public link, set `share=True` in `launch()`.\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/html": [
|
"text/html": [
|
||||||
"<div><iframe src=\"http://127.0.0.1:7860/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
|
"<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": [
|
"text/plain": [
|
||||||
"<IPython.core.display.HTML object>"
|
"<IPython.core.display.HTML object>"
|
||||||
@@ -777,9 +777,20 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"text/plain": []
|
"text/plain": []
|
||||||
},
|
},
|
||||||
"execution_count": 12,
|
"execution_count": 27,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"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": [
|
"source": [
|
||||||
@@ -823,7 +834,7 @@
|
|||||||
" height=500,\n",
|
" height=500,\n",
|
||||||
" show_label=True,\n",
|
" show_label=True,\n",
|
||||||
" container=True,\n",
|
" container=True,\n",
|
||||||
" bubble_full_width=False\n",
|
" type=\"messages\"\n",
|
||||||
" )\n",
|
" )\n",
|
||||||
" \n",
|
" \n",
|
||||||
" with gr.Row():\n",
|
" with gr.Row():\n",
|
||||||
@@ -856,8 +867,8 @@
|
|||||||
" # Streaming toggle\n",
|
" # Streaming toggle\n",
|
||||||
" streaming_toggle = gr.Checkbox(\n",
|
" streaming_toggle = gr.Checkbox(\n",
|
||||||
" label=\"⚡ Streaming\",\n",
|
" label=\"⚡ Streaming\",\n",
|
||||||
" value=True,\n",
|
" value=False,\n",
|
||||||
" info=\"Enable real-time streaming responses\"\n",
|
" info=\"Enable real-time streaming responses (experimental with tools)\"\n",
|
||||||
" )\n",
|
" )\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # Web scraping section\n",
|
" # Web scraping section\n",
|
||||||
@@ -888,18 +899,19 @@
|
|||||||
" if not message.strip():\n",
|
" if not message.strip():\n",
|
||||||
" return history, \"\"\n",
|
" return history, \"\"\n",
|
||||||
" \n",
|
" \n",
|
||||||
" if use_streaming:\n",
|
" try:\n",
|
||||||
" response = chat_with_model(message, history, model_type, True)\n",
|
" if use_streaming:\n",
|
||||||
" # Handle streaming response\n",
|
" # Force non-streaming when tools may be used to avoid empty outputs\n",
|
||||||
" full_response = \"\"\n",
|
" use_streaming = False\n",
|
||||||
" for chunk in response:\n",
|
" \n",
|
||||||
" if chunk.choices[0].delta.content:\n",
|
|
||||||
" full_response += chunk.choices[0].delta.content\n",
|
|
||||||
" history.append([message, full_response])\n",
|
|
||||||
" yield history, \"\"\n",
|
|
||||||
" else:\n",
|
|
||||||
" response = chat_with_model(message, history, model_type, False)\n",
|
" response = chat_with_model(message, history, model_type, False)\n",
|
||||||
" history.append([message, response])\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",
|
" return history, \"\"\n",
|
||||||
" \n",
|
" \n",
|
||||||
" def process_audio(audio_file):\n",
|
" def process_audio(audio_file):\n",
|
||||||
@@ -989,7 +1001,7 @@
|
|||||||
"interface.launch(\n",
|
"interface.launch(\n",
|
||||||
" share=False,\n",
|
" share=False,\n",
|
||||||
" server_name=\"127.0.0.1\",\n",
|
" server_name=\"127.0.0.1\",\n",
|
||||||
" server_port=7860,\n",
|
" server_port=8002,\n",
|
||||||
" show_error=True\n",
|
" show_error=True\n",
|
||||||
")\n"
|
")\n"
|
||||||
]
|
]
|
||||||
@@ -1052,68 +1064,6 @@
|
|||||||
"- ✅ **Database Management**: Persistent storage\n",
|
"- ✅ **Database Management**: Persistent storage\n",
|
||||||
"- ✅ **UI/UX**: Professional interface design\n"
|
"- ✅ **UI/UX**: Professional interface design\n"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"# Port management and launch with error handling\n",
|
|
||||||
"import socket\n",
|
|
||||||
"import subprocess\n",
|
|
||||||
"import os\n",
|
|
||||||
"import time\n",
|
|
||||||
"\n",
|
|
||||||
"def find_free_port(start_port=7860):\n",
|
|
||||||
" \"\"\"Find a free port starting from the given port\"\"\"\n",
|
|
||||||
" for port in range(start_port, start_port + 100):\n",
|
|
||||||
" try:\n",
|
|
||||||
" with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:\n",
|
|
||||||
" s.bind(('127.0.0.1', port))\n",
|
|
||||||
" return port\n",
|
|
||||||
" except OSError:\n",
|
|
||||||
" continue\n",
|
|
||||||
" return None\n",
|
|
||||||
"\n",
|
|
||||||
"def kill_gradio_processes():\n",
|
|
||||||
" \"\"\"Kill any existing Gradio processes\"\"\"\n",
|
|
||||||
" try:\n",
|
|
||||||
" # Kill processes on common Gradio ports\n",
|
|
||||||
" for port in range(7860, 7890):\n",
|
|
||||||
" result = subprocess.run(['netstat', '-ano'], capture_output=True, text=True)\n",
|
|
||||||
" for line in result.stdout.split('\\n'):\n",
|
|
||||||
" if f':{port}' in line and 'LISTENING' in line:\n",
|
|
||||||
" parts = line.split()\n",
|
|
||||||
" if len(parts) > 4:\n",
|
|
||||||
" pid = parts[-1]\n",
|
|
||||||
" try:\n",
|
|
||||||
" subprocess.run(['taskkill', '/F', '/PID', pid], capture_output=True)\n",
|
|
||||||
" except:\n",
|
|
||||||
" pass\n",
|
|
||||||
" except:\n",
|
|
||||||
" pass\n",
|
|
||||||
"\n",
|
|
||||||
"# Kill existing processes and find free port\n",
|
|
||||||
"print(\"🔄 Cleaning up existing processes...\")\n",
|
|
||||||
"kill_gradio_processes()\n",
|
|
||||||
"time.sleep(2) # Wait for processes to be killed\n",
|
|
||||||
"\n",
|
|
||||||
"free_port = find_free_port(7860)\n",
|
|
||||||
"if free_port:\n",
|
|
||||||
" print(f\"✅ Found free port: {free_port}\")\n",
|
|
||||||
" \n",
|
|
||||||
" # Launch the interface with the free port\n",
|
|
||||||
" \n",
|
|
||||||
" interface.launch(\n",
|
|
||||||
" share=False,\n",
|
|
||||||
" server_name=\"127.0.0.1\",\n",
|
|
||||||
" server_port=free_port,\n",
|
|
||||||
" show_error=True\n",
|
|
||||||
" )\n",
|
|
||||||
"else:\n",
|
|
||||||
" print(\"❌ No free ports available. Please restart your kernel and try again.\")\n"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
@@ -347,7 +347,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 6,
|
"execution_count": 7,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -414,7 +414,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 9,
|
"execution_count": 8,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -448,7 +448,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 7,
|
"execution_count": 9,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -562,14 +562,14 @@
|
|||||||
" - 'Set the costs for Classic 105 to 15000 spot ads and 60000 sponsorship'\n",
|
" - 'Set the costs for Classic 105 to 15000 spot ads and 60000 sponsorship'\n",
|
||||||
" - 'What career opportunities are available?'\n",
|
" - 'What career opportunities are available?'\n",
|
||||||
" - 'Add a new job: Marketing Coordinator in Marketing department'\n",
|
" - 'Add a new job: Marketing Coordinator in Marketing department'\n",
|
||||||
"* Running on local URL: http://127.0.0.1:7887\n",
|
"* Running on local URL: http://127.0.0.1:7860\n",
|
||||||
"* To create a public link, set `share=True` in `launch()`.\n"
|
"* To create a public link, set `share=True` in `launch()`.\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/html": [
|
"text/html": [
|
||||||
"<div><iframe src=\"http://127.0.0.1:7887/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
|
"<div><iframe src=\"http://127.0.0.1:7860/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
|
||||||
],
|
],
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"<IPython.core.display.HTML object>"
|
"<IPython.core.display.HTML object>"
|
||||||
@@ -590,7 +590,7 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"DATABASE TOOL CALLED: Getting career opportunities for all departments\n"
|
"DATABASE TOOL CALLED: Adding career opportunity - Marketing Coordinator\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
Binary file not shown.
@@ -1,84 +0,0 @@
|
|||||||
"""
|
|
||||||
Simple launch script for Radio Africa Group Chatbot
|
|
||||||
Handles port conflicts and launches the chatbot
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
import time
|
|
||||||
import socket
|
|
||||||
|
|
||||||
def kill_gradio_processes():
|
|
||||||
"""Kill all Gradio processes"""
|
|
||||||
print("🔄 Killing existing Gradio processes...")
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Get all processes using ports 7860-7890
|
|
||||||
result = subprocess.run(['netstat', '-ano'], capture_output=True, text=True)
|
|
||||||
|
|
||||||
pids_to_kill = set()
|
|
||||||
for line in result.stdout.split('\n'):
|
|
||||||
for port in range(7860, 7890):
|
|
||||||
if f':{port}' in line and 'LISTENING' in line:
|
|
||||||
parts = line.split()
|
|
||||||
if len(parts) > 4:
|
|
||||||
pid = parts[-1]
|
|
||||||
pids_to_kill.add(pid)
|
|
||||||
|
|
||||||
# Kill all identified processes
|
|
||||||
for pid in pids_to_kill:
|
|
||||||
try:
|
|
||||||
subprocess.run(['taskkill', '/F', '/PID', pid], capture_output=True)
|
|
||||||
print(f"✅ Killed process {pid}")
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"⚠️ Error: {e}")
|
|
||||||
|
|
||||||
def find_free_port():
|
|
||||||
"""Find a free port"""
|
|
||||||
for port in range(7860, 8000):
|
|
||||||
try:
|
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
||||||
s.bind(('127.0.0.1', port))
|
|
||||||
return port
|
|
||||||
except OSError:
|
|
||||||
continue
|
|
||||||
return None
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Main function"""
|
|
||||||
print("🚀 Radio Africa Group Advanced Chatbot")
|
|
||||||
print("=" * 50)
|
|
||||||
|
|
||||||
# Kill existing processes
|
|
||||||
kill_gradio_processes()
|
|
||||||
time.sleep(2)
|
|
||||||
|
|
||||||
# Find free port
|
|
||||||
free_port = find_free_port()
|
|
||||||
if not free_port:
|
|
||||||
print("❌ No free ports available!")
|
|
||||||
return
|
|
||||||
|
|
||||||
print(f"✅ Using port: {free_port}")
|
|
||||||
|
|
||||||
# Set environment variable
|
|
||||||
os.environ['GRADIO_SERVER_PORT'] = str(free_port)
|
|
||||||
|
|
||||||
print(f"🌐 Interface will be available at: http://127.0.0.1:{free_port}")
|
|
||||||
print("\n📋 Available features:")
|
|
||||||
print(" - Model switching (GPT/Claude)")
|
|
||||||
print(" - Web scraping from radioafricagroup.co.ke")
|
|
||||||
print(" - Audio input/output support")
|
|
||||||
print(" - Advanced tool integration")
|
|
||||||
print(" - Streaming responses")
|
|
||||||
print(" - Comprehensive database management")
|
|
||||||
|
|
||||||
print("\n🎯 You can now run the notebook or Python script!")
|
|
||||||
print(" The ports are now free and ready to use.")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
Reference in New Issue
Block a user