Update app.py
Browse files
app.py
CHANGED
|
@@ -181,6 +181,13 @@ footer, #MainMenu { visibility: hidden; }
|
|
| 181 |
margin-top: 4px; padding: 0 6px;
|
| 182 |
}
|
| 183 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
/* ── Source chunks ── */
|
| 185 |
.sources-wrap {
|
| 186 |
margin-top: 10px;
|
|
@@ -552,10 +559,12 @@ else:
|
|
| 552 |
for msg in st.session_state.messages:
|
| 553 |
ts = msg.get("time", "")
|
| 554 |
if msg["role"] == "user":
|
|
|
|
|
|
|
| 555 |
chat_html += f"""
|
| 556 |
<div class="msg-user">
|
| 557 |
<div>
|
| 558 |
-
<div class="bubble-user">{
|
| 559 |
<div class="msg-meta" style="text-align:right;">YOU · {ts}</div>
|
| 560 |
</div>
|
| 561 |
</div>"""
|
|
@@ -564,17 +573,21 @@ else:
|
|
| 564 |
if msg.get("sources"):
|
| 565 |
chips = "".join(f'<span class="source-chip">📎 Chunk {i+1}</span>'
|
| 566 |
for i, _ in enumerate(msg["sources"]))
|
| 567 |
-
sources_html = f"""
|
| 568 |
-
|
| 569 |
-
<div class="source-label">SOURCE CHUNKS USED</div>
|
| 570 |
{chips}
|
| 571 |
</div>"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 572 |
chat_html += f"""
|
| 573 |
<div class="msg-ai">
|
| 574 |
<div>
|
| 575 |
<div class="bubble-ai">
|
| 576 |
-
<div class="answer-label">QUERYDOCS RESPONSE</div>
|
| 577 |
-
|
| 578 |
{sources_html}
|
| 579 |
</div>
|
| 580 |
<div class="msg-meta">📚 QUERYDOCS AI · {ts} · {msg.get("elapsed","?")}s</div>
|
|
|
|
| 181 |
margin-top: 4px; padding: 0 6px;
|
| 182 |
}
|
| 183 |
|
| 184 |
+
.answer-text {
|
| 185 |
+
white-space: pre-wrap;
|
| 186 |
+
word-break: break-word;
|
| 187 |
+
line-height: 1.75;
|
| 188 |
+
font-size: 0.95rem;
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
/* ── Source chunks ── */
|
| 192 |
.sources-wrap {
|
| 193 |
margin-top: 10px;
|
|
|
|
| 559 |
for msg in st.session_state.messages:
|
| 560 |
ts = msg.get("time", "")
|
| 561 |
if msg["role"] == "user":
|
| 562 |
+
import html as html_module
|
| 563 |
+
safe_user = html_module.escape(msg["content"])
|
| 564 |
chat_html += f"""
|
| 565 |
<div class="msg-user">
|
| 566 |
<div>
|
| 567 |
+
<div class="bubble-user">{safe_user}</div>
|
| 568 |
<div class="msg-meta" style="text-align:right;">YOU · {ts}</div>
|
| 569 |
</div>
|
| 570 |
</div>"""
|
|
|
|
| 573 |
if msg.get("sources"):
|
| 574 |
chips = "".join(f'<span class="source-chip">📎 Chunk {i+1}</span>'
|
| 575 |
for i, _ in enumerate(msg["sources"]))
|
| 576 |
+
sources_html = f"""<div class="sources-wrap">
|
| 577 |
+
<div class="source-label">// SOURCE CHUNKS USED</div>
|
|
|
|
| 578 |
{chips}
|
| 579 |
</div>"""
|
| 580 |
+
|
| 581 |
+
# Escape answer to prevent HTML injection from LLM output
|
| 582 |
+
import html as html_module
|
| 583 |
+
safe_answer = html_module.escape(msg["content"]).replace("\n", "<br>")
|
| 584 |
+
|
| 585 |
chat_html += f"""
|
| 586 |
<div class="msg-ai">
|
| 587 |
<div>
|
| 588 |
<div class="bubble-ai">
|
| 589 |
+
<div class="answer-label">// QUERYDOCS RESPONSE</div>
|
| 590 |
+
<div class="answer-text">{safe_answer}</div>
|
| 591 |
{sources_html}
|
| 592 |
</div>
|
| 593 |
<div class="msg-meta">📚 QUERYDOCS AI · {ts} · {msg.get("elapsed","?")}s</div>
|