diff --git a/.gitignore b/.gitignore index 2f2142b..cc7d04f 100644 --- a/.gitignore +++ b/.gitignore @@ -230,4 +230,5 @@ secrets.json # NextJS frontend directory nextjs/ netcop-ai-hub/ -temp/ \ No newline at end of file +temp/ +five-whys-agent-new.html diff --git a/agent_base/management/commands/populate_agents.py b/agent_base/management/commands/populate_agents.py index 8bda506..342c510 100644 --- a/agent_base/management/commands/populate_agents.py +++ b/agent_base/management/commands/populate_agents.py @@ -78,6 +78,15 @@ class Command(BaseCommand): 'icon': '📱', 'agent_type': 'webhook', }, + { + 'name': '5 Whys Analysis Agent', + 'slug': 'five-whys-analyzer', + 'description': 'Systematic root cause analysis using the proven 5 Whys methodology to identify and solve business problems effectively.', + 'category': 'analytics', + 'price': 8.0, + 'icon': '🔍', + 'agent_type': 'webhook', + }, ] created_count = 0 diff --git a/five_whys_analyzer/__init__.py b/five_whys_analyzer/__init__.py new file mode 100644 index 0000000..1f5df5b --- /dev/null +++ b/five_whys_analyzer/__init__.py @@ -0,0 +1 @@ +# 5 Whys Analysis Agent Agent App \ No newline at end of file diff --git a/five_whys_analyzer/admin.py b/five_whys_analyzer/admin.py new file mode 100644 index 0000000..fd2d7a1 --- /dev/null +++ b/five_whys_analyzer/admin.py @@ -0,0 +1,43 @@ +from django.contrib import admin +from .models import FiveWhysAnalyzerRequest, FiveWhysAnalyzerResponse + + +@admin.register(FiveWhysAnalyzerRequest) +class FiveWhysAnalyzerRequestAdmin(admin.ModelAdmin): + list_display = ['id', 'user', 'session_id', 'status', 'report_generated', 'chat_active', 'created_at', 'cost'] + list_filter = ['status', 'report_generated', 'chat_active', 'analysis_depth', 'created_at'] + search_fields = ['user__email', 'user__username', 'session_id', 'problem_statement'] + readonly_fields = ['id', 'created_at', 'processed_at', 'session_id'] + ordering = ['-created_at'] + + fieldsets = ( + ('Basic Info', { + 'fields': ('id', 'user', 'session_id', 'status', 'created_at', 'processed_at') + }), + ('Chat Session', { + 'fields': ('chat_active', 'chat_messages') + }), + ('Report Generation', { + 'fields': ('report_generated', 'problem_statement', 'context_info', 'analysis_depth', 'cost') + }), + ) + + +@admin.register(FiveWhysAnalyzerResponse) +class FiveWhysAnalyzerResponseAdmin(admin.ModelAdmin): + list_display = ['id', 'request', 'success', 'created_at'] + list_filter = ['success', 'created_at'] + readonly_fields = ['id', 'created_at'] + ordering = ['-created_at'] + + fieldsets = ( + ('Basic Info', { + 'fields': ('id', 'request', 'success', 'created_at', 'processing_time', 'error_message') + }), + ('Chat Response', { + 'fields': ('chat_response', 'chat_history') + }), + ('Final Report', { + 'fields': ('final_report', 'report_metadata') + }), + ) \ No newline at end of file diff --git a/five_whys_analyzer/apps.py b/five_whys_analyzer/apps.py new file mode 100644 index 0000000..8127422 --- /dev/null +++ b/five_whys_analyzer/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class FiveWhysAnalyzerConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'five_whys_analyzer' \ No newline at end of file diff --git a/five_whys_analyzer/migrations/0001_initial.py b/five_whys_analyzer/migrations/0001_initial.py new file mode 100644 index 0000000..7224c15 --- /dev/null +++ b/five_whys_analyzer/migrations/0001_initial.py @@ -0,0 +1,74 @@ +# Generated by Django 5.2.4 on 2025-07-12 16:08 + +import django.db.models.deletion +import uuid +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('agent_base', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='FiveWhysAnalyzerRequest', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('status', models.CharField(choices=[('pending', 'Pending'), ('processing', 'Processing'), ('completed', 'Completed'), ('failed', 'Failed')], default='pending', max_length=20)), + ('cost', models.DecimalField(decimal_places=2, max_digits=10)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('processed_at', models.DateTimeField(blank=True, null=True)), + ('session_id', models.CharField(db_index=True, default=uuid.uuid4, max_length=100)), + ('chat_messages', models.JSONField(default=list, help_text='Store chat history as list of messages')), + ('problem_statement', models.TextField(blank=True, help_text='Main problem to analyze')), + ('context_info', models.TextField(blank=True, help_text='Additional context information')), + ('analysis_depth', models.CharField(blank=True, choices=[('standard', 'Standard 5 Whys'), ('detailed', 'Extended Analysis'), ('comprehensive', 'Comprehensive Report')], default='standard', max_length=20)), + ('report_generated', models.BooleanField(default=False, help_text='Has final report been generated and paid for')), + ('chat_active', models.BooleanField(default=True, help_text='Is chat session still active')), + ('input_text', models.TextField(blank=True)), + ('agent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='agent_base.baseagent')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': '5 Whys Analysis Agent Request', + 'verbose_name_plural': '5 Whys Analysis Agent Requests', + 'db_table': 'five_whys_analyzer_requests', + }, + ), + migrations.CreateModel( + name='FiveWhysAnalyzerResponse', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('success', models.BooleanField(default=False)), + ('error_message', models.TextField(blank=True)), + ('processing_time', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('chat_response', models.TextField(blank=True, help_text='Latest chat response')), + ('chat_history', models.JSONField(default=list, help_text='Full chat response history')), + ('final_report', models.TextField(blank=True, help_text='Generated 5 Whys analysis report')), + ('report_metadata', models.JSONField(default=dict, help_text='Report generation metadata')), + ('output_text', models.TextField(blank=True)), + ('raw_response', models.JSONField(blank=True, default=dict)), + ('request', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='response', to='five_whys_analyzer.fivewhysanalyzerrequest')), + ], + options={ + 'verbose_name': '5 Whys Analysis Agent Response', + 'verbose_name_plural': '5 Whys Analysis Agent Responses', + 'db_table': 'five_whys_analyzer_responses', + }, + ), + migrations.AddIndex( + model_name='fivewhysanalyzerrequest', + index=models.Index(fields=['session_id'], name='five_whys_a_session_0dd791_idx'), + ), + migrations.AddIndex( + model_name='fivewhysanalyzerrequest', + index=models.Index(fields=['user', 'chat_active'], name='five_whys_a_user_id_810315_idx'), + ), + ] diff --git a/five_whys_analyzer/migrations/__init__.py b/five_whys_analyzer/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/five_whys_analyzer/models.py b/five_whys_analyzer/models.py new file mode 100644 index 0000000..9d2214e --- /dev/null +++ b/five_whys_analyzer/models.py @@ -0,0 +1,71 @@ +from django.db import models +from decimal import Decimal +from agent_base.models import BaseAgentRequest, BaseAgentResponse +import uuid + + +class FiveWhysAnalyzerRequest(BaseAgentRequest): + """5 Whys Analysis Agent request tracking with chat support""" + + # Chat session management + session_id = models.CharField(max_length=100, default=uuid.uuid4, db_index=True) + + # Chat interaction tracking + chat_messages = models.JSONField(default=list, help_text="Store chat history as list of messages") + + # Final report fields (only filled when report is generated) + problem_statement = models.TextField(blank=True, help_text="Main problem to analyze") + context_info = models.TextField(blank=True, help_text="Additional context information") + analysis_depth = models.CharField( + max_length=20, + blank=True, + choices=[ + ('standard', 'Standard 5 Whys'), + ('detailed', 'Extended Analysis'), + ('comprehensive', 'Comprehensive Report') + ], + default='standard' + ) + + # Chat vs Report tracking + report_generated = models.BooleanField(default=False, help_text="Has final report been generated and paid for") + chat_active = models.BooleanField(default=True, help_text="Is chat session still active") + + # Legacy field for compatibility + input_text = models.TextField(blank=True) + + class Meta: + db_table = 'five_whys_analyzer_requests' + verbose_name = '5 Whys Analysis Agent Request' + verbose_name_plural = '5 Whys Analysis Agent Requests' + indexes = [ + models.Index(fields=['session_id']), + models.Index(fields=['user', 'chat_active']), + ] + + +class FiveWhysAnalyzerResponse(BaseAgentResponse): + """5 Whys Analysis Agent response storage""" + + request = models.OneToOneField( + FiveWhysAnalyzerRequest, + on_delete=models.CASCADE, + related_name='response' + ) + + # Chat responses (free interactions) + chat_response = models.TextField(blank=True, help_text="Latest chat response") + chat_history = models.JSONField(default=list, help_text="Full chat response history") + + # Final report (paid interaction) + final_report = models.TextField(blank=True, help_text="Generated 5 Whys analysis report") + report_metadata = models.JSONField(default=dict, help_text="Report generation metadata") + + # Legacy fields for compatibility + output_text = models.TextField(blank=True) + raw_response = models.JSONField(default=dict, blank=True) + + class Meta: + db_table = 'five_whys_analyzer_responses' + verbose_name = '5 Whys Analysis Agent Response' + verbose_name_plural = '5 Whys Analysis Agent Responses' \ No newline at end of file diff --git a/five_whys_analyzer/processor.py b/five_whys_analyzer/processor.py new file mode 100644 index 0000000..4e7c0df --- /dev/null +++ b/five_whys_analyzer/processor.py @@ -0,0 +1,247 @@ +from agent_base.processors import StandardWebhookProcessor +from django.utils import timezone +from django.conf import settings +from .models import FiveWhysAnalyzerRequest, FiveWhysAnalyzerResponse +import json +import uuid + + +class FiveWhysAnalyzerProcessor(StandardWebhookProcessor): + """Dual-mode webhook processor for 5 Whys Analysis Agent - supports chat and report generation""" + + agent_slug = 'five-whys-analyzer' + webhook_url = 'https://m8taq6tk.rpcld.cc/webhook/5-whys-web' + agent_id = 'five-whys-001' + + def process_response(self, response_data, request_obj): + """Required implementation of abstract method - delegates to specific handlers""" + # This method is required by the base class but we handle responses + # differently in our dual-mode approach + return self.process_report_response(response_data, request_obj) + + def process_request(self, **kwargs): + """Handle both chat messages (free) and report generation (paid)""" + message_type = kwargs.get('message_type', 'chat') + + if message_type == 'chat': + return self.handle_chat_message(**kwargs) + elif message_type == 'generate_report': + return self.handle_report_generation(**kwargs) + else: + raise ValueError(f"Unknown message type: {message_type}") + + def handle_chat_message(self, **kwargs): + """Handle free chat interactions - no wallet deduction""" + user = kwargs.get('user') + session_id = kwargs.get('session_id', str(uuid.uuid4())) + user_message = kwargs.get('message', '') + + # Get the agent object + from agent_base.models import BaseAgent + try: + agent = BaseAgent.objects.get(slug=self.agent_slug) + except BaseAgent.DoesNotExist: + raise Exception(f"Agent with slug '{self.agent_slug}' not found") + + # Get or create request object for this session + request_obj, created = FiveWhysAnalyzerRequest.objects.get_or_create( + user=user, + session_id=session_id, + chat_active=True, + defaults={ + 'agent': agent, + 'cost': 0, # No cost for chat + 'status': 'pending' + } + ) + + # Add user message to chat history + chat_messages = request_obj.chat_messages + chat_messages.append({ + 'role': 'user', + 'message': user_message, + 'timestamp': timezone.now().isoformat() + }) + request_obj.chat_messages = chat_messages + request_obj.save() + + # Prepare chat payload for webhook + chat_payload = { + 'message': { + 'text': f"Chat message: {user_message}. Provide helpful guidance about 5 Whys analysis. Do not generate the final report - just chat and help the user understand their problem." + }, + 'sessionId': session_id, + 'userId': str(user.id), + 'agentId': self.agent_id, + 'messageType': 'chat' + } + + # Send to webhook + response_data = self.make_request(chat_payload) + + # Process chat response (no wallet deduction) + return self.process_chat_response(response_data, request_obj, user_message) + + def handle_report_generation(self, **kwargs): + """Handle paid report generation - deduct wallet after success""" + user = kwargs.get('user') + session_id = kwargs.get('session_id') + problem_statement = kwargs.get('problem_statement', '') + context_info = kwargs.get('context_info', '') + analysis_depth = kwargs.get('analysis_depth', 'standard') + + # Get the agent object + from agent_base.models import BaseAgent + try: + agent = BaseAgent.objects.get(slug=self.agent_slug) + except BaseAgent.DoesNotExist: + raise Exception(f"Agent with slug '{self.agent_slug}' not found") + + # Get existing session or create new one + try: + request_obj = FiveWhysAnalyzerRequest.objects.get( + user=user, + session_id=session_id, + chat_active=True + ) + except FiveWhysAnalyzerRequest.DoesNotExist: + # Create new request for report generation + request_obj = FiveWhysAnalyzerRequest.objects.create( + user=user, + session_id=session_id, + agent=agent, + cost=8.0, # Cost for report generation + status='pending' + ) + + # Update request with report details + request_obj.problem_statement = problem_statement + request_obj.context_info = context_info + request_obj.analysis_depth = analysis_depth + request_obj.cost = 8.0 # Ensure cost is set for report + request_obj.save() + + # Prepare report generation payload + report_payload = { + 'message': { + 'text': f"Generate comprehensive 5 Whys analysis report.\nProblem: {problem_statement}\nContext: {context_info}\nDepth: {analysis_depth}\nChat History: {json.dumps(request_obj.chat_messages[-10:])}" + }, + 'sessionId': session_id, + 'userId': str(user.id), + 'agentId': self.agent_id, + 'messageType': 'report', + 'analysisDepth': analysis_depth + } + + # Send to webhook + response_data = self.make_request(report_payload) + + # Process report response (with wallet deduction) + return self.process_report_response(response_data, request_obj) + + def process_chat_response(self, response_data, request_obj, user_message): + """Process chat response - no wallet deduction""" + try: + # Extract chat response + chat_response = response_data.get('output', response_data.get('message', 'I\'m here to help with 5 Whys analysis. What would you like to know?')) + + # Add assistant response to chat history + chat_messages = request_obj.chat_messages + chat_messages.append({ + 'role': 'assistant', + 'message': chat_response, + 'timestamp': timezone.now().isoformat() + }) + request_obj.chat_messages = chat_messages + request_obj.status = 'completed' # Chat message completed + request_obj.save() + + # Get or create response object + response_obj, created = FiveWhysAnalyzerResponse.objects.get_or_create( + request=request_obj, + defaults={ + 'success': True, + 'processing_time': response_data.get('processing_time', 0) + } + ) + + # Update response with chat data + response_obj.chat_response = chat_response + chat_history = response_obj.chat_history + chat_history.append({ + 'user_message': user_message, + 'assistant_response': chat_response, + 'timestamp': timezone.now().isoformat() + }) + response_obj.chat_history = chat_history + response_obj.save() + + print(f"{self.agent_slug}: Chat message processed - no wallet deduction") + return response_obj + + except Exception as e: + request_obj.status = 'failed' + request_obj.save() + raise Exception(f"Failed to process chat response: {e}") + + def process_report_response(self, response_data, request_obj): + """Process report generation response - deduct wallet after success""" + try: + request_obj.status = 'processing' + request_obj.save() + + # Extract report data + final_report = response_data.get('output', response_data.get('report', '')) + success = bool(final_report) and response_data.get('success', True) + + # Get or create response object + response_obj, created = FiveWhysAnalyzerResponse.objects.get_or_create( + request=request_obj, + defaults={ + 'success': success, + 'processing_time': response_data.get('processing_time', 0) + } + ) + + if success: + # Update with final report + response_obj.final_report = final_report + response_obj.report_metadata = { + 'analysis_depth': request_obj.analysis_depth, + 'generated_at': timezone.now().isoformat(), + 'problem_statement': request_obj.problem_statement, + 'context_info': request_obj.context_info + } + response_obj.save() + + # Mark request as report generated + request_obj.report_generated = True + request_obj.chat_active = False # End chat session + + # ONLY deduct wallet balance after successful report generation + request_obj.user.deduct_balance( + request_obj.cost, + f"5 Whys Analysis Agent - Final Report ({request_obj.analysis_depth})", + 'five-whys-analyzer' + ) + print(f"{self.agent_slug}: Wallet deducted {request_obj.cost} AED for successful report generation") + + request_obj.status = 'completed' + else: + request_obj.status = 'failed' + response_obj.error_message = "Failed to generate report" + response_obj.save() + + request_obj.processed_at = timezone.now() + request_obj.save() + + return response_obj + + except Exception as e: + request_obj.status = 'failed' + request_obj.save() + raise Exception(f"Failed to process report response: {e}") + + def prepare_message_text(self, **kwargs): + """Legacy method for compatibility""" + return kwargs.get('message', 'Process 5 Whys analysis') \ No newline at end of file diff --git a/five_whys_analyzer/templates/five_whys_analyzer/detail.html b/five_whys_analyzer/templates/five_whys_analyzer/detail.html new file mode 100644 index 0000000..8e3e739 --- /dev/null +++ b/five_whys_analyzer/templates/five_whys_analyzer/detail.html @@ -0,0 +1,671 @@ +{% extends "base.html" %} +{% csrf_token %} + +{% block title %}5 Whys Analysis Agent - NetCop AI Hub{% endblock %} + +{% block content %} +
+ +
+ +
+ +
+

