Chatbot_RAG / ui_utils.py
felixflier03's picture
Update ui_utils.py
b020283 verified
Raw
History Blame Contribute Delete
8.15 kB
import streamlit as st
from typing import Dict, Any, List, Union
import logging
logger = logging.getLogger(__name__)
def display_chat_message(message: Dict[str, Any], idx: int):
with st.chat_message(message["role"]):
# Hauptinhalt
content = message["content"]
st.markdown(content)
if message["role"] == "assistant":
# Button Container Styling
st.markdown("""
<style>
.button-container {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 4px;
margin-top: -30px;
margin-right: 8px;
}
/* Entferne alle Browser-Tooltips */
button::after,
button::before,
[data-tooltip]::after,
[data-tooltip]::before,
[role="tooltip"],
.streamlit-tooltip {
display: none !important;
opacity: 0 !important;
pointer-events: none !important;
}
/* Feedback Message Styling */
.feedback-message {
display: inline-block;
margin-right: 8px;
opacity: 0;
transition: opacity 0.3s;
}
.feedback-message.show {
opacity: 1;
}
</style>
""", unsafe_allow_html=True)
cols = st.columns([0.94, 0.02, 0.02, 0.02])
with cols[1]:
if st.button("📋", key=f'copy_{idx}', use_container_width=True):
st.session_state.to_copy = message["content"]
st.markdown('<div class="feedback-message show">Kopiert!</div>', unsafe_allow_html=True)
with cols[2]:
if st.button("👎", key=f'thumb_down_{idx}', use_container_width=True):
st.markdown('<div class="feedback-message show">Danke für Ihr Feedback!</div>', unsafe_allow_html=True)
with cols[3]:
if st.button("👍", key=f'thumb_up_{idx}', use_container_width=True):
st.markdown('<div class="feedback-message show">Danke für Ihr Feedback!</div>', unsafe_allow_html=True)
# Zeige Metadaten direkt nach der Nachricht an
if "metadata" in message:
display_metadata(message["metadata"])
def display_typical_questions(questions: List[str]):
"""Zeigt typische Fragen als einheitlich gestylte Buttons an"""
cols = st.columns(len(questions))
for idx, question in enumerate(questions):
with cols[idx]:
if st.button(
question,
key=f'question_{idx}',
help="Klicken Sie um diese Frage zu stellen",
use_container_width=True,
type="secondary"
):
st.session_state.user_prompt = question
def display_metadata(metadata: Union[Dict[str, Any], str]):
"""Zeigt Metadaten sicher an"""
try:
if isinstance(metadata, str):
st.warning(f"Unerwartetes Metadaten-Format: {metadata}")
return
if not isinstance(metadata, dict):
st.warning(f"Ungültiges Metadaten-Format: {type(metadata)}")
return
with st.expander("🔍 Details", expanded=False):
# Intent und Konfidenz
col1, col2 = st.columns(2)
with col1:
intent_info = metadata.get('intent', {})
if isinstance(intent_info, dict):
st.markdown(f"**Intent:** {intent_info.get('intent', 'unknown')}")
if metadata.get('subintents'):
st.markdown("**Sub-Intents:**")
for subintent in metadata['subintents']:
st.markdown(f"- {subintent}")
with col2:
if isinstance(intent_info, dict):
confidence = intent_info.get('confidence', 0.0)
st.markdown(f"**Konfidenz:** {confidence:.2f}")
# Weitere Metadaten-Anzeige...
if metadata.get('quality_metrics'):
metrics = metadata['quality_metrics'].get('metrics', {})
if metrics:
st.markdown("### Qualitätsmetriken")
metric_data = {
'Metrik': ['Datenkonsistenz', 'Antwortrelevanz'],
'Score': [
f"{metrics.get('data_consistency', {}).get('score', 0.0):.2f}",
f"{metrics.get('query_relevance', {}).get('score', 0.0):.2f}"
],
'Status': [
"✅" if metrics.get('data_consistency', {}).get('passes', False) else "❌",
"✅" if metrics.get('query_relevance', {}).get('passes', False) else "❌"
]
}
st.table(metric_data)
except Exception as e:
logger.error(f"Fehler bei Metadaten-Anzeige: {str(e)}")
st.warning("Metadaten konnten nicht angezeigt werden")
def add_scroll_button():
"""Fügt einen Scroll-nach-unten Button hinzu"""
scroll_button_style = """
<style>
#scroll-button {
position: fixed;
bottom: 120px;
right: 20px;
background-color: rgba(6, 182, 212, 0.8);
color: white;
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
font-size: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
z-index: 9999;
}
#scroll-button:hover {
background-color: rgba(6, 182, 212, 1);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
}
@media (max-width: 768px) {
#scroll-button {
bottom: 80px;
right: 10px;
width: 35px;
height: 35px;
font-size: 20px;
}
}
</style>
<script>
// Warte bis das Dokument geladen ist
document.addEventListener('DOMContentLoaded', function() {
// Erstelle den Scroll-Button
const scrollButton = document.createElement('button');
scrollButton.id = 'scroll-button';
scrollButton.innerHTML = '<i class="fas fa-arrow-down"></i>';
document.body.appendChild(scrollButton);
// Scroll-Funktion
scrollButton.addEventListener('click', () => {
window.scrollTo({
top: document.body.scrollHeight,
behavior: 'smooth'
});
});
// Button ein-/ausblenden basierend auf Scroll-Position
window.addEventListener('scroll', () => {
const scrollPosition = window.scrollY;
const windowHeight = window.innerHeight;
const documentHeight = document.documentElement.scrollHeight;
scrollButton.style.display =
scrollPosition + windowHeight < documentHeight - 100 ? 'flex' : 'none';
});
});
</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
"""
st.components.v1.html(scroll_button_style, height=0)
def add_font_size_control():
"""Fügt eine Schriftgrößen-Kontrolle hinzu"""
st.sidebar.markdown("### Textgröße")
font_size = st.sidebar.slider("Wählen Sie die Textgröße", 12, 24, 16)
st.markdown(
f"""
<style>
.stChatMessage p {{
font-size: {font_size}px !important;
line-height: 1.5;
}}
</style>
""",
unsafe_allow_html=True
)