diff --git a/agents/configs/agents/ai-voice-agent.json b/agents/configs/agents/ai-voice-agent.json new file mode 100644 index 0000000..03bd77a --- /dev/null +++ b/agents/configs/agents/ai-voice-agent.json @@ -0,0 +1,16 @@ +{ + "slug": "ai-voice-agent", + "name": "AI Voice Agent", + "short_description": "Transform your content with AI-powered voice generation and audio solutions", + "description": "Create professional voiceovers, podcasts, and audio content using advanced AI voice technology. Perfect for marketing campaigns, educational content, and multimedia projects.", + "category": "marketing", + "price": 0.0, + "agent_type": "form", + "system_type": "direct_access", + "form_schema": { + "fields": [] + }, + "webhook_url": "https://agent.jotform.com/0198a8860b46796895f2a40367a6cea4df0c/voice", + "access_url_name": "agents:direct_access_handler", + "display_url_name": "agents:direct_access_display" +} \ No newline at end of file diff --git a/agents/configs/agents/five-whys-analysis.json b/agents/configs/agents/five-whys-analysis.json index 97c6535..7c50d6f 100644 --- a/agents/configs/agents/five-whys-analysis.json +++ b/agents/configs/agents/five-whys-analysis.json @@ -7,7 +7,18 @@ "price": 15.0, "agent_type": "chat", "system_type": "webhook", - "form_schema": null, + "form_schema": { + "fields": [ + { + "name": "problem_description", + "type": "textarea", + "label": "Describe the problem you want to analyze", + "placeholder": "Describe the issue, failure, or problem you're experiencing", + "required": true, + "rows": 4 + } + ] + }, "webhook_url": "http://localhost:5678/webhook/5-whys-web", "access_url_name": "", "display_url_name": "" diff --git a/agents/direct_access_views.py b/agents/direct_access_views.py index b4fff48..ad9c0a7 100644 --- a/agents/direct_access_views.py +++ b/agents/direct_access_views.py @@ -14,392 +14,6 @@ from .services import AgentFileService from .utils import AgentCompat -def career_navigator_access(request): - """Handle Try Now button click - charge wallet and redirect to form""" - if not request.user.is_authenticated: - # Clear all existing messages before adding login message - storage = messages.get_messages(request) - for _ in storage: - pass # Consume all messages - # Add login message to session for after login redirect - request.session['post_login_message'] = 'Please complete your login to access the Career Navigator.' - return redirect('authentication:login') - - # Get the career navigator agent - agent_data = AgentFileService.get_agent_by_slug('cybersec-career-navigator') - if not agent_data or not agent_data.get('is_active', True): - messages.error(request, 'Career Navigator is currently unavailable.') - return redirect('agents:marketplace') - - agent_price = float(agent_data['price']) - - # Check if user has sufficient balance - if not request.user.has_sufficient_balance(agent_price): - messages.error(request, f'Insufficient balance! You need {agent_price} AED to access the Career Navigator.') - return redirect('wallet:wallet') - - # Deduct fee from user wallet - success = request.user.deduct_balance( - agent_price, - f'{agent_data["name"]} - Direct Access', - agent_data['slug'] - ) - - if not success: - messages.error(request, 'Failed to process payment. Please try again.') - return redirect('agents:marketplace') - - # Create execution record for tracking - execution = AgentExecution.objects.create( - agent_slug=agent_data['slug'], - agent_name=agent_data['name'], - user=request.user, - input_data={'action': 'direct_access', 'source': 'try_now_button'}, - fee_charged=agent_price, - status='completed', - output_data={ - 'type': 'direct_access', - 'message': f'Direct access granted to {agent_data["name"]}', - 'access_method': 'try_now_button' - }, - completed_at=timezone.now() - ) - - # Redirect directly to form - no message needed - return redirect('agents:career_navigator') - - -def career_navigator_view(request): - """Display the career navigator form page""" - if not request.user.is_authenticated: - # Clear all existing messages before adding login message - storage = messages.get_messages(request) - for _ in storage: - pass # Consume all messages - # Add login message to session for after login redirect - request.session['post_login_message'] = 'Please complete your login to access the Career Navigator.' - return redirect('authentication:login') - - # Get the career navigator agent - agent_data = AgentFileService.get_agent_by_slug('cybersec-career-navigator') - if not agent_data or not agent_data.get('is_active', True): - messages.error(request, 'Career Navigator is currently unavailable.') - return redirect('agents:marketplace') - - # Convert to compatible object - agent = AgentCompat(agent_data) - - # Check if user has a recent execution (within last 2 hours) or just redirect to payment - recent_execution = AgentExecution.objects.filter( - agent_slug=agent.slug, # Changed to slug-based lookup - user=request.user, - status='completed', - created_at__gte=timezone.now() - timedelta(hours=2) - ).first() - - if not recent_execution: - messages.info(request, 'Please click "Try Now" to access your Career Navigator consultation.') - return redirect('agents:marketplace') - - context = { - 'agent': agent, - 'form_url': agent.webhook_url, - 'user_balance': request.user.wallet_balance, - 'execution': recent_execution - } - - return render(request, 'career_navigator.html', context) - - -def ai_brand_strategist_view(request): - """Display the AI Brand Strategist form page""" - if not request.user.is_authenticated: - # Clear all existing messages before adding login message - storage = messages.get_messages(request) - for _ in storage: - pass # Consume all messages - # Add login message to session for after login redirect - request.session['post_login_message'] = 'Please complete your login to access the AI Brand Strategist.' - return redirect('authentication:login') - - # Get the AI Brand Strategist agent - agent_data = AgentFileService.get_agent_by_slug('ai-brand-strategist') - if not agent_data or not agent_data.get('is_active', True): - messages.error(request, 'AI Brand Strategist is currently unavailable.') - return redirect('agents:marketplace') - - # Convert to compatible object - agent = AgentCompat(agent_data) - - # Check if user has a recent execution (within last 2 hours) or just redirect to payment - recent_execution = AgentExecution.objects.filter( - agent_slug=agent.slug, # Changed to slug-based lookup - user=request.user, - status='completed', - created_at__gte=timezone.now() - timedelta(hours=2) - ).first() - - if not recent_execution: - messages.info(request, 'Please click "Try Now" to access your AI Brand Strategist consultation.') - return redirect('agents:marketplace') - - context = { - 'agent': agent, - 'form_url': agent.webhook_url, - 'user_balance': request.user.wallet_balance, - 'execution': recent_execution - } - - return render(request, 'ai_brand_strategist.html', context) - - -def ai_brand_strategist_access(request): - """Handle Try Now button click - charge wallet and redirect to form""" - if not request.user.is_authenticated: - # Clear all existing messages before adding login message - storage = messages.get_messages(request) - for _ in storage: - pass # Consume all messages - # Add login message to session for after login redirect - request.session['post_login_message'] = 'Please complete your login to access the AI Brand Strategist.' - return redirect('authentication:login') - - # Get the AI Brand Strategist agent - agent_data = AgentFileService.get_agent_by_slug('ai-brand-strategist') - if not agent_data or not agent_data.get('is_active', True): - messages.error(request, 'AI Brand Strategist is currently unavailable.') - return redirect('agents:marketplace') - - agent_price = float(agent_data['price']) - - # Check if user has sufficient balance - if not request.user.has_sufficient_balance(agent_price): - messages.error(request, f'Insufficient balance! You need {agent_price} AED to access the AI Brand Strategist.') - return redirect('wallet:wallet') - - # Deduct fee from user wallet - success = request.user.deduct_balance( - agent_price, - f'{agent_data["name"]} - Direct Access', - agent_data['slug'] - ) - - if not success: - messages.error(request, 'Failed to process payment. Please try again.') - return redirect('agents:marketplace') - - # Create execution record for tracking - execution = AgentExecution.objects.create( - agent_slug=agent_data['slug'], - agent_name=agent_data['name'], - user=request.user, - input_data={'action': 'direct_access', 'source': 'try_now_button'}, - fee_charged=agent_price, - status='completed', - output_data={ - 'type': 'direct_access', - 'message': f'Direct access granted to {agent_data["name"]}', - 'access_method': 'try_now_button' - }, - completed_at=timezone.now() - ) - - # Redirect directly to form - no message needed - return redirect('agents:ai_brand_strategist') - - -def lean_six_sigma_expert_view(request): - """Display the Lean Six Sigma Expert form page""" - if not request.user.is_authenticated: - # Clear all existing messages before adding login message - storage = messages.get_messages(request) - for _ in storage: - pass # Consume all messages - # Add login message to session for after login redirect - request.session['post_login_message'] = 'Please complete your login to access the Lean Six Sigma Expert.' - return redirect('authentication:login') - - # Get the Lean Six Sigma Expert agent - agent_data = AgentFileService.get_agent_by_slug('lean-six-sigma-expert') - if not agent_data or not agent_data.get('is_active', True): - messages.error(request, 'Lean Six Sigma Expert is currently unavailable.') - return redirect('agents:marketplace') - - # Convert to compatible object - agent = AgentCompat(agent_data) - - # Check if user has a recent execution (within last 2 hours) or just redirect to payment - recent_execution = AgentExecution.objects.filter( - agent_slug=agent.slug, # Changed to slug-based lookup - user=request.user, - status='completed', - created_at__gte=timezone.now() - timedelta(hours=2) - ).first() - - if not recent_execution: - messages.info(request, 'Please click "Try Now" to access your Lean Six Sigma Expert consultation.') - return redirect('agents:marketplace') - - context = { - 'agent': agent, - 'form_url': agent.webhook_url, - 'user_balance': request.user.wallet_balance, - 'execution': recent_execution - } - - return render(request, 'lean_six_sigma_expert.html', context) - - -def lean_six_sigma_expert_access(request): - """Handle Try Now button click - charge wallet and redirect to form""" - if not request.user.is_authenticated: - # Clear all existing messages before adding login message - storage = messages.get_messages(request) - for _ in storage: - pass # Consume all messages - # Add login message to session for after login redirect - request.session['post_login_message'] = 'Please complete your login to access the Lean Six Sigma Expert.' - return redirect('authentication:login') - - # Get the Lean Six Sigma Expert agent - agent_data = AgentFileService.get_agent_by_slug('lean-six-sigma-expert') - if not agent_data or not agent_data.get('is_active', True): - messages.error(request, 'Lean Six Sigma Expert is currently unavailable.') - return redirect('agents:marketplace') - - agent_price = float(agent_data['price']) - - # Check if user has sufficient balance - if not request.user.has_sufficient_balance(agent_price): - messages.error(request, f'Insufficient balance! You need {agent_price} AED to access the Lean Six Sigma Expert.') - return redirect('wallet:wallet') - - # Deduct fee from user wallet - success = request.user.deduct_balance( - agent_price, - f'{agent_data["name"]} - Direct Access', - agent_data['slug'] - ) - - if not success: - messages.error(request, 'Failed to process payment. Please try again.') - return redirect('agents:marketplace') - - # Create execution record for tracking - execution = AgentExecution.objects.create( - agent_slug=agent_data['slug'], - agent_name=agent_data['name'], - user=request.user, - input_data={'action': 'direct_access', 'source': 'try_now_button'}, - fee_charged=agent_price, - status='completed', - output_data={ - 'type': 'direct_access', - 'message': f'Direct access granted to {agent_data["name"]}', - 'access_method': 'try_now_button' - }, - completed_at=timezone.now() - ) - - # Redirect directly to form - no message needed - return redirect('agents:lean_six_sigma_expert') - - -def swot_analysis_expert_view(request): - """Display the SWOT Analysis Expert form page""" - if not request.user.is_authenticated: - # Clear all existing messages before adding login message - storage = messages.get_messages(request) - for _ in storage: - pass # Consume all messages - # Add login message to session for after login redirect - request.session['post_login_message'] = 'Please complete your login to access the SWOT Analysis Expert.' - return redirect('authentication:login') - - # Get the SWOT Analysis Expert agent - agent_data = AgentFileService.get_agent_by_slug('swot-analysis-expert') - if not agent_data or not agent_data.get('is_active', True): - messages.error(request, 'SWOT Analysis Expert is currently unavailable.') - return redirect('agents:marketplace') - - # Convert to compatible object - agent = AgentCompat(agent_data) - - # Check if user has a recent execution (within last 2 hours) or just redirect to payment - recent_execution = AgentExecution.objects.filter( - agent_slug=agent.slug, # Changed to slug-based lookup - user=request.user, - status='completed', - created_at__gte=timezone.now() - timedelta(hours=2) - ).first() - - if not recent_execution: - messages.info(request, 'Please click "Try Now" to access your SWOT Analysis Expert consultation.') - return redirect('agents:marketplace') - - context = { - 'agent': agent, - 'form_url': agent.webhook_url, - 'user_balance': request.user.wallet_balance, - 'execution': recent_execution - } - - return render(request, 'swot_analysis_expert.html', context) - - -def swot_analysis_expert_access(request): - """Handle Try Now button click - charge wallet and redirect to form""" - if not request.user.is_authenticated: - # Clear all existing messages before adding login message - storage = messages.get_messages(request) - for _ in storage: - pass # Consume all messages - # Add login message to session for after login redirect - request.session['post_login_message'] = 'Please complete your login to access the SWOT Analysis Expert.' - return redirect('authentication:login') - - # Get the SWOT Analysis Expert agent - agent_data = AgentFileService.get_agent_by_slug('swot-analysis-expert') - if not agent_data or not agent_data.get('is_active', True): - messages.error(request, 'SWOT Analysis Expert is currently unavailable.') - return redirect('agents:marketplace') - - agent_price = float(agent_data['price']) - - # Check if user has sufficient balance - if not request.user.has_sufficient_balance(agent_price): - messages.error(request, f'Insufficient balance! You need {agent_price} AED to access the SWOT Analysis Expert.') - return redirect('wallet:wallet') - - # Deduct fee from user wallet - success = request.user.deduct_balance( - agent_price, - f'{agent_data["name"]} - Direct Access', - agent_data['slug'] - ) - - if not success: - messages.error(request, 'Failed to process payment. Please try again.') - return redirect('agents:marketplace') - - # Create execution record for tracking - execution = AgentExecution.objects.create( - agent_slug=agent_data['slug'], - agent_name=agent_data['name'], - user=request.user, - input_data={'action': 'direct_access', 'source': 'try_now_button'}, - fee_charged=agent_price, - status='completed', - output_data={ - 'type': 'direct_access', - 'message': f'Direct access granted to {agent_data["name"]}', - 'access_method': 'try_now_button' - }, - completed_at=timezone.now() - ) - - # Redirect directly to form - no message needed - return redirect('agents:swot_analysis_expert') @login_required @@ -465,6 +79,11 @@ def direct_access_display(request, slug): messages.error(request, 'This agent does not support direct access.') return redirect('agents:marketplace') - # For now, redirect directly to external form - # Future: Can render iframe template or custom display logic - return redirect(agent.webhook_url) \ No newline at end of file + # Render generic template with iframe to external form + context = { + 'agent': agent, + 'form_url': agent.webhook_url, + 'user_balance': request.user.wallet_balance if hasattr(request.user, 'wallet_balance') else 0 + } + + return render(request, 'agents/direct_access_agent.html', context) diff --git a/templates/career_navigator.html b/agents/templates/agents/direct_access_agent.html similarity index 87% rename from templates/career_navigator.html rename to agents/templates/agents/direct_access_agent.html index c38370b..8137432 100644 --- a/templates/career_navigator.html +++ b/agents/templates/agents/direct_access_agent.html @@ -1,7 +1,7 @@ {% extends 'base.html' %} {% load static %} -{% block title %}Career Navigator - Quantum Tasks AI{% endblock %} +{% block title %}{{ agent.name }} - Quantum Tasks AI{% endblock %} {% block extra_css %} -{% endblock %} - -{% block content %} -
- -
-{% endblock %} \ No newline at end of file diff --git a/templates/components/quick_agents_panel.html b/templates/components/quick_agents_panel.html index 9ec94c0..34569f3 100644 --- a/templates/components/quick_agents_panel.html +++ b/templates/components/quick_agents_panel.html @@ -8,9 +8,11 @@
{% for agent in all_agents %} - {% if agent.slug == 'cybersec-career-navigator' %} - + {% if agent.access_url_name and agent.display_url_name %} + + {% else %} + {% endif %}
{{ agent.category.icon }}
diff --git a/templates/lean_six_sigma_expert.html b/templates/lean_six_sigma_expert.html deleted file mode 100644 index f7633cf..0000000 --- a/templates/lean_six_sigma_expert.html +++ /dev/null @@ -1,43 +0,0 @@ -{% extends 'base.html' %} -{% load static %} - -{% block title %}Lean Six Sigma Expert - Quantum Tasks AI{% endblock %} - -{% block extra_css %} - -{% endblock %} - -{% block content %} -
- -
-{% endblock %} \ No newline at end of file diff --git a/templates/swot_analysis_expert.html b/templates/swot_analysis_expert.html deleted file mode 100644 index 0ea3488..0000000 --- a/templates/swot_analysis_expert.html +++ /dev/null @@ -1,38 +0,0 @@ -{% extends 'base.html' %} -{% load static %} - -{% block title %}SWOT Analysis Expert - Quantum Tasks AI{% endblock %} - -{% block extra_css %} - -{% endblock %} - -{% block content %} -
- -
-{% endblock %} \ No newline at end of file