🎨 Enhance 5 Whys agent response formatting for professional appearance

Improved agent responses to match the formatting quality of other agents
with structured, engaging content using markdown and professional styling.

## Changes:

### 📝 Enhanced Welcome Message:
- Added markdown headers and emojis for engagement
- Structured sections: 'How It Works' and 'Getting Started'
- Clear bullet points and bold emphasis for key concepts
- Professional yet friendly tone

### 🔧 Improved N8N Webhook Instructions:
- Detailed formatting requirements (headers, bold, lists, emojis)
- Clear content guidelines for systematic 5 Whys guidance
- Instructions for structured but conversational responses
- Focus on interactive guidance vs final reports

### 💻 JavaScript Markdown Processing:
- Added formatMarkdownContent() function for consistent formatting
- Processes headers (##, ###), bold text (**text**), bullet points
- Handles both new real-time messages and existing messages on load
- Shared formatting logic for consistency

### 🎨 Enhanced CSS & Template:
- Better message bubble styling for structured content
- Improved typography and spacing for readability
- Support for formatted headers, lists, and emphasis
- Added data attributes for content processing

## Expected User Experience:
- **Before**: Plain text responses lacking visual hierarchy
- **After**: Professional, structured responses with clear sections,
  bullet points, bold emphasis, and engaging emojis

The 5 Whys agent now provides responses that match the quality and
formatting standards of other premium agents in the platform.

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude 2025-08-03 13:54:23 +05:30
parent 641d676f2f
commit 942bbcdd40
3 changed files with 103 additions and 6 deletions

View File

@ -28,6 +28,31 @@
.message-bubble h3 { font-size: 15px; color: var(--on-surface); } .message-bubble h3 { font-size: 15px; color: var(--on-surface); }
.message-bubble h4 { font-size: 14px; color: var(--on-surface); } .message-bubble h4 { font-size: 14px; color: var(--on-surface); }
/* Handle markdown-style headers in plain text */
.message-bubble p:has(strong):first-child,
.message-bubble p:contains("##"),
.message-bubble p:contains("###") {
font-weight: 600;
color: var(--primary);
margin-top: 16px;
margin-bottom: 8px;
}
/* Enhanced styling for better visual hierarchy */
.message-bubble {
font-size: 14px;
line-height: 1.6;
}
/* Better spacing for structured content */
.message-bubble p:first-child {
margin-top: 0;
}
.message-bubble p:last-child {
margin-bottom: 0;
}
.message-bubble ul, .message-bubble ul,
.message-bubble ol { .message-bubble ol {
margin: 12px 0; margin: 12px 0;
@ -468,7 +493,7 @@ document.body.setAttribute('data-session-expires', '{{ chat_session.expires_at.i
{% if messages %} {% if messages %}
{% for message in messages %} {% for message in messages %}
<div class="message {{ message.message_type }}"> <div class="message {{ message.message_type }}">
<div class="message-bubble"> <div class="message-bubble" data-raw-content="{{ message.content|escape }}">
{{ message.content|linebreaks }} {{ message.content|linebreaks }}
<div class="message-time">{{ message.timestamp|date:"H:i" }}</div> <div class="message-time">{{ message.timestamp|date:"H:i" }}</div>
</div> </div>
@ -709,8 +734,8 @@ class ChatInterface {
const bubbleDiv = document.createElement('div'); const bubbleDiv = document.createElement('div');
bubbleDiv.className = 'message-bubble'; bubbleDiv.className = 'message-bubble';
// Convert line breaks to <br> tags // Use the shared formatting function
const formattedContent = content.replace(/\n/g, '<br>'); const formattedContent = formatMarkdownContent(content);
bubbleDiv.innerHTML = formattedContent; bubbleDiv.innerHTML = formattedContent;
// Add timestamp // Add timestamp
@ -762,6 +787,9 @@ class ChatInterface {
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
new ChatInterface(); new ChatInterface();
// Format existing messages with markdown
formatExistingMessages();
// Clear any old localStorage data for sessions // Clear any old localStorage data for sessions
const sessionId = document.body.getAttribute('data-session-id'); const sessionId = document.body.getAttribute('data-session-id');
if (sessionId) { if (sessionId) {
@ -776,6 +804,42 @@ document.addEventListener('DOMContentLoaded', function() {
} }
}); });
// Format existing messages on page load
function formatExistingMessages() {
const messageBubbles = document.querySelectorAll('.message-bubble[data-raw-content]');
messageBubbles.forEach(bubble => {
const rawContent = bubble.getAttribute('data-raw-content');
if (rawContent) {
const formattedContent = formatMarkdownContent(rawContent);
// Only replace the content part, preserve the timestamp
const timeElement = bubble.querySelector('.message-time');
const timeHTML = timeElement ? timeElement.outerHTML : '';
bubble.innerHTML = formattedContent + timeHTML;
}
});
}
// Helper function to format markdown content
function formatMarkdownContent(content) {
return content
// Convert headers
.replace(/^## (.*$)/gim, '<h2>$1</h2>')
.replace(/^### (.*$)/gim, '<h3>$1</h3>')
// Convert bold text
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
// Convert bullet points
.replace(/^• (.*$)/gim, '<li>$1</li>')
.replace(/^- (.*$)/gim, '<li>$1</li>')
// Convert line breaks
.replace(/\n/g, '<br>')
// Wrap consecutive list items in ul tags
.replace(/(<li>.*?<\/li>(<br>)*)+/gs, '<ul>$&</ul>')
// Clean up extra breaks around lists
.replace(/<ul>(<li>.*?<\/li>)(<br>)*(<li>.*?<\/li>)*<\/ul>/gs, function(match) {
return match.replace(/<br>/g, '');
});
}
// Download functionality // Download functionality
function toggleDownloadMenu() { function toggleDownloadMenu() {
const menu = document.getElementById('downloadMenu'); const menu = document.getElementById('downloadMenu');

View File

@ -544,7 +544,22 @@ def start_chat_session(request):
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# Send welcome message # Send welcome message
welcome_message = f"Welcome to {agent.name}! I'm here to help you with 5 Whys analysis. What problem would you like to analyze?" welcome_message = f"""## Welcome to {agent.name}! 🔍
I'm here to guide you through the **5 Whys methodology** - a powerful problem-solving technique to uncover root causes.
### How It Works:
**Ask "Why" 5 times** to drill down from symptoms to root causes
**Systematic analysis** of Occurrence, Detection, and Prevention
**Actionable insights** for effective solutions
### Getting Started:
Please describe the **specific problem** you'd like to analyze. Include:
- What happened?
- When did it occur?
- What are the immediate impacts?
Let's discover the root cause together! 💪"""
ChatMessage.objects.create( ChatMessage.objects.create(
session=chat_session, session=chat_session,
@ -604,7 +619,25 @@ def send_chat_message(request):
# Prepare webhook payload # Prepare webhook payload
webhook_payload = { webhook_payload = {
"message": { "message": {
"text": f"Chat message: {message_content}. Provide helpful guidance about 5 Whys analysis. Do not generate the final report - just chat and help the user understand their problem." "text": f"""User message: "{message_content}"
Provide helpful 5 Whys analysis guidance with professional formatting:
FORMATTING REQUIREMENTS:
- Use markdown headers (##, ###) for sections
- Use **bold** for key terms and emphasis
- Use bullet points () for lists
- Use numbered lists (1., 2., 3.) for steps
- Structure responses with clear sections
- Add relevant emojis for engagement
CONTENT GUIDELINES:
- Guide through 5 Whys methodology systematically
- Ask probing questions about Occurrence, Detection, Prevention
- Help user drill down from symptoms to root causes
- Keep responses conversational but structured
- Do not generate final reports - focus on interactive guidance
- Encourage deeper thinking with follow-up questions"""
}, },
"sessionId": session_id, "sessionId": session_id,
"userId": str(request.user.id), "userId": str(request.user.id),

View File

@ -22,7 +22,7 @@
</div> </div>
</div> </div>
{% if session.status == 'completed' and session.user_message_count > 0 %} {% if session.user_message_count > 0 and session.status != 'active' %}
<div class="session-actions"> <div class="session-actions">
<div class="download-actions"> <div class="download-actions">
<a href="{% url 'agents:export_chat' session.session_id %}?format=pdf" <a href="{% url 'agents:export_chat' session.session_id %}?format=pdf"