Problem: The agent was throwing Object of type date is not JSON serializable and Object of type Decimal is not JSON serializable errors.
Solution:
- Added custom
CustomJSONEncoderclass that handles MySQL data types:Decimalβfloatdate/datetimeβISO format stringbytesβUTF-8 decoded string
- Created
safe_json_serialize()function that recursively converts all data - Applied serialization to ALL tool functions and API responses
Problem: When viewing table data, the agent showed too many records by default.
Solution:
- Changed
preview_table_datadefault from 10 to 5 rows - Updated function description to reflect this
- Added automatic LIMIT 100 to SELECT queries for safety
- Shows limit info in results: "Retrieved 5 rows (showing 5) from Employees"
Problem: Users couldn't see the AI's reasoning process like in real Gemini.
Solution:
- Switched to
gemini-2.0-flash-thinking-exp-01-21model - Extracts and displays thinking steps in the UI
- Shows both:
- Thought steps: The AI's internal reasoning
- Action steps: When it calls database tools
- Beautiful, animated display similar to real Gemini interface
Problem: Generic errors without helpful context.
Solution:
- All tool functions now use try-catch with safe serialization
- Clear error messages for common issues
- Prevents crashes from unexpected data types
- Validates inputs before executing queries
Added comprehensive instructions for the AI:
- Always explain what it's doing before calling tools
- Show reasoning process when working on queries
- Default to 5 records for data previews
- Handle dates/decimals properly
- Provide clear, actionable results
- Offer follow-up help
- Import additions:
from decimal import Decimal
from datetime import date, datetime- Custom JSON Encoder:
class CustomJSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Decimal):
return float(obj)
elif isinstance(obj, (date, datetime)):
return obj.isoformat()
elif isinstance(obj, bytes):
return obj.decode('utf-8', errors='replace')
return super().default(obj)- Safe Serialization Function:
def safe_json_serialize(data):
"""Recursively converts all MySQL data types to JSON-safe format"""- All Tool Functions Updated:
tool_list_tables()- Returns serialized datatool_describe_table()- Handles NULL defaultstool_preview_table_data()- Default limit=5, serializes rowstool_execute_select_query()- Auto-adds LIMIT, serializes results- And all others...
- Enhanced AI Response:
return jsonify({
"success": True,
"response": response_text,
"sql": sql_query,
"tool_calls": tool_calls,
"thinking": thinking_steps, # NEW!
"iterations": iterations,
"history": conversation_sessions[session_id]
})- Thinking Display Function:
function addThinkingMessage(thinkingSteps) {
// Creates beautiful thinking process display
// Shows thought steps and action steps
// Animated and styled like real Gemini
}- Enhanced Loading:
function addLoadingMessage() {
// Shows spinner with "AI thinking and analyzing database..."
}- Tool Calls Display Enhanced:
- Shows exact number of rows retrieved
- Better formatting for different result types
- Clear success/error indicators
- Thinking Process Styles:
- Gradient background with animation
- Numbered thinking steps
- Special styling for action steps (tool calls)
- Smooth animations (fadeIn, slideIn)
- Enhanced Loading Spinner:
- Animated circular spinner
- Pulse animation for the container
- Modern, smooth appearance
-
User asks β "Show me the records in the Employees table"
-
AI Thinking Display:
π AI Thinking Process ββ 1. User wants to see employee records ββ 2. I should use preview_table_data function ββ 3. Default to 5 rows for better UX -
Tool Call Display:
π§ AI Agent Actions (1) ββ 1. Preview Table Data β β Parameters: {"table_name": "Employees", "limit": 5} ββ Result: Retrieved 5 rows (showing 5) from Employees -
AI Response:
Here are 5 sample records from your Employees table: - John Doe (john.doe@example.com) - Software Engineer - Jane Smith (jane.smith@example.com) - Product Manager ... The table has 8 columns including employee_id, first_name, last_name, email, hire_date, and salary. All dates and decimal values are properly formatted. Would you like to see more records or filter by specific criteria?
β Hire dates show as: "2024-01-15"
β Timestamps show as: "2024-01-15T09:30:00"
β No more serialization errors!
β Salaries show as: 75000.00
β Prices show as: 29.99
β All numeric precision preserved!
β Default: 5 records (not overwhelming)
β Max: 50 records (safety limit)
β Always shows count: "Retrieved 5 rows"
β See what the AI is thinking
β Understand why it chose certain tools
β Follow the reasoning process
β Learn SQL concepts through explanation
User: "Show me employee records"
AI: [tries to get data]
Error: "Object of type date is not JSON serializable"
User: π
User: "Show me employee records"
AI: [shows thinking]
"I'll preview the Employees table with a sample of records"
AI: [calls tool]
Preview Table Data β
AI: [responds]
"Here are 5 sample employees with their information:
- John Doe (hired: 2024-01-15, salary: $75,000)
- ..."
User: π
- Soft gradient background (purple/pink)
- Numbered steps for clarity
- Different styling for thoughts vs actions
- Smooth animations
- Clear success/error indicators
- Formatted results based on type
- Shows row counts and limits
- Expandable details
- Modern spinner animation
- Clear status message
- Pulse effect for attention
-
Query Safety:
- Auto-adds LIMIT to SELECT queries
- Blocks dangerous operations
- Validates inputs
-
Data Safety:
- Limits preview to 5 rows default
- Max 50 rows for preview
- Max 100 rows for custom queries
-
Error Safety:
- All operations wrapped in try-catch
- Graceful error messages
- No crashes from bad data
The thinking process display helps users:
- Understand how SQL queries are constructed
- Learn about database relationships
- See the agent's problem-solving approach
- Discover database best practices
- Install dependencies:
pip install -r requirements.txt --break-system-packages- Set up environment variables:
export GEMINI_API_KEY="your_key_here"
export MYSQL_HOST="localhost"
export MYSQL_USER="root"
export MYSQL_PASSWORD="your_password"
export MYSQL_DB="your_database"- Run the application:
python app.py- Open browser:
http://localhost:5000/terminal
Try these queries to see the improvements:
-
"Show me all tables"
- See thinking process
- Watch tool calls
- Get clear results
-
"Show me records from Employees"
- Default 5 records
- Dates properly formatted
- Salaries as numbers
-
"Help me join Employees and Orders"
- See relationship discovery
- Watch schema inspection
- Get smart JOIN query
- β Date serialization errors
- β Decimal serialization errors
- β Too many records returned
- β No thinking visibility
- β Generic error messages
- β NULL value handling
- β Missing limit on queries
Potential future improvements:
- Add query history
- Save favorite queries
- Export results to CSV/Excel
- Visual query builder
- Database schema diagram
- Performance insights
- Query optimization suggestions
- Uses Gemini 2.0 Flash Thinking Experimental model
- Shows real thinking process like ChatGPT/Claude
- All data properly serialized
- Safe defaults for data preview
- Enhanced user experience
- Educational and transparent
Built with:
- Flask (Python backend)
- Google Generative AI (Gemini)
- MySQL (Database)
- Vanilla JavaScript (Frontend)
- Custom CSS (Styling)
Version: 2.0 (Improved)
Date: January 2025
Author: Enhanced with thinking display and proper serialization