feat(chat): better markdown rendering, smart titles, follow-up chips, prompt fixes
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-03-28 12:21:03 +01:00
parent 1c7636e5c6
commit 50d31c1b84
2 changed files with 78 additions and 3 deletions

View File

@ -1421,9 +1421,11 @@ BŁĘDNIE (NIE RÓB - resetuje numerację):
1. **Rada Izby NORDA**
Data: 04.02.2026
- Używaj **pogrubienia** dla nazw firm i tytułów
- Używaj **pogrubienia** dla tytułów sekcji i nazw wydarzeń
- Nazwy firm ZAWSZE jako link [Nazwa](/company/slug), nigdy jako bold tekst
- Numeracja MUSI być ciągła w obrębie jednej listy: 1, 2, 3, 4, 5 NIE resetuj do 1
- Gdy dzielisz odpowiedź na sekcje, używaj nagłówków ### zamiast numerowanych list
- Wszystkie szczegóły elementu w JEDNEJ linii (po myślniku lub w nawiasie)
- Numeracja MUSI być sekwencyjna: 1. 2. 3. 4. 5. (nie 1. 1. 1. 1.)
"""
# Add thinking level specific instructions

View File

@ -724,6 +724,57 @@
background: #f5f3ff;
}
/* Chat markdown heading styles */
.chat-heading {
font-size: 14px;
font-weight: 600;
color: var(--text-primary);
margin: 12px 0 6px 0;
}
h3.chat-heading {
font-size: 15px;
}
.chat-bullet {
list-style: none;
padding-left: 16px;
position: relative;
margin: 2px 0;
}
.chat-bullet::before {
content: '\2022';
position: absolute;
left: 4px;
color: var(--primary);
font-weight: bold;
}
/* Follow-up suggestion chips after AI response */
.follow-up-suggestions {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 8px;
padding-top: 8px;
}
.suggestion-chip.small {
font-size: 11px;
padding: 4px 10px;
border-radius: 14px;
background: #f0f4ff;
border: 1px solid #c7d2fe;
color: #3730a3;
cursor: pointer;
transition: background 0.2s;
}
.suggestion-chip.small:hover {
background: #e0e7ff;
}
/* Input area */
.chat-input-area {
padding: var(--spacing-lg);
@ -2430,7 +2481,10 @@ async function sendMessage() {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrfToken },
body: JSON.stringify({
title: message.substring(0, 50) + (message.length > 50 ? '...' : '')
title: (() => {
const firstSentence = message.split(/[.!?]\s/)[0];
return firstSentence.length <= 60 ? firstSentence : message.substring(0, 57) + '...';
})()
})
});
const startData = await startResponse.json();
@ -2545,6 +2599,17 @@ async function sendMessage() {
badgeHTML += `<span class="badge-chip cost">💰 ${costStr}</span>`;
infoBadge.innerHTML = badgeHTML;
streamContent.appendChild(infoBadge);
// Add follow-up suggestion chips
const suggestions = document.createElement('div');
suggestions.className = 'follow-up-suggestions';
suggestions.innerHTML = `
<button class="suggestion-chip small" onclick="sendSuggestion('Podaj dane kontaktowe do wymienionych firm')">&#x1F4C7; Dane kontaktowe</button>
<button class="suggestion-chip small" onclick="sendSuggestion('Porównaj te firmy pod kątem doświadczenia')">&#x2696;&#xFE0F; Porównaj firmy</button>
<button class="suggestion-chip small" onclick="sendSuggestion('Jakie inne firmy mogłyby pomóc?')">&#x1F50D; Więcej firm</button>
`;
streamContent.appendChild(suggestions);
if (chunk.cost_usd) updateMonthlyCost(chunk.cost_usd);
loadConversations();
scrollToBottom();
@ -2732,6 +2797,14 @@ function formatMessage(text) {
return '<a href="' + url + '" target="_blank" rel="noopener" class="' + linkClass + '">' + url + '</a>';
});
// Headers: ### text -> <h4>, ## text -> <h3> (before bold, before \n -> <br>)
text = text.replace(/^### (.+)$/gm, '<h4 class="chat-heading">$1</h4>');
text = text.replace(/^## (.+)$/gm, '<h3 class="chat-heading">$1</h3>');
// Bullet lists: "* text" or "- text" at start of line (before \n -> <br>)
text = text.replace(/^\* (.+)$/gm, '<li class="chat-bullet">$1</li>');
text = text.replace(/^- (.+)$/gm, '<li class="chat-bullet">$1</li>');
// Convert **bold** to <strong>
text = text.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');