+ 🔍 {{ agent.name }} +

+

+ {{ agent.description }} +

+
+ + +
+

💬 Chat with 5 Whys Analyst

+ + +
+
5 Whys Analyst
+
+ Hello! I'm here to help you with root cause analysis using the 5 Whys methodology. + + You can ask me questions, describe your problem, and I'll guide you through the analysis process. When you're ready, I can generate a comprehensive report for 8.00 AED. + + How can I help you today? +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+

📋 Generate Final Report

+ +
+ 💬 Ask 2-3 questions about your problem first, then I'll generate a comprehensive report +
+ + + + +
+ + + +
+ + +
+
+

💳 Your Wallet

+ +
+ {{ user.wallet_balance|floatformat:2 }} AED +
+
+ Available Balance +
+ + + 💳 Top Up Wallet + +
+ +
+

💡 How it works

+
    +
  • + + Chat freely to explore your problem +
  • +
  • + + Get guidance and ask questions +
  • +
  • + + Generate final report when ready +
  • +
  • + + Pay only for the final report +
  • +
+
+
+
+
+ + + + +{% endblock %} \ No newline at end of file diff --git a/five_whys_analyzer/urls.py b/five_whys_analyzer/urls.py new file mode 100644 index 0000000..d333e82 --- /dev/null +++ b/five_whys_analyzer/urls.py @@ -0,0 +1,13 @@ +from django.urls import path +from . import views + +app_name = 'five_whys_analyzer' + +urlpatterns = [ + path('', views.five_whys_analyzer_detail, name='detail'), + path('chat/', views.FiveWhysAnalyzerChatView.as_view(), name='chat'), + path('report/', views.FiveWhysAnalyzerReportView.as_view(), name='report'), + path('session//', views.five_whys_analyzer_session, name='session'), + # Legacy compatibility + path('process/', views.FiveWhysAnalyzerProcessView.as_view(), name='process'), +] \ No newline at end of file diff --git a/five_whys_analyzer/views.py b/five_whys_analyzer/views.py new file mode 100644 index 0000000..5258281 --- /dev/null +++ b/five_whys_analyzer/views.py @@ -0,0 +1,186 @@ +from django.shortcuts import render, redirect +from django.contrib.auth.decorators import login_required +from django.contrib import messages +from django.http import JsonResponse +from django.views.decorators.csrf import csrf_exempt +from django.utils.decorators import method_decorator +from django.views import View +from agent_base.models import BaseAgent +from .models import FiveWhysAnalyzerRequest, FiveWhysAnalyzerResponse +from .processor import FiveWhysAnalyzerProcessor +import json +import uuid + + +@login_required +def five_whys_analyzer_detail(request): + """Detail page for 5 Whys Analysis Agent with chat interface""" + try: + agent = BaseAgent.objects.get(slug='five-whys-analyzer') + except BaseAgent.DoesNotExist: + messages.error(request, '5 Whys Analysis Agent agent not found.') + return redirect('core:homepage') + + # Get user's active chat sessions + active_sessions = FiveWhysAnalyzerRequest.objects.filter( + user=request.user, + chat_active=True + ).order_by('-created_at')[:5] + + # Get user's completed reports + completed_reports = FiveWhysAnalyzerRequest.objects.filter( + user=request.user, + report_generated=True + ).order_by('-created_at')[:10] + + context = { + 'agent': agent, + 'active_sessions': active_sessions, + 'completed_reports': completed_reports + } + return render(request, 'five_whys_analyzer/detail.html', context) + + +@method_decorator(csrf_exempt, name='dispatch') +class FiveWhysAnalyzerChatView(View): + """Handle chat messages - free interactions""" + + def post(self, request): + if not request.user.is_authenticated: + return JsonResponse({'error': 'Authentication required'}, status=401) + + try: + # Parse request data + data = json.loads(request.body) + + # Get session ID or create new one + session_id = data.get('session_id', str(uuid.uuid4())) + user_message = data.get('message', '').strip() + + if not user_message: + return JsonResponse({'error': 'Message cannot be empty'}, status=400) + + # Process chat message (no wallet deduction) + processor = FiveWhysAnalyzerProcessor() + result = processor.handle_chat_message( + user=request.user, + session_id=session_id, + message=user_message + ) + + return JsonResponse({ + 'success': True, + 'session_id': session_id, + 'response': result.chat_response, + 'message_type': 'chat', + 'wallet_balance': float(request.user.wallet_balance) # No change expected + }) + + except Exception as e: + return JsonResponse({'error': str(e)}, status=500) + + +@method_decorator(csrf_exempt, name='dispatch') +class FiveWhysAnalyzerReportView(View): + """Generate final report - paid interaction""" + + def post(self, request): + if not request.user.is_authenticated: + return JsonResponse({'error': 'Authentication required'}, status=401) + + try: + # Parse request data + data = json.loads(request.body) + + # Get report parameters + session_id = data.get('session_id') + problem_statement = data.get('problem_statement', '').strip() + context_info = data.get('context_info', '').strip() + analysis_depth = data.get('analysis_depth', 'standard') + + if not session_id: + return JsonResponse({'error': 'Session ID required'}, status=400) + + if not problem_statement: + return JsonResponse({'error': 'Problem statement required'}, status=400) + + # Get agent for price checking + agent = BaseAgent.objects.get(slug='five-whys-analyzer') + + # Check wallet balance + if not request.user.has_sufficient_balance(agent.price): + return JsonResponse({'error': 'Insufficient wallet balance'}, status=400) + + # Process report generation (wallet deduction after success) + processor = FiveWhysAnalyzerProcessor() + result = processor.handle_report_generation( + user=request.user, + session_id=session_id, + problem_statement=problem_statement, + context_info=context_info, + analysis_depth=analysis_depth + ) + + # Refresh user to get updated wallet balance + request.user.refresh_from_db() + + return JsonResponse({ + 'success': True, + 'session_id': session_id, + 'report': result.final_report, + 'message_type': 'report', + 'analysis_depth': analysis_depth, + 'wallet_balance': float(request.user.wallet_balance) + }) + + except BaseAgent.DoesNotExist: + return JsonResponse({'error': '5 Whys Analysis Agent not found'}, status=404) + except Exception as e: + return JsonResponse({'error': str(e)}, status=500) + + +@login_required +def five_whys_analyzer_session(request, session_id): + """Get chat session data""" + try: + session_request = FiveWhysAnalyzerRequest.objects.get( + session_id=session_id, + user=request.user + ) + + session_data = { + 'session_id': session_id, + 'chat_messages': session_request.chat_messages, + 'chat_active': session_request.chat_active, + 'report_generated': session_request.report_generated, + 'problem_statement': session_request.problem_statement, + 'context_info': session_request.context_info, + 'analysis_depth': session_request.analysis_depth + } + + # Add final report if generated + if session_request.report_generated and hasattr(session_request, 'response'): + session_data['final_report'] = session_request.response.final_report + session_data['report_metadata'] = session_request.response.report_metadata + + return JsonResponse({ + 'success': True, + 'session': session_data + }) + + except FiveWhysAnalyzerRequest.DoesNotExist: + return JsonResponse({'error': 'Session not found'}, status=404) + except Exception as e: + return JsonResponse({'error': str(e)}, status=500) + + +# Legacy view for compatibility +@method_decorator(csrf_exempt, name='dispatch') +class FiveWhysAnalyzerProcessView(View): + """Legacy process view - redirects to chat interface""" + + def post(self, request): + return JsonResponse({ + 'error': 'This endpoint is deprecated. Use the chat interface instead.', + 'redirect': '/agents/five-whys-analyzer/' + }, status=410) \ No newline at end of file diff --git a/netcop_hub/settings.py b/netcop_hub/settings.py index cb59873..7e25461 100644 --- a/netcop_hub/settings.py +++ b/netcop_hub/settings.py @@ -51,6 +51,7 @@ INSTALLED_APPS = [ 'data_analyzer', 'job_posting_generator', 'social_ads_generator', + 'five_whys_analyzer', ] MIDDLEWARE = [ diff --git a/netcop_hub/urls.py b/netcop_hub/urls.py index 1d7a776..48b0309 100644 --- a/netcop_hub/urls.py +++ b/netcop_hub/urls.py @@ -26,6 +26,7 @@ urlpatterns = [ path('agents/data-analyzer/', include('data_analyzer.urls')), path('agents/job-posting-generator/', include('job_posting_generator.urls')), path('agents/social-ads-generator/', include('social_ads_generator.urls')), + path('agents/five-whys-analyzer/', include('five_whys_analyzer.urls')), path('', include('core.urls')), ]