diff --git a/docs/AGENT_SETUP_CHECKLIST.md b/docs/AGENT_SETUP_CHECKLIST.md
index 6b9b25d..896e6f1 100644
--- a/docs/AGENT_SETUP_CHECKLIST.md
+++ b/docs/AGENT_SETUP_CHECKLIST.md
@@ -1,12 +1,25 @@
-# Agent Setup Checklist
+# Agent Setup Checklist - Error-Free Creation Guide
## Steps to Complete After Running `create_agent` Command
-This checklist covers the **6 essential steps** needed after running the automated `create_agent` command to make your agent fully functional.
+This checklist covers the **6 essential steps** needed after running the automated `create_agent` command to make your agent fully functional. **Updated with debugging insights from the successful 5 Whys Agent implementation.**
**โ
The automated system now generates all code files including models, views, processors, and admin interface!**
---
+## ๐ **Success Patterns from 5 Whys Agent**
+
+The 5 Whys Analyzer represents the most robust agent implementation with these key features:
+- **Dual-mode processing**: Free chat interactions + paid report generation
+- **Session-based architecture**: UUID tracking with persistent chat history
+- **Delayed wallet deduction**: Only charge after successful processing
+- **Comprehensive error handling**: Graceful failure recovery
+- **Smart status tracking**: Proper request lifecycle management
+
+**Apply these patterns to achieve error-free agent creation.**
+
+---
+
## Example Command
```bash
python manage.py create_agent "PDF Analyzer" "pdf-analyzer" api \
@@ -227,22 +240,29 @@ python manage.py shell -c "from django.urls import reverse; print('Agent URL:',
---
-## ๐ **Common Issues & Quick Fixes**
+## ๐ **Common Issues & Quick Fixes** *(Learned from 5 Whys Debugging)*
### **Issue 1: "No module named 'agent_pdf_analyzer'"**
+**Root Cause:** App not added to Django settings
**Fix:** Make sure you added the app to `INSTALLED_APPS` in settings.py
+**Prevention:** Use the automated validation script (coming soon)
### **Issue 2: "TemplateDoesNotExist: detail.html"**
+**Root Cause:** Template in wrong location or server cache
**Fix:** Ensure template is in correct location within the agent app:
```bash
# Template should be at:
+agent_[name]/templates/agent_[name]/detail.html
+
+# NOT just:
agent_[name]/templates/detail.html
-# NOT in the global templates folder
-# Restart Django server after moving templates
+# CRITICAL: Restart Django server after moving templates
```
+**5 Whys Learning:** Template organization is crucial for reliability
### **Issue 3: "NoReverseMatch: Reverse for 'wallet' not found"**
+**Root Cause:** Missing URL namespaces in templates
**Fix:** Check template URLs use proper namespaces:
```html
@@ -251,42 +271,100 @@ agent_[name]/templates/detail.html
{% url 'core:wallet' %}
```
+**5 Whys Learning:** Always use namespaced URLs for reliability
### **Issue 4: "Agent not found" in marketplace**
+**Root Cause:** BaseAgent entry missing or wrong slug
**Fix:** Verify BaseAgent was created with correct slug:
```bash
python manage.py shell -c "from agent_base.models import BaseAgent; print([a.slug for a in BaseAgent.objects.all()])"
```
-### **Issue 4: Agent page shows 404**
+### **Issue 5: Agent page shows 404**
+**Root Cause:** URL registration order is wrong
**Fix:** Check URL registration order in `netcop_hub/urls.py` - agent URLs must come before core URLs.
+**5 Whys Learning:** URL order matters for Django routing
-### **Issue 5: API key errors**
+### **Issue 6: API key errors**
+**Root Cause:** Environment variable name mismatch
**Fix:** Verify environment variable name matches processor:
```python
# In processor.py
api_key_env = 'DOCPARSER_API_KEY' # Must match .env file
```
----
+### **Issue 7: Wallet deduction errors (5 Whys Pattern)**
+**Root Cause:** Deducting balance before processing success
+**Fix:** Follow the 5 Whys pattern - only deduct after successful processing:
+```python
+# โ Wrong - deduct before processing
+user.deduct_balance(cost, description, agent_slug)
+response = process_request()
-## ๐ **Quick Checklist Summary**
+# โ
Correct - deduct after success (5 Whys pattern)
+response = process_request()
+if response.success:
+ user.deduct_balance(cost, description, agent_slug)
+```
-After running `create_agent`, complete these 6 steps:
+### **Issue 8: Migration conflicts**
+**Root Cause:** Django migrations out of sync with database
+**Fix:** Create empty migration to sync state:
+```bash
+# Create manual sync migration
+python manage.py makemigrations [agent_name] --empty
+# Edit migration to match your needs
+python manage.py migrate
+```
+**5 Whys Learning:** Migration conflicts are common - be prepared to sync manually
-- [ ] **Settings:** Add agent to `INSTALLED_APPS`
-- [ ] **URLs:** Add URL pattern to `netcop_hub/urls.py`
-- [ ] **Database:** Run `makemigrations` and `migrate`
-- [ ] **Marketplace:** Create `BaseAgent` entry (done automatically)
-- [ ] **Environment:** Add API keys to `.env`
-- [ ] **Template:** Create and customize `detail.html` template
-- [ ] **Test:** Verify agent works end-to-end
+### **Issue 9: Session management errors (Advanced Agents)**
+**Root Cause:** No persistent session tracking
+**Fix:** Implement session-based architecture like 5 Whys:
+```python
+# Add to your models
+session_id = models.CharField(max_length=100, default=uuid.uuid4, db_index=True)
+chat_messages = models.JSONField(default=list)
+```
-**Total time:** ~10-15 minutes
+### **Issue 10: Status tracking problems**
+**Root Cause:** Inconsistent request status management
+**Fix:** Use proper status lifecycle like 5 Whys:
+```python
+# Status flow: pending โ processing โ completed/failed
+request_obj.status = 'processing'
+request_obj.save()
+# ... do processing ...
+request_obj.status = 'completed' if success else 'failed'
+request_obj.save()
+```
---
-## ๐ **You're Done!**
+## ๐ **Quick Checklist Summary** *(Error-Free Process)*
+
+After running `create_agent`, complete these **7 critical steps** (updated with 5 Whys learnings):
+
+- [ ] **Settings:** Add agent to `INSTALLED_APPS` in `netcop_hub/settings.py`
+- [ ] **URLs:** Add URL pattern to `netcop_hub/urls.py` **BEFORE core URLs**
+- [ ] **Database:** Run `makemigrations` and `migrate` (watch for conflicts)
+- [ ] **Marketplace:** Verify `BaseAgent` entry created correctly
+- [ ] **Environment:** Add API keys/webhook URLs to `.env`
+- [ ] **Template:** Create `agent_[name]/templates/agent_[name]/detail.html`
+- [ ] **Validation:** Run complete test flow including wallet integration
+
+**5 Whys Bonus Validations:**
+- [ ] **Template Loading:** Restart Django server after template creation
+- [ ] **URL Namespaces:** Use `{% url 'core:wallet' %}` not `{% url 'wallet' %}`
+- [ ] **Error Handling:** Implement try-catch blocks in processor
+- [ ] **Wallet Logic:** Only deduct balance after successful processing
+- [ ] **Status Tracking:** Use pending โ processing โ completed/failed flow
+
+**Total time:** ~15-20 minutes (includes validation steps)
+
+---
+
+## ๐ **You're Done!** *(Error-Free Agent)*
Your agent should now be:
โ
**Visible** in the marketplace
@@ -294,9 +372,22 @@ Your agent should now be:
โ
**Functional** with authentication
โ
**Processing** requests successfully
โ
**Integrated** with wallet system
+โ
**Error-resistant** with proper handling
+โ
**Session-aware** (if applicable)
+โ
**Status-tracked** throughout lifecycle
+
+**Success Validation** (5 Whys Standard):
+- Agent processes test request without errors
+- Wallet deduction only happens after successful processing
+- Templates load correctly with namespaced URLs
+- Error states are handled gracefully
+- Status updates correctly throughout request lifecycle
**Next Steps:**
-- Customize the agent's UI/templates
-- Add more complex business logic
-- Configure additional API integrations
-- Monitor usage and performance
\ No newline at end of file
+- Consider implementing dual-mode processing (free chat + paid reports)
+- Add session management for complex interactions
+- Enhance error handling with comprehensive try-catch blocks
+- Monitor usage patterns and optimize based on 5 Whys learnings
+- Document any new patterns for future agents
+
+**๐ฏ Remember:** Follow the 5 Whys Agent patterns for maximum reliability!
\ No newline at end of file
diff --git a/docs/DEVELOPMENT_GUIDE.md b/docs/DEVELOPMENT_GUIDE.md
index 5ade896..abdfb2c 100644
--- a/docs/DEVELOPMENT_GUIDE.md
+++ b/docs/DEVELOPMENT_GUIDE.md
@@ -1,4 +1,4 @@
-# Development Guide
+# Development Guide - Enhanced with Agent Testing
## Quick Start
@@ -226,4 +226,489 @@ python manage.py shell # Django shell
1. Make script executable: `chmod +x run_dev.sh`
2. Check file permissions: `ls -la`
+---
+
+## ๐งช Agent Testing Procedures *(5 Whys Experience)*
+
+Based on extensive debugging and the successful 5 Whys Analyzer implementation, here are comprehensive testing procedures for error-free agent development.
+
+### Pre-Development Agent Testing Setup
+
+```bash
+# Agent validation environment setup
+python manage.py shell -c "
+from agent_base.models import BaseAgent
+from django.template.loader import get_template
+from django.urls import reverse
+import os
+
+def validate_agent_environment(agent_slug):
+ print(f'๐งช Testing environment for {agent_slug}...')
+
+ # Test 1: BaseAgent exists
+ try:
+ agent = BaseAgent.objects.get(slug=agent_slug)
+ print(f'โ
BaseAgent found: {agent.name}')
+ except BaseAgent.DoesNotExist:
+ print(f'โ BaseAgent not found for slug: {agent_slug}')
+ return False
+
+ # Test 2: URL resolution
+ try:
+ url = reverse('core:agent_detail', args=[agent_slug])
+ print(f'โ
URL resolved: {url}')
+ except Exception as e:
+ print(f'โ URL resolution failed: {e}')
+ return False
+
+ # Test 3: Template loading
+ try:
+ template = get_template(f'{agent_slug.replace(\"-\", \"_\")}/detail.html')
+ print(f'โ
Template found: {template.origin.name}')
+ except Exception as e:
+ print(f'โ Template not found: {e}')
+ return False
+
+ # Test 4: Environment variables (if needed)
+ env_var = f'N8N_WEBHOOK_{agent_slug.upper().replace(\"-\", \"_\")}'
+ if os.getenv(env_var):
+ print(f'โ
Environment variable found: {env_var}')
+ else:
+ print(f'โ ๏ธ Environment variable not set: {env_var}')
+
+ print(f'๐ฏ Environment validation complete for {agent_slug}')
+ return True
+
+# Test your agent
+validate_agent_environment('five-whys-analyzer')
+"
+```
+
+### Agent Request Lifecycle Testing
+
+```bash
+# Test complete agent request lifecycle
+python manage.py shell -c "
+import uuid
+from django.contrib.auth import get_user_model
+from agent_base.models import BaseAgent
+from five_whys_analyzer.models import FiveWhysAnalyzerRequest, FiveWhysAnalyzerResponse
+from five_whys_analyzer.processor import FiveWhysAnalyzerProcessor
+from decimal import Decimal
+
+User = get_user_model()
+
+def test_agent_lifecycle(agent_slug='five-whys-analyzer'):
+ print(f'๐งช Testing complete lifecycle for {agent_slug}...')
+
+ # Get test user
+ user = User.objects.filter(is_superuser=True).first()
+ if not user:
+ print('โ No superuser found for testing')
+ return False
+
+ # Test 1: Agent exists and is active
+ try:
+ agent = BaseAgent.objects.get(slug=agent_slug, is_active=True)
+ print(f'โ
Active agent found: {agent.name} (${agent.price})')
+ except BaseAgent.DoesNotExist:
+ print(f'โ Active agent not found: {agent_slug}')
+ return False
+
+ # Test 2: User has sufficient balance
+ if user.wallet_balance < agent.price:
+ print(f'โ ๏ธ User balance ({user.wallet_balance}) < agent price ({agent.price})')
+ print('Adding test balance...')
+ user.wallet_balance += Decimal('50.00')
+ user.save()
+
+ # Test 3: Create request object
+ session_id = str(uuid.uuid4())
+ try:
+ request_obj = FiveWhysAnalyzerRequest.objects.create(
+ user=user,
+ agent=agent,
+ session_id=session_id,
+ cost=Decimal('8.00'),
+ problem_statement='Test problem for validation',
+ status='pending'
+ )
+ print(f'โ
Request created: {request_obj.id}')
+ except Exception as e:
+ print(f'โ Request creation failed: {e}')
+ return False
+
+ # Test 4: Status transitions
+ try:
+ request_obj.status = 'processing'
+ request_obj.save()
+ print('โ
Status updated to processing')
+
+ request_obj.status = 'completed'
+ request_obj.save()
+ print('โ
Status updated to completed')
+ except Exception as e:
+ print(f'โ Status update failed: {e}')
+ return False
+
+ # Test 5: Response creation
+ try:
+ response_obj = FiveWhysAnalyzerResponse.objects.create(
+ request=request_obj,
+ success=True,
+ final_report='Test report generated successfully',
+ processing_time=2.5
+ )
+ print(f'โ
Response created: {response_obj.id}')
+ except Exception as e:
+ print(f'โ Response creation failed: {e}')
+ return False
+
+ # Test 6: Cleanup
+ response_obj.delete()
+ request_obj.delete()
+ print('โ
Test objects cleaned up')
+
+ print(f'๐ฏ Lifecycle test completed successfully for {agent_slug}')
+ return True
+
+# Run the test
+test_agent_lifecycle()
+"
+```
+
+### Wallet Integration Testing
+
+```bash
+# Test wallet integration patterns (5 Whys delayed deduction pattern)
+python manage.py shell -c "
+from django.contrib.auth import get_user_model
+from agent_base.models import BaseAgent
+from decimal import Decimal
+
+User = get_user_model()
+
+def test_wallet_integration():
+ print('๐งช Testing wallet integration patterns...')
+
+ user = User.objects.filter(is_superuser=True).first()
+ agent = BaseAgent.objects.filter(is_active=True).first()
+
+ if not user or not agent:
+ print('โ Missing test user or agent')
+ return False
+
+ # Record initial balance
+ initial_balance = user.wallet_balance
+ print(f'Initial balance: {initial_balance}')
+
+ # Test 1: Balance check (5 Whys pattern)
+ if user.wallet_balance >= agent.price:
+ print('โ
Sufficient balance for processing')
+ else:
+ print('โ Insufficient balance')
+ return False
+
+ # Test 2: Delayed deduction simulation
+ print('๐ Simulating processing...')
+ processing_success = True # Simulate success
+
+ if processing_success:
+ # Only deduct after success (5 Whys pattern)
+ user.deduct_balance(
+ agent.price,
+ f'Test deduction for {agent.name}',
+ agent.slug
+ )
+ print(f'โ
Balance deducted after success: {user.wallet_balance}')
+
+ # Verify deduction
+ expected_balance = initial_balance - agent.price
+ if user.wallet_balance == expected_balance:
+ print('โ
Wallet deduction verified correct')
+ else:
+ print(f'โ Wallet deduction incorrect: expected {expected_balance}, got {user.wallet_balance}')
+ return False
+ else:
+ print('โ
No deduction for failed processing (correct behavior)')
+
+ # Test 3: Restore balance for other tests
+ user.wallet_balance = initial_balance
+ user.save()
+ print(f'๐ Balance restored to: {user.wallet_balance}')
+
+ print('๐ฏ Wallet integration test completed successfully')
+ return True
+
+test_wallet_integration()
+"
+```
+
+### Template and URL Testing
+
+```bash
+# Test template loading and URL routing (common 5 Whys issues)
+python manage.py shell -c "
+from django.template.loader import get_template
+from django.urls import reverse
+from django.test import RequestFactory
+from django.contrib.auth import get_user_model
+
+User = get_user_model()
+
+def test_template_and_urls():
+ print('๐งช Testing templates and URLs...')
+
+ # Test template loading for all agents
+ agents = ['weather_reporter', 'five_whys_analyzer']
+
+ for agent in agents:
+ try:
+ template = get_template(f'{agent}/detail.html')
+ print(f'โ
Template loaded for {agent}: {template.origin.name}')
+ except Exception as e:
+ print(f'โ Template failed for {agent}: {e}')
+
+ # Test URL resolution
+ url_tests = [
+ ('core:homepage', []),
+ ('core:marketplace', []),
+ ('core:wallet', []),
+ ('core:agent_detail', ['weather-reporter']),
+ ('core:agent_detail', ['five-whys-analyzer']),
+ ]
+
+ for url_name, args in url_tests:
+ try:
+ url = reverse(url_name, args=args)
+ print(f'โ
URL resolved {url_name}: {url}')
+ except Exception as e:
+ print(f'โ URL failed {url_name}: {e}')
+
+ print('๐ฏ Template and URL testing completed')
+
+test_template_and_urls()
+"
+```
+
+### Error Handling Testing
+
+```bash
+# Test error handling patterns (5 Whys comprehensive error handling)
+python manage.py shell -c "
+from five_whys_analyzer.processor import FiveWhysAnalyzerProcessor
+from agent_base.models import BaseAgent
+from django.contrib.auth import get_user_model
+import uuid
+
+User = get_user_model()
+
+def test_error_handling():
+ print('๐งช Testing error handling patterns...')
+
+ processor = FiveWhysAnalyzerProcessor()
+ user = User.objects.filter(is_superuser=True).first()
+
+ # Test 1: Missing session_id
+ try:
+ result = processor.handle_chat_message(
+ user=user,
+ message='Test message'
+ # No session_id - should auto-generate
+ )
+ print('โ
Missing session_id handled gracefully')
+ except Exception as e:
+ print(f'โ Missing session_id caused error: {e}')
+
+ # Test 2: Missing user
+ try:
+ result = processor.handle_chat_message(
+ session_id=str(uuid.uuid4()),
+ message='Test message'
+ # No user - should raise clear error
+ )
+ print('โ Missing user should have raised error')
+ except Exception as e:
+ print(f'โ
Missing user properly handled: {type(e).__name__}')
+
+ # Test 3: Invalid message type
+ try:
+ result = processor.process_request(
+ user=user,
+ message_type='invalid_type'
+ )
+ print('โ Invalid message type should have raised error')
+ except ValueError as e:
+ print(f'โ
Invalid message type properly handled: {e}')
+ except Exception as e:
+ print(f'โ Unexpected error type: {e}')
+
+ print('๐ฏ Error handling testing completed')
+
+test_error_handling()
+"
+```
+
+### Performance and Index Testing
+
+```bash
+# Test database performance and indexes (5 Whys optimization patterns)
+python manage.py shell -c "
+from django.db import connection
+from five_whys_analyzer.models import FiveWhysAnalyzerRequest
+from django.contrib.auth import get_user_model
+import uuid
+import time
+
+User = get_user_model()
+
+def test_performance():
+ print('๐งช Testing database performance...')
+
+ user = User.objects.first()
+ if not user:
+ print('โ No user found for testing')
+ return
+
+ # Test 1: Session lookup performance
+ session_id = str(uuid.uuid4())
+
+ start_time = time.time()
+ try:
+ request = FiveWhysAnalyzerRequest.objects.filter(
+ user=user,
+ session_id=session_id,
+ chat_active=True
+ ).first()
+ end_time = time.time()
+ print(f'โ
Session lookup completed in {(end_time - start_time)*1000:.2f}ms')
+ except Exception as e:
+ print(f'โ Session lookup failed: {e}')
+
+ # Test 2: Index usage check
+ with connection.cursor() as cursor:
+ cursor.execute('EXPLAIN QUERY PLAN SELECT * FROM five_whys_analyzer_requests WHERE session_id = ?', [session_id])
+ plan = cursor.fetchall()
+
+ # Check if index is being used
+ plan_text = str(plan).lower()
+ if 'index' in plan_text:
+ print('โ
Database index being used for session_id queries')
+ else:
+ print('โ ๏ธ No index detected for session_id queries')
+
+ print('๐ฏ Performance testing completed')
+
+test_performance()
+"
+```
+
+### Agent Integration Testing Commands
+
+```bash
+# Complete agent validation script
+python manage.py shell -c "
+def run_complete_agent_test(agent_slug):
+ print(f'๐ Running complete agent test for {agent_slug}')
+ print('='*50)
+
+ tests = [
+ ('Environment', lambda: validate_agent_environment(agent_slug)),
+ ('Lifecycle', lambda: test_agent_lifecycle(agent_slug)),
+ ('Wallet', lambda: test_wallet_integration()),
+ ('Templates & URLs', lambda: test_template_and_urls()),
+ ('Error Handling', lambda: test_error_handling()),
+ ('Performance', lambda: test_performance()),
+ ]
+
+ results = []
+ for test_name, test_func in tests:
+ print(f'\\n๐งช Running {test_name} test...')
+ try:
+ result = test_func()
+ results.append((test_name, result))
+ if result:
+ print(f'โ
{test_name} test PASSED')
+ else:
+ print(f'โ {test_name} test FAILED')
+ except Exception as e:
+ print(f'โ {test_name} test ERROR: {e}')
+ results.append((test_name, False))
+
+ print(f'\\n๐ฏ Test Summary for {agent_slug}:')
+ print('='*30)
+ passed = sum(1 for _, result in results if result)
+ total = len(results)
+
+ for test_name, result in results:
+ status = 'โ
PASS' if result else 'โ FAIL'
+ print(f'{test_name}: {status}')
+
+ print(f'\\nOverall: {passed}/{total} tests passed')
+ if passed == total:
+ print('๐ All tests passed! Agent is ready for production.')
+ else:
+ print('โ ๏ธ Some tests failed. Please review and fix issues.')
+
+# Run for 5 Whys Analyzer
+run_complete_agent_test('five-whys-analyzer')
+"
+```
+
+### 5 Whys Debugging Workflow
+
+When issues arise during agent development, follow this debugging workflow learned from 5 Whys experience:
+
+```bash
+# 1. Basic validation
+python manage.py check
+python manage.py showmigrations [agent_name]
+
+# 2. Template validation
+python manage.py shell -c "
+from django.template.loader import get_template
+template = get_template('[agent_name]/detail.html')
+print('Template found:', template.origin.name)
+"
+
+# 3. URL validation
+python manage.py shell -c "
+from django.urls import reverse
+url = reverse('core:agent_detail', args=['[agent-slug]'])
+print('URL resolved:', url)
+"
+
+# 4. Model validation
+python manage.py shell -c "
+from [agent_name].models import *
+from agent_base.models import BaseAgent
+agent = BaseAgent.objects.get(slug='[agent-slug]')
+print('Agent found:', agent.name)
+"
+
+# 5. Processor validation
+python manage.py shell -c "
+from [agent_name].processor import [AgentName]Processor
+processor = [AgentName]Processor()
+print('Processor initialized successfully')
+"
+```
+
+### Production Readiness Checklist
+
+Based on 5 Whys success patterns, verify these before deploying:
+
+- [ ] **Template Loading**: Templates load without server restart
+- [ ] **URL Routing**: All URLs resolve correctly with namespaces
+- [ ] **Database**: Migrations applied, indexes created
+- [ ] **Wallet Integration**: Delayed deduction pattern implemented
+- [ ] **Error Handling**: Comprehensive try-catch blocks
+- [ ] **Session Management**: UUID-based sessions (if applicable)
+- [ ] **Status Tracking**: Request lifecycle properly managed
+- [ ] **Environment Variables**: All required variables validated
+- [ ] **Performance**: Database queries optimized with indexes
+- [ ] **Testing**: Complete test suite passes
+
+**๐ฏ Following these testing procedures ensures the same level of reliability achieved with the 5 Whys Analyzer.**
+
Happy coding! ๐
\ No newline at end of file
diff --git a/docs/ERROR_PREVENTION_GUIDE.md b/docs/ERROR_PREVENTION_GUIDE.md
new file mode 100644
index 0000000..c4bd04f
--- /dev/null
+++ b/docs/ERROR_PREVENTION_GUIDE.md
@@ -0,0 +1,803 @@
+# Error Prevention Guide for Agent Creation
+
+## ๐ฏ Based on 5 Whys Analyzer Debugging Experience
+
+This guide documents all the common errors encountered during agent development and their proven solutions, based on extensive debugging work that led to the successful 5 Whys Analyzer implementation.
+
+---
+
+## ๐ Table of Contents
+
+1. [Template Loading Errors](#template-loading-errors)
+2. [URL Routing Issues](#url-routing-issues)
+3. [Database Migration Conflicts](#database-migration-conflicts)
+4. [Wallet Integration Problems](#wallet-integration-problems)
+5. [Session Management Issues](#session-management-issues)
+6. [Status Tracking Problems](#status-tracking-problems)
+7. [Error Handling Failures](#error-handling-failures)
+8. [Environment Variable Issues](#environment-variable-issues)
+9. [N8N Webhook Problems](#n8n-webhook-problems)
+10. [Performance and Index Issues](#performance-and-index-issues)
+
+---
+
+## 1. Template Loading Errors
+
+### โ Common Error
+```
+TemplateDoesNotExist: detail.html
+django.template.loader.TemplateDoesNotExist: detail.html
+```
+
+### ๐ Root Cause Analysis
+- Template in wrong directory structure
+- Django server cache holding old template paths
+- Missing app in INSTALLED_APPS
+- Incorrect template naming convention
+
+### โ
5 Whys Learned Solution
+
+**Correct Template Structure:**
+```bash
+# โ
Correct - 5 Whys pattern
+agent_five_whys_analyzer/
+โโโ templates/
+ โโโ five_whys_analyzer/
+ โโโ detail.html
+
+# โ Wrong - causes TemplateDoesNotExist
+agent_five_whys_analyzer/
+โโโ templates/
+ โโโ detail.html # Missing app subdirectory
+```
+
+**Template Path Validation Script:**
+```bash
+# Test template loading before starting server
+python manage.py shell -c "
+from django.template.loader import get_template
+try:
+ template = get_template('five_whys_analyzer/detail.html')
+ print('โ
Template found:', template.origin.name)
+except Exception as e:
+ print('โ Template error:', e)
+"
+```
+
+**Critical Fix Steps:**
+1. Create proper directory structure
+2. Move template to correct location
+3. **RESTART Django server** (cache issue)
+4. Verify template loading with shell command
+
+### ๐ก๏ธ Prevention Strategy
+```bash
+# Template creation checklist
+mkdir -p [agent_name]/templates/[agent_name]/
+cp existing_working_template.html [agent_name]/templates/[agent_name]/detail.html
+# Always restart server after template changes
+```
+
+---
+
+## 2. URL Routing Issues
+
+### โ Common Errors
+```
+NoReverseMatch: Reverse for 'wallet' not found
+django.urls.exceptions.NoReverseMatch at /agents/five-whys-analyzer/
+```
+
+### ๐ Root Cause Analysis
+- Missing URL namespaces in templates
+- Incorrect URL registration order
+- Agent URLs placed after catch-all core URLs
+
+### โ
5 Whys Learned Solution
+
+**Correct URL Namespacing in Templates:**
+```html
+
+Wallet
+Home
+
+
+Wallet
+Home
+Login
+```
+
+**Correct URL Registration Order:**
+```python
+# netcop_hub/urls.py - CRITICAL ORDER
+urlpatterns = [
+ path('admin/', admin.site.urls),
+ path('auth/', include('authentication.urls')),
+
+ # โ
Agent URLs MUST come before core URLs
+ path('agents/weather-reporter/', include('weather_reporter.urls')),
+ path('agents/five-whys-analyzer/', include('five_whys_analyzer.urls')),
+
+ # โ Core URLs with catch-all pattern must be LAST
+ path('', include('core.urls')), # This catches everything - put LAST
+]
+```
+
+**URL Testing Commands:**
+```bash
+# Test URL resolution
+python manage.py shell -c "
+from django.urls import reverse
+try:
+ url = reverse('core:agent_detail', args=['five-whys-analyzer'])
+ print('โ
URL resolved:', url)
+except Exception as e:
+ print('โ URL error:', e)
+"
+```
+
+### ๐ก๏ธ Prevention Strategy
+- Always use namespaced URLs in templates
+- Register agent URLs before core URLs
+- Test URL resolution after each agent creation
+
+---
+
+## 3. Database Migration Conflicts
+
+### โ Common Errors
+```
+django.db.utils.ProgrammingError: relation "five_whys_analyzer_requests" already exists
+django.db.migrations.exceptions.InconsistentMigrationHistory
+```
+
+### ๐ Root Cause Analysis
+- Django migration state out of sync with actual database
+- Manually created tables conflicting with migrations
+- Migration dependencies missing or circular
+
+### โ
5 Whys Learned Solution
+
+**Manual Migration Sync Fix:**
+```bash
+# 1. Check current migration state
+python manage.py showmigrations five_whys_analyzer
+
+# 2. Create empty migration to sync state
+python manage.py makemigrations five_whys_analyzer --empty --name fix_migration_sync
+
+# 3. Edit the migration file to match current state
+# migrations/000X_fix_migration_sync.py
+from django.db import migrations
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ('five_whys_analyzer', '0001_initial'),
+ ]
+ operations = [
+ # Empty operations - just sync Django state
+ ]
+
+# 4. Apply migration
+python manage.py migrate five_whys_analyzer
+```
+
+**Conflict Resolution Pattern:**
+```bash
+# If migration conflicts persist
+python manage.py migrate five_whys_analyzer --fake-initial
+python manage.py migrate five_whys_analyzer
+```
+
+### ๐ก๏ธ Prevention Strategy
+- Always run `makemigrations` immediately after model changes
+- Test migrations on clean database before production
+- Keep migration files in version control
+
+---
+
+## 4. Wallet Integration Problems
+
+### โ Common Errors
+```
+AttributeError: 'User' object has no attribute 'deduct_balance'
+decimal.InvalidOperation: []
+Wallet balance incorrectly deducted for failed requests
+```
+
+### ๐ Root Cause Analysis
+- Deducting balance before processing completion
+- Incorrect decimal handling for currency
+- Missing wallet methods in User model
+
+### โ
5 Whys Learned Solution
+
+**Delayed Deduction Pattern (Critical):**
+```python
+# โ Wrong - deduct before processing
+def process_view(request):
+ # Bad: deduct immediately
+ request.user.deduct_balance(agent.price, description, agent_slug)
+ result = process_request() # What if this fails?
+ return result
+
+# โ
Correct - 5 Whys pattern (deduct after success)
+def process_report_response(self, response_data, request_obj):
+ try:
+ # Process first
+ final_report = response_data.get('output', '')
+ success = bool(final_report) and response_data.get('success', True)
+
+ if success:
+ # Save successful response
+ response_obj.final_report = final_report
+ response_obj.save()
+
+ # ONLY deduct after confirmed success
+ request_obj.user.deduct_balance(
+ request_obj.cost,
+ f"5 Whys Analysis Agent - Final Report",
+ 'five-whys-analyzer'
+ )
+ request_obj.status = 'completed'
+ else:
+ request_obj.status = 'failed'
+ # No wallet deduction for failures
+
+ request_obj.save()
+ return response_obj
+
+ except Exception as e:
+ request_obj.status = 'failed'
+ request_obj.save()
+ # No wallet deduction for exceptions
+ raise Exception(f"Failed to process: {e}")
+```
+
+**Decimal Handling:**
+```python
+# โ
Correct decimal usage
+from decimal import Decimal
+
+# Always use Decimal for currency
+agent.price = Decimal('8.00')
+request_obj.cost = Decimal('8.00')
+
+# Check balance properly
+if request.user.wallet_balance >= agent.price:
+ # Proceed
+```
+
+### ๐ก๏ธ Prevention Strategy
+- Never deduct balance before processing completion
+- Always use Decimal for currency calculations
+- Implement balance checks before processing
+- Test wallet integration with both success and failure scenarios
+
+---
+
+## 5. Session Management Issues
+
+### โ Common Errors
+```
+KeyError: 'session_id'
+Multiple chat sessions created for same user
+Session state lost between requests
+```
+
+### ๐ Root Cause Analysis
+- Missing session ID handling
+- No persistent session storage
+- Poor session lifecycle management
+
+### โ
5 Whys Learned Solution
+
+**Session-Based Model Pattern:**
+```python
+# 5 Whys session management pattern
+class AgentRequest(BaseAgentRequest):
+ # Session management
+ session_id = models.CharField(max_length=100, default=uuid.uuid4, db_index=True)
+
+ # Session state tracking
+ chat_messages = models.JSONField(default=list)
+ chat_active = models.BooleanField(default=True)
+ report_generated = models.BooleanField(default=False)
+
+ class Meta:
+ indexes = [
+ models.Index(fields=['session_id']),
+ models.Index(fields=['user', 'chat_active']),
+ ]
+```
+
+**Session Retrieval Pattern:**
+```python
+# Safe session handling
+def handle_chat_message(self, **kwargs):
+ user = kwargs.get('user')
+ session_id = kwargs.get('session_id', str(uuid.uuid4()))
+
+ # Get or create session
+ request_obj, created = AgentRequest.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 message to 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()
+```
+
+### ๐ก๏ธ Prevention Strategy
+- Always use UUID for session IDs
+- Index session_id field for performance
+- Implement session cleanup for old sessions
+- Test session persistence across requests
+
+---
+
+## 6. Status Tracking Problems
+
+### โ Common Errors
+```
+Requests stuck in 'processing' status
+Status not updated after completion
+Inconsistent status across request lifecycle
+```
+
+### ๐ Root Cause Analysis
+- Missing status updates in error paths
+- No status transitions defined
+- Exception handling bypassing status updates
+
+### โ
5 Whys Learned Solution
+
+**Status Lifecycle Pattern:**
+```python
+# 5 Whys status tracking pattern
+def process_response(self, response_data, request_obj):
+ try:
+ # Always update status to processing
+ request_obj.status = 'processing'
+ request_obj.save()
+
+ # Process the request
+ success = self.extract_and_validate_response(response_data)
+
+ # Update status based on result
+ if success:
+ request_obj.status = 'completed'
+ # Handle successful response
+ else:
+ request_obj.status = 'failed'
+ # Handle failed response
+
+ except Exception as e:
+ # Always handle errors with status update
+ request_obj.status = 'failed'
+ request_obj.save()
+ raise
+ finally:
+ # Always set processed timestamp
+ request_obj.processed_at = timezone.now()
+ request_obj.save()
+```
+
+**Status Validation:**
+```python
+# Status transition validation
+VALID_STATUS_TRANSITIONS = {
+ 'pending': ['processing', 'failed'],
+ 'processing': ['completed', 'failed'],
+ 'completed': [], # Terminal state
+ 'failed': [], # Terminal state
+}
+
+def update_status(self, request_obj, new_status):
+ current_status = request_obj.status
+ if new_status not in VALID_STATUS_TRANSITIONS.get(current_status, []):
+ raise ValueError(f"Invalid status transition: {current_status} -> {new_status}")
+ request_obj.status = new_status
+ request_obj.save()
+```
+
+### ๐ก๏ธ Prevention Strategy
+- Define clear status lifecycle
+- Always update status in exception handlers
+- Use try-finally blocks for cleanup
+- Monitor requests stuck in processing status
+
+---
+
+## 7. Error Handling Failures
+
+### โ Common Errors
+```
+Unhandled exceptions breaking request flow
+Users see raw Django error pages
+No error logging for debugging
+```
+
+### ๐ Root Cause Analysis
+- Missing try-catch blocks
+- No graceful error recovery
+- Poor error messaging to users
+
+### โ
5 Whys Learned Solution
+
+**Comprehensive Error Handling Pattern:**
+```python
+# 5 Whys error handling pattern
+def process_request(self, **kwargs):
+ request_obj = None
+ try:
+ # Create request object
+ request_obj = self.create_request_object(**kwargs)
+
+ # Process the request
+ response_data = self.make_api_call(**kwargs)
+
+ # Handle response
+ return self.process_response(response_data, request_obj)
+
+ except ValidationError as e:
+ # User input error - don't log as system error
+ self.handle_user_error(request_obj, f"Invalid input: {e}")
+ raise Exception(f"Please check your input: {e}")
+
+ except requests.RequestException as e:
+ # External API error - log and retry
+ self.log_api_error(e, request_obj)
+ self.handle_api_error(request_obj, "External service temporarily unavailable")
+ raise Exception("Service temporarily unavailable. Please try again later.")
+
+ except Exception as e:
+ # Unknown error - log everything for debugging
+ self.log_system_error(e, request_obj, **kwargs)
+ self.handle_system_error(request_obj, "An unexpected error occurred")
+ raise Exception("An unexpected error occurred. Please contact support.")
+
+def handle_user_error(self, request_obj, message):
+ if request_obj:
+ request_obj.status = 'failed'
+ request_obj.save()
+ # Don't log user errors as system issues
+
+def handle_api_error(self, request_obj, message):
+ if request_obj:
+ request_obj.status = 'failed'
+ request_obj.save()
+ # Log API errors for monitoring
+ print(f"API Error: {message}")
+
+def handle_system_error(self, request_obj, message):
+ if request_obj:
+ request_obj.status = 'failed'
+ request_obj.save()
+ # Log system errors with full context
+ print(f"SYSTEM ERROR: {message}")
+
+def log_system_error(self, error, request_obj, **kwargs):
+ """Log system errors with full context for debugging"""
+ error_context = {
+ 'error': str(error),
+ 'request_id': str(request_obj.id) if request_obj else 'None',
+ 'user_id': kwargs.get('user', {}).get('id', 'None'),
+ 'agent_slug': self.agent_slug,
+ 'kwargs': kwargs
+ }
+ print(f"SYSTEM ERROR CONTEXT: {error_context}")
+```
+
+**User-Friendly Error Messages:**
+```python
+# Map internal errors to user-friendly messages
+ERROR_MESSAGES = {
+ 'insufficient_balance': "Insufficient wallet balance. Please top up your wallet.",
+ 'file_too_large': "File size exceeds limit. Please upload a smaller file.",
+ 'invalid_format': "Unsupported file format. Please upload a valid file.",
+ 'api_timeout': "Request timed out. Please try again.",
+ 'service_unavailable': "Service temporarily unavailable. Please try again later.",
+ 'unknown_error': "An unexpected error occurred. Please contact support."
+}
+
+def get_user_friendly_error(self, error_code):
+ return ERROR_MESSAGES.get(error_code, ERROR_MESSAGES['unknown_error'])
+```
+
+### ๐ก๏ธ Prevention Strategy
+- Wrap all external calls in try-catch blocks
+- Provide user-friendly error messages
+- Log errors with sufficient context for debugging
+- Test error scenarios during development
+
+---
+
+## 8. Environment Variable Issues
+
+### โ Common Errors
+```
+KeyError: 'N8N_WEBHOOK_5_WHYS'
+API authentication failures
+Webhook URLs not found
+```
+
+### ๐ Root Cause Analysis
+- Environment variables not loaded
+- Variable name mismatches
+- Missing .env file in production
+
+### โ
5 Whys Learned Solution
+
+**Environment Variable Pattern:**
+```python
+# Safe environment variable loading
+import os
+from django.conf import settings
+
+class AgentProcessor:
+ def __init__(self):
+ # Safe environment variable access
+ self.webhook_url = self.get_env_var('N8N_WEBHOOK_5_WHYS')
+ self.api_key = self.get_env_var('EXTERNAL_API_KEY')
+
+ def get_env_var(self, var_name, default=None):
+ """Safely get environment variable with validation"""
+ value = os.getenv(var_name, default)
+ if not value and default is None:
+ raise Exception(f"Required environment variable '{var_name}' not found")
+ return value
+
+ def validate_configuration(self):
+ """Validate all required environment variables"""
+ required_vars = [
+ 'N8N_WEBHOOK_5_WHYS',
+ 'DATABASE_URL',
+ 'SECRET_KEY'
+ ]
+
+ missing_vars = []
+ for var in required_vars:
+ if not os.getenv(var):
+ missing_vars.append(var)
+
+ if missing_vars:
+ raise Exception(f"Missing required environment variables: {missing_vars}")
+```
+
+**Environment Variable Validation Command:**
+```bash
+# Create validation script
+python manage.py shell -c "
+import os
+required_vars = ['N8N_WEBHOOK_5_WHYS', 'OPENWEATHER_API_KEY', 'DATABASE_URL']
+missing = [var for var in required_vars if not os.getenv(var)]
+if missing:
+ print('โ Missing variables:', missing)
+else:
+ print('โ
All required variables present')
+"
+```
+
+### ๐ก๏ธ Prevention Strategy
+- Create environment variable validation script
+- Use safe access patterns with defaults
+- Document all required variables
+- Test with missing variables to ensure graceful failure
+
+---
+
+## 9. N8N Webhook Problems
+
+### โ Common Errors
+```
+Connection refused to N8N webhook
+Webhook timeout errors
+Invalid webhook response format
+```
+
+### ๐ Root Cause Analysis
+- N8N workflow not active
+- Network connectivity issues
+- Response format mismatches
+
+### โ
5 Whys Learned Solution
+
+**Webhook Validation Pattern:**
+```python
+# 5 Whys webhook handling pattern
+class WebhookProcessor(StandardWebhookProcessor):
+ def make_request(self, payload):
+ """Make webhook request with comprehensive error handling"""
+ try:
+ # Validate webhook URL
+ if not self.webhook_url:
+ raise Exception("Webhook URL not configured")
+
+ # Test connectivity first
+ self.test_webhook_connectivity()
+
+ # Make request with timeout
+ response = requests.post(
+ self.webhook_url,
+ json=payload,
+ timeout=30, # 30 second timeout
+ headers={'Content-Type': 'application/json'}
+ )
+
+ # Validate response
+ if response.status_code != 200:
+ raise Exception(f"Webhook returned status {response.status_code}: {response.text}")
+
+ # Validate response format
+ try:
+ response_data = response.json()
+ except ValueError:
+ raise Exception("Webhook returned invalid JSON")
+
+ return response_data
+
+ except requests.ConnectionError:
+ raise Exception("Cannot connect to N8N webhook. Check N8N service status.")
+ except requests.Timeout:
+ raise Exception("Webhook request timed out. Try again later.")
+ except Exception as e:
+ raise Exception(f"Webhook error: {e}")
+
+ def test_webhook_connectivity(self):
+ """Test webhook connectivity before making actual request"""
+ try:
+ test_response = requests.get(
+ self.webhook_url.replace('/webhook/', '/ping/'),
+ timeout=5
+ )
+ return True
+ except:
+ # Webhook connectivity test failed - continue anyway
+ return False
+```
+
+**Webhook Response Validation:**
+```python
+def validate_webhook_response(self, response_data):
+ """Validate webhook response format"""
+ required_fields = ['output', 'success']
+
+ if not isinstance(response_data, dict):
+ raise Exception("Webhook response must be JSON object")
+
+ missing_fields = [field for field in required_fields if field not in response_data]
+ if missing_fields:
+ raise Exception(f"Webhook response missing fields: {missing_fields}")
+
+ return True
+```
+
+### ๐ก๏ธ Prevention Strategy
+- Always test webhook connectivity
+- Implement proper timeout handling
+- Validate webhook response format
+- Have fallback mechanisms for webhook failures
+
+---
+
+## 10. Performance and Index Issues
+
+### โ Common Errors
+```
+Slow database queries
+Missing indexes on frequently queried fields
+Session lookup timeouts
+```
+
+### ๐ Root Cause Analysis
+- Missing database indexes
+- Inefficient query patterns
+- No query optimization
+
+### โ
5 Whys Learned Solution
+
+**Database Index Pattern:**
+```python
+# 5 Whys performance optimization
+class AgentRequest(BaseAgentRequest):
+ session_id = models.CharField(max_length=100, default=uuid.uuid4, db_index=True)
+
+ class Meta:
+ indexes = [
+ # Session-based queries
+ models.Index(fields=['session_id']),
+ models.Index(fields=['user', 'chat_active']),
+
+ # Status and time-based queries
+ models.Index(fields=['status', 'created_at']),
+ models.Index(fields=['user', 'status']),
+
+ # Agent-specific queries
+ models.Index(fields=['agent', 'created_at']),
+ ]
+```
+
+**Query Optimization Pattern:**
+```python
+# Efficient query patterns
+def get_user_active_session(self, user, agent_slug):
+ """Optimized session lookup"""
+ return AgentRequest.objects.select_related('agent', 'user').filter(
+ user=user,
+ agent__slug=agent_slug,
+ chat_active=True
+ ).first()
+
+def get_recent_requests(self, user, limit=10):
+ """Optimized recent requests lookup"""
+ return AgentRequest.objects.select_related('agent').filter(
+ user=user
+ ).order_by('-created_at')[:limit]
+```
+
+### ๐ก๏ธ Prevention Strategy
+- Add indexes for all frequently queried fields
+- Use select_related for foreign key queries
+- Monitor slow queries in production
+- Test with realistic data volumes
+
+---
+
+## ๐ก๏ธ Overall Prevention Strategy
+
+### Pre-Development Checklist
+- [ ] Study 5 Whys Analyzer patterns before starting
+- [ ] Plan session management if needed
+- [ ] Design delayed wallet deduction flow
+- [ ] Plan comprehensive error handling
+
+### During Development Checklist
+- [ ] Use proper template directory structure
+- [ ] Always use namespaced URLs
+- [ ] Implement delayed wallet deduction
+- [ ] Add comprehensive error handling
+- [ ] Create proper database indexes
+
+### Post-Development Checklist
+- [ ] Test all error scenarios
+- [ ] Validate template loading
+- [ ] Test URL routing
+- [ ] Verify wallet integration
+- [ ] Test session management
+- [ ] Validate environment variables
+
+### Production Deployment Checklist
+- [ ] Run migration validation
+- [ ] Test webhook connectivity
+- [ ] Verify environment variables
+- [ ] Monitor error rates
+- [ ] Check performance metrics
+
+---
+
+## ๐ฏ Key Takeaways from 5 Whys Debugging
+
+1. **Template Organization is Critical**: Always use proper directory structure
+2. **URL Namespaces Prevent Errors**: Always use namespaced URLs
+3. **Delayed Wallet Deduction**: Never deduct before processing success
+4. **Session Management**: Use UUID-based sessions for complex agents
+5. **Status Tracking**: Implement proper lifecycle management
+6. **Error Handling**: Wrap everything in try-catch blocks
+7. **Environment Variables**: Validate all required variables
+8. **Performance**: Add indexes for frequently queried fields
+
+**Following these patterns from the 5 Whys success ensures error-free agent creation.**
\ No newline at end of file
diff --git a/docs/MANUAL_AGENT_CREATION_GUIDE.md b/docs/MANUAL_AGENT_CREATION_GUIDE.md
index 3b35073..431ce6d 100644
--- a/docs/MANUAL_AGENT_CREATION_GUIDE.md
+++ b/docs/MANUAL_AGENT_CREATION_GUIDE.md
@@ -1,6 +1,6 @@
-# Complete Manual Agent Creation Guide
+# Complete Manual Agent Creation Guide - Error-Free Edition
-This guide provides step-by-step instructions for manually creating AI agents in the NetCop Hub platform.
+This guide provides step-by-step instructions for manually creating AI agents in the NetCop Hub platform. **Updated with proven patterns from the successful 5 Whys Analyzer implementation.**
## Table of Contents
1. [Overview](#overview)
@@ -20,15 +20,28 @@ This guide provides step-by-step instructions for manually creating AI agents in
### Agent Types
- **API Agents**: Direct integration with external APIs (e.g., OpenWeather, Stripe)
-- **Webhook Agents**: Integration with N8N workflows or custom webhooks
+- **Webhook Agents**: Integration with N8N workflows or custom webhooks *(Recommended)*
+- **Dual-Mode Agents**: Free interactions + paid reports *(5 Whys Pattern)*
-### Architecture
+### Architecture *(5 Whys Success Patterns)*
Each agent is a separate Django app that extends the base agent framework:
- `BaseAgent`: Marketplace catalog entry
- `BaseAgentRequest`/`BaseAgentResponse`: Request/response tracking
- `BaseAgentProcessor`: Processing logic (API or webhook)
- `BaseAgentView`: Form handling and authentication
+### ๐ **5 Whys Analyzer Success Patterns**
+The most robust agent implementation includes these key patterns:
+
+**Core Success Features:**
+- **Session-based architecture**: UUID tracking with persistent state
+- **Dual-mode processing**: Free chat interactions + paid report generation
+- **Delayed wallet deduction**: Only charge after successful processing
+- **Comprehensive error handling**: Try-catch blocks throughout lifecycle
+- **Smart status tracking**: pending โ processing โ completed/failed
+
+**Apply these patterns for maximum reliability and user satisfaction.**
+
## Prerequisites
1. Django project setup and running
@@ -36,6 +49,199 @@ Each agent is a separate Django app that extends the base agent framework:
3. Authentication system configured
4. Wallet system for payments
+---
+
+## ๐ฏ **5 Whys Analyzer - Proven Implementation Patterns**
+
+Before diving into the step-by-step guide, study these proven patterns from the successful 5 Whys Analyzer implementation. **Following these patterns ensures error-free agent creation.**
+
+### Session-Based Models *(Recommended for Complex Agents)*
+
+```python
+# Key model patterns from 5 Whys success
+class FiveWhysAnalyzerRequest(BaseAgentRequest):
+ # Session management
+ session_id = models.CharField(max_length=100, default=uuid.uuid4, db_index=True)
+
+ # Chat interaction tracking
+ chat_messages = models.JSONField(default=list)
+
+ # Mode tracking
+ report_generated = models.BooleanField(default=False)
+ chat_active = models.BooleanField(default=True)
+
+ # Specific request data
+ problem_statement = models.TextField(blank=True)
+ analysis_depth = models.CharField(max_length=20, choices=[...])
+```
+
+### Delayed Wallet Deduction Pattern *(Critical for Reliability)*
+
+```python
+# โ Wrong - deduct before processing
+user.deduct_balance(cost, description, agent_slug)
+response = process_request()
+
+# โ
Correct - 5 Whys pattern (deduct after success)
+def process_report_response(self, response_data, request_obj):
+ try:
+ # Process the request first
+ final_report = response_data.get('output', '')
+ success = bool(final_report) and response_data.get('success', True)
+
+ if success:
+ # Save response data
+ response_obj.final_report = final_report
+ response_obj.save()
+
+ # ONLY deduct wallet balance after successful processing
+ request_obj.user.deduct_balance(
+ request_obj.cost,
+ f"5 Whys Analysis Agent - Final Report",
+ 'five-whys-analyzer'
+ )
+ request_obj.status = 'completed'
+ else:
+ request_obj.status = 'failed'
+
+ request_obj.save()
+ return response_obj
+ except Exception as e:
+ request_obj.status = 'failed'
+ request_obj.save()
+ raise Exception(f"Failed to process: {e}")
+```
+
+### Dual-Mode Processing Pattern *(Free + Paid Interactions)*
+
+```python
+# 5 Whys processor pattern - handle both free chat and paid reports
+def process_request(self, **kwargs):
+ message_type = kwargs.get('message_type', 'chat')
+
+ if message_type == 'chat':
+ return self.handle_chat_message(**kwargs) # Free
+ elif message_type == 'generate_report':
+ return self.handle_report_generation(**kwargs) # Paid
+ else:
+ raise ValueError(f"Unknown message type: {message_type}")
+
+def handle_chat_message(self, **kwargs):
+ # No wallet deduction for chat
+ request_obj.cost = 0
+ # Process free interaction
+ return self.process_chat_response(response_data, request_obj)
+
+def handle_report_generation(self, **kwargs):
+ # Set cost for report generation
+ request_obj.cost = 8.0
+ # Process paid interaction (wallet deducted only after success)
+ return self.process_report_response(response_data, request_obj)
+```
+
+### Comprehensive Error Handling Pattern
+
+```python
+# 5 Whys error handling pattern
+def process_response(self, response_data, request_obj):
+ try:
+ request_obj.status = 'processing'
+ request_obj.save()
+
+ # Extract and validate response
+ result = response_data.get('output', '')
+ success = bool(result) and response_data.get('success', True)
+
+ # Create response object
+ response_obj, created = ModelResponse.objects.get_or_create(
+ request=request_obj,
+ defaults={'success': success, 'processing_time': response_data.get('processing_time', 0)}
+ )
+
+ if success:
+ response_obj.result_data = result
+ response_obj.save()
+
+ # Only deduct balance after confirmed success
+ request_obj.user.deduct_balance(
+ request_obj.cost,
+ f"Agent processing - {request_obj.agent.name}",
+ request_obj.agent.slug
+ )
+ request_obj.status = 'completed'
+ else:
+ request_obj.status = 'failed'
+ response_obj.error_message = "Processing failed"
+ response_obj.save()
+
+ request_obj.processed_at = timezone.now()
+ request_obj.save()
+
+ return response_obj
+
+ except Exception as e:
+ # Always handle errors gracefully
+ request_obj.status = 'failed'
+ request_obj.save()
+
+ # Log the error for debugging
+ print(f"Agent {self.agent_slug} error: {e}")
+ raise Exception(f"Failed to process response: {e}")
+```
+
+### Status Tracking Pattern *(Request Lifecycle Management)*
+
+```python
+# 5 Whys status flow pattern
+# 1. Initial state
+request_obj.status = 'pending'
+
+# 2. Start processing
+request_obj.status = 'processing'
+request_obj.save()
+
+# 3. Complete or fail
+try:
+ # ... do processing ...
+ request_obj.status = 'completed'
+except Exception:
+ request_obj.status = 'failed'
+finally:
+ request_obj.processed_at = timezone.now()
+ request_obj.save()
+```
+
+### Template URL Namespace Pattern *(Prevents 404 Errors)*
+
+```html
+
+Wallet
+
+
+Wallet
+Home
+Login
+```
+
+### Database Index Pattern *(Performance Optimization)*
+
+```python
+# 5 Whys database optimization patterns
+class AgentRequest(BaseAgentRequest):
+ session_id = models.CharField(max_length=100, default=uuid.uuid4, db_index=True)
+
+ class Meta:
+ indexes = [
+ models.Index(fields=['session_id']),
+ models.Index(fields=['user', 'chat_active']),
+ models.Index(fields=['status', 'created_at']),
+ ]
+```
+
+**๐ฏ Key Takeaway:** The 5 Whys Analyzer's success comes from these robust patterns. Apply them to your agents for maximum reliability and user satisfaction.
+
+---
+
## Step 1: Create Django App
### 1.1 Create the App
@@ -304,12 +510,9 @@ class PdfAnalyzerProcessView(View):
language=language,
)
- # Deduct from wallet
- request.user.deduct_balance(
- agent.price,
- f"PDF Analyzer request for {pdf_file.name}",
- 'pdf-analyzer'
- )
+ # โ ๏ธ WARNING: This violates 5 Whys pattern!
+ # Better to deduct ONLY after successful processing
+ # Consider implementing delayed deduction pattern for reliability
# Process request
processor = PdfAnalyzerProcessor()