feat(chat): Add recommendations and news to AI chat context

- Add CompanyRecommendation and ZOPKNews imports to nordabiz_chat.py
- Fetch approved recommendations (last 20) in conversation context
- Fetch approved news from last 30 days (last 10) in context
- Serialize recommendations and news to JSON in AI prompt
- Update system prompt with data format descriptions
- Update chat template header description
- Add new suggestion chips: "Kto poleca firmę..." and "Co słychać..."

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-01-13 13:19:23 +01:00
parent ffc6d8219f
commit 819273bb58
2 changed files with 78 additions and 9 deletions

View File

@ -36,7 +36,9 @@ from database import (
Award,
CompanyEvent,
AIChatConversation,
AIChatMessage
AIChatMessage,
CompanyRecommendation,
ZOPKNews
)
# Import feedback learning service for few-shot learning
@ -314,6 +316,41 @@ class NordaBizChatEngine:
for msg in reversed(messages)
]
# === ETAP 1: Rekomendacje i Newsy ===
# Add approved recommendations (peer endorsements)
recommendations = db.query(CompanyRecommendation).filter_by(
status='approved'
).order_by(CompanyRecommendation.created_at.desc()).limit(20).all()
context['recommendations'] = [
{
'company': rec.company.name if rec.company else 'Nieznana',
'text': rec.recommendation_text[:200] if rec.recommendation_text else '',
'service': rec.service_category or '',
'author': rec.user.name if rec.user and rec.show_contact else 'Członek Norda Biznes'
}
for rec in recommendations
]
# Add recent approved news (last 30 days)
from datetime import timedelta
news_cutoff = datetime.now() - timedelta(days=30)
recent_news = db.query(ZOPKNews).filter(
ZOPKNews.status == 'approved',
ZOPKNews.published_at >= news_cutoff
).order_by(ZOPKNews.published_at.desc()).limit(10).all()
context['recent_news'] = [
{
'title': news.title[:100] if news.title else '',
'source': news.source_name or '',
'date': news.published_at.strftime('%Y-%m-%d') if news.published_at else '',
'type': news.news_type or 'news'
}
for news in recent_news
]
return context
def _company_to_compact_dict(self, c: Company) -> Dict[str, Any]:
@ -430,19 +467,26 @@ class NordaBizChatEngine:
import json
# Build system prompt with ALL companies
recommendations_count = len(context.get('recommendations', []))
news_count = len(context.get('recent_news', []))
system_prompt = f"""Jesteś pomocnym asystentem portalu Norda Biznes - katalogu firm zrzeszonych w stowarzyszeniu Norda Biznes z Wejherowa.
📊 MASZ DOSTĘP DO PEŁNEJ BAZY DANYCH:
📊 MASZ DOSTĘP DO BAZY WIEDZY:
- Liczba firm: {context['total_companies']}
- Kategorie: {', '.join([f"{cat['name']} ({cat['company_count']})" for cat in context.get('categories', [])])}
- Rekomendacje członków: {recommendations_count}
- Ostatnie aktualności: {news_count}
🎯 TWOJA ROLA:
- Analizujesz CAŁĄ bazę firm i wybierasz najlepsze dopasowania do pytania użytkownika
- Odpowiadasz zwięźle (2-3 zdania), chyba że użytkownik prosi o szczegóły
- Podajesz konkretne nazwy firm z kontaktem
- Możesz wyszukiwać po: nazwie firmy, usługach, kompetencjach, właścicielach (w history), mieście
- Możesz cytować rekomendacje innych członków
- Możesz informować o aktualnych newsach
📋 FORMAT DANYCH (skróty):
📋 FORMAT DANYCH FIRM (skróty):
- name: nazwa firmy
- cat: kategoria
- desc: krótki opis
@ -453,9 +497,22 @@ class NordaBizChatEngine:
- city: miasto
- cert: certyfikaty
REKOMENDACJE - opinie członków o firmach:
- company: nazwa polecanej firmy
- text: treść rekomendacji
- service: kategoria usługi
- author: kto poleca
📰 AKTUALNOŚCI - ostatnie newsy:
- title: tytuł artykułu
- source: źródło (portal)
- date: data publikacji
WAŻNE:
- ZAWSZE podawaj nazwę firmy i kontakt (tel/web/mail jeśli dostępne)
- Jeśli pytanie o osobę (np. "kto to Roszman") - szukaj w polu "history"
- Jeśli pytanie "kto poleca firmę X" - szukaj w rekomendacjach
- Jeśli pytanie "co słychać" - sprawdź aktualności
- Odpowiadaj PO POLSKU
"""
@ -477,6 +534,18 @@ class NordaBizChatEngine:
system_prompt += json.dumps(context['all_companies'], ensure_ascii=False, indent=None)
system_prompt += "\n"
# Add recommendations (peer endorsements)
if context.get('recommendations'):
system_prompt += "\n\n⭐ REKOMENDACJE CZŁONKÓW:\n"
system_prompt += json.dumps(context['recommendations'], ensure_ascii=False, indent=None)
system_prompt += "\n"
# Add recent news
if context.get('recent_news'):
system_prompt += "\n\n📰 OSTATNIE AKTUALNOŚCI:\n"
system_prompt += json.dumps(context['recent_news'], ensure_ascii=False, indent=None)
system_prompt += "\n"
# Add conversation history
full_prompt = system_prompt + "\n\n# HISTORIA ROZMOWY:\n"
for msg in context.get('recent_messages', []):

View File

@ -459,7 +459,7 @@
<span id="modelName">Ładowanie...</span>
</div>
</div>
<p>Wyszukaj firmy, usługi i partnerów biznesowych</p>
<p>Firmy, usługi, rekomendacje i aktualności Norda Biznes</p>
</div>
<div class="chat-messages" id="chatMessages">
@ -478,15 +478,15 @@
<button class="suggestion-chip" onclick="sendSuggestion('Kto robi strony internetowe?')">
Kto robi strony internetowe?
</button>
<button class="suggestion-chip" onclick="sendSuggestion('Potrzebuję hali stalowej')">
Potrzebuję hali stalowej
<button class="suggestion-chip" onclick="sendSuggestion('Kto poleca firmę PIXLAB?')">
Kto poleca firmę PIXLAB?
</button>
<button class="suggestion-chip" onclick="sendSuggestion('Co słychać w Norda Biznes?')">
Co słychać w Norda Biznes?
</button>
<button class="suggestion-chip" onclick="sendSuggestion('Szukam prawnika')">
Szukam prawnika
</button>
<button class="suggestion-chip" onclick="sendSuggestion('Które firmy mają ISO 9001?')">
Które firmy mają ISO 9001?
</button>
</div>
</div>