quantum-ai-v2/weather_reporter/processor.py
Claude 375b2b9d65 Implement wallet deduction after success & fix display issues
🚀 Major improvements to agent system:

## Wallet Management 
- Move wallet deduction to AFTER successful processing (not before)
- Add real-time wallet balance updates in frontend
- Prevent users from losing money on failed requests
- Update both data_analyzer and weather_reporter processors

## Data Analyzer Agent 📊
- Fix N8N integration to handle array response format
- Add binary PDF file upload (multipart/form-data)
- Implement real-time AJAX results display below form
- Add wallet balance updates after successful processing
- Support continuous workflow with "Analyze Another File"

## Weather Reporter Agent 🌤️
- Update price from 2.5 AED to 2.0 AED
- Fix results display (was using page reload, now AJAX)
- Add real-time wallet balance updates
- Implement dynamic results rendering below form
- Add "Get Another Report" functionality

## Template System 🎨
- Update agent generator templates with correct wallet flow
- Add data-wallet-balance attributes for easy targeting
- Fix JavaScript querySelector errors
- Implement proper error handling and logging

## Documentation 📚
- Update CLAUDE.md with wallet best practices
- Add examples of current production agents
- Document required JavaScript functions
- Update pricing information and modern agent features
- Add gitignore entries for nextjs/ and netcop-ai-hub/

## Frontend JavaScript 💻
- Add updateWalletBalance() function for real-time updates
- Implement displayResults() for dynamic content rendering
- Add proper error handling with user-friendly messages
- Support continuous workflow without page refresh

🎉 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-10 16:34:03 +05:30

139 lines
5.4 KiB
Python

from agent_base.processors import StandardAPIProcessor
from django.utils import timezone
from .models import WeatherReporterRequest, WeatherReporterResponse
import json
class WeatherReporterProcessor(StandardAPIProcessor):
"""API processor for Weather Reporter agent"""
agent_slug = 'weather-reporter'
api_base_url = 'https://api.openweathermap.org/data/2.5/weather'
api_key_env = 'OPENWEATHER_API_KEY'
auth_method = 'query'
def get_endpoint(self, **kwargs):
"""Get the OpenWeather API endpoint with location"""
location = kwargs.get('location', 'London')
return f"{self.api_base_url}?q={location}&units=metric"
def prepare_request_data(self, **kwargs):
"""Prepare API request data"""
return {
'location': kwargs.get('location', 'London'),
'report_type': kwargs.get('report_type', 'current'),
}
def should_use_get(self, **kwargs):
"""Use GET for weather API"""
return True
def format_weather_report(self, weather_data, report_type):
"""Format weather data into readable report"""
if not weather_data or 'main' not in weather_data:
return "Weather data unavailable"
location = weather_data.get('name', 'Unknown')
country = weather_data.get('sys', {}).get('country', '')
temp = weather_data.get('main', {}).get('temp', 0)
feels_like = weather_data.get('main', {}).get('feels_like', 0)
humidity = weather_data.get('main', {}).get('humidity', 0)
pressure = weather_data.get('main', {}).get('pressure', 0)
description = weather_data.get('weather', [{}])[0].get('description', 'Unknown')
wind_speed = weather_data.get('wind', {}).get('speed', 0)
wind_deg = weather_data.get('wind', {}).get('deg', 0)
if report_type == 'detailed':
report = f"""🌤️ Weather Report for {location}, {country}
🌡️ Temperature: {temp}°C (feels like {feels_like}°C)
☁️ Conditions: {description.title()}
💨 Wind: {wind_speed} m/s at {wind_deg}°
💧 Humidity: {humidity}%
🔽 Pressure: {pressure} hPa
Weather data provided by OpenWeatherMap"""
else:
report = f"🌤️ {location}: {temp}°C, {description.title()}, {humidity}% humidity"
return report
def process_response(self, response_data, request_obj):
"""Process the weather API response"""
try:
# Update request status
request_obj.status = 'processing'
request_obj.save()
# Extract weather data
weather_data = response_data.copy()
if 'processing_time' in weather_data:
del weather_data['processing_time']
if 'success' in weather_data:
del weather_data['success']
# Extract specific fields
temperature = None
description = ""
humidity = None
wind_speed = None
if 'main' in weather_data:
temperature = weather_data['main'].get('temp')
humidity = weather_data['main'].get('humidity')
if 'weather' in weather_data and len(weather_data['weather']) > 0:
description = weather_data['weather'][0].get('description', '')
if 'wind' in weather_data:
wind_speed = weather_data['wind'].get('speed')
# Format report
formatted_report = self.format_weather_report(weather_data, request_obj.report_type)
# Determine success
success = response_data.get('success', True) and bool(weather_data.get('main'))
# Create response object
response_obj = WeatherReporterResponse.objects.create(
request=request_obj,
success=success,
processing_time=response_data.get('processing_time', 0),
weather_data=weather_data,
temperature=temperature,
description=description,
humidity=humidity,
wind_speed=wind_speed,
formatted_report=formatted_report,
)
# Only deduct wallet balance after successful processing
if success:
request_obj.user.deduct_balance(
request_obj.cost,
f"Weather Reporter - {request_obj.location}",
'weather-reporter'
)
print(f"{self.agent_slug}: Wallet deducted {request_obj.cost} AED for successful processing")
# Update request as completed
request_obj.status = 'completed' if success else 'failed'
request_obj.processed_at = timezone.now()
request_obj.save()
return response_obj
except Exception as e:
# Handle error
request_obj.status = 'failed'
request_obj.save()
# Create error response
error_response = WeatherReporterResponse.objects.create(
request=request_obj,
success=False,
error_message=str(e),
processing_time=response_data.get('processing_time', 0)
)
raise Exception(f"Failed to process Weather Reporter response: {e}")