Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -33,15 +33,38 @@ st.markdown(
|
|
| 33 |
.stApp {
|
| 34 |
max-width: 900px;
|
| 35 |
margin: 0 auto;
|
|
|
|
| 36 |
}
|
| 37 |
|
| 38 |
-
/*
|
| 39 |
-
.
|
| 40 |
-
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
}
|
| 43 |
|
| 44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
.trust-header {
|
| 46 |
font-family: 'Titillium Web', sans-serif;
|
| 47 |
text-align: center;
|
|
@@ -145,6 +168,7 @@ st.markdown(
|
|
| 145 |
border-top: 1px solid #E5E7EB;
|
| 146 |
padding-top: 1rem;
|
| 147 |
margin-top: 2rem;
|
|
|
|
| 148 |
}
|
| 149 |
|
| 150 |
.stChatInput > div {
|
|
@@ -166,29 +190,73 @@ st.markdown(
|
|
| 166 |
color: #9CA3AF !important;
|
| 167 |
}
|
| 168 |
|
| 169 |
-
/* Chat messages */
|
| 170 |
.chat-container {
|
| 171 |
-
margin-top:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
}
|
| 173 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
.user-message {
|
| 175 |
background-color: #F3F4F6;
|
| 176 |
padding: 1rem 1.25rem;
|
| 177 |
border-radius: 18px;
|
| 178 |
-
|
| 179 |
-
max-width: 85%;
|
| 180 |
-
margin-left: auto;
|
| 181 |
font-family: 'Titillium Web', sans-serif;
|
|
|
|
| 182 |
}
|
| 183 |
|
| 184 |
.bot-message {
|
| 185 |
background-color: #FFFFFF;
|
| 186 |
padding: 1rem 1.25rem;
|
| 187 |
border-radius: 18px;
|
| 188 |
-
|
| 189 |
-
max-width: 85%;
|
| 190 |
border: 1px solid #E5E7EB;
|
| 191 |
font-family: 'Titillium Web', sans-serif;
|
|
|
|
| 192 |
}
|
| 193 |
|
| 194 |
/* Submit button styling */
|
|
@@ -243,6 +311,18 @@ st.markdown(
|
|
| 243 |
|
| 244 |
/* Mobile responsive */
|
| 245 |
@media screen and (max-width: 600px) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 246 |
.trust-header {
|
| 247 |
font-size: 26px;
|
| 248 |
}
|
|
@@ -267,6 +347,15 @@ st.markdown(
|
|
| 267 |
.prompt-subtitle {
|
| 268 |
font-size: 0.85rem;
|
| 269 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 270 |
}
|
| 271 |
</style>
|
| 272 |
""",
|
|
@@ -377,10 +466,14 @@ if "messages" not in st.session_state:
|
|
| 377 |
if "conversation_started" not in st.session_state:
|
| 378 |
st.session_state.conversation_started = False
|
| 379 |
|
| 380 |
-
# ----------
|
| 381 |
-
|
| 382 |
-
|
| 383 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 384 |
|
| 385 |
# ---------- WELCOME SCREEN OR CHAT ----------
|
| 386 |
if not st.session_state.conversation_started:
|
|
@@ -443,9 +536,21 @@ else:
|
|
| 443 |
st.markdown('<div class="chat-container">', unsafe_allow_html=True)
|
| 444 |
for msg in st.session_state.messages:
|
| 445 |
if msg["role"] == "user":
|
| 446 |
-
st.markdown(f'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 447 |
else:
|
| 448 |
-
st.markdown(f'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 449 |
st.markdown('</div>', unsafe_allow_html=True)
|
| 450 |
|
| 451 |
# ---------- USER INPUT ----------
|
|
@@ -459,26 +564,39 @@ st.session_state.conversation_started = True
|
|
| 459 |
|
| 460 |
# Add user message
|
| 461 |
st.session_state.messages.append({"role": "user", "content": user_query})
|
| 462 |
-
|
|
|
|
|
|
|
| 463 |
|
| 464 |
# ---------- RESPONSE LOGIC ----------
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
|
| 469 |
-
|
| 470 |
-
|
| 471 |
-
|
| 472 |
-
|
| 473 |
-
|
| 474 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 475 |
|
| 476 |
-
|
| 477 |
-
|
| 478 |
|
| 479 |
Evaluate if this knowledge base response adequately answers the user's question:
|
| 480 |
|
| 481 |
-
User Question: {
|
| 482 |
Knowledge Base Response: {str(kb_response)}
|
| 483 |
|
| 484 |
Decision criteria:
|
|
@@ -488,40 +606,55 @@ Decision criteria:
|
|
| 488 |
|
| 489 |
Reply with only: USE_KB or USE_WEB"""
|
| 490 |
|
| 491 |
-
|
| 492 |
-
model="gpt-4o",
|
| 493 |
-
messages=[{"role": "user", "content": decision_prompt}],
|
| 494 |
-
)
|
| 495 |
-
decision_text = decision.choices[0].message.content.strip()
|
| 496 |
-
|
| 497 |
-
if "USE_KB" in decision_text:
|
| 498 |
-
response_text = str(kb_response) + FOOTER_MESSAGE
|
| 499 |
-
else:
|
| 500 |
-
results = tavily.search(query=user_query, max_results=5)
|
| 501 |
-
web_results_list = results.get("results", [])
|
| 502 |
-
web_results = "\n".join([
|
| 503 |
-
f"• **{r['title']}** — {r['url']}\n {r.get('content', '')[:300]}..."
|
| 504 |
-
for r in web_results_list
|
| 505 |
-
])
|
| 506 |
-
prompt = WEB_SEARCH_PROMPT.format(query=user_query, web_results=web_results)
|
| 507 |
-
|
| 508 |
-
stream = client.chat.completions.create(
|
| 509 |
model="gpt-4o",
|
| 510 |
-
messages=[
|
| 511 |
-
{"role": "system", "content": SYSTEM_INSTRUCTION},
|
| 512 |
-
{"role": "user", "content": prompt}
|
| 513 |
-
],
|
| 514 |
-
stream=True
|
| 515 |
)
|
|
|
|
| 516 |
|
| 517 |
-
|
| 518 |
-
|
| 519 |
-
|
| 520 |
-
|
| 521 |
-
|
| 522 |
-
|
| 523 |
-
|
| 524 |
-
|
| 525 |
-
|
| 526 |
-
|
| 527 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
.stApp {
|
| 34 |
max-width: 900px;
|
| 35 |
margin: 0 auto;
|
| 36 |
+
padding-top: 100px !important;
|
| 37 |
}
|
| 38 |
|
| 39 |
+
/* Fixed Header Container */
|
| 40 |
+
.fixed-header {
|
| 41 |
+
position: fixed;
|
| 42 |
+
top: 0;
|
| 43 |
+
left: 0;
|
| 44 |
+
right: 0;
|
| 45 |
+
background-color: #FFFFFF;
|
| 46 |
+
z-index: 999;
|
| 47 |
+
border-bottom: 1px solid #E5E7EB;
|
| 48 |
+
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
| 49 |
+
padding: 15px 0;
|
| 50 |
}
|
| 51 |
|
| 52 |
+
.header-content {
|
| 53 |
+
max-width: 900px;
|
| 54 |
+
margin: 0 auto;
|
| 55 |
+
display: flex;
|
| 56 |
+
justify-content: center;
|
| 57 |
+
align-items: center;
|
| 58 |
+
padding: 0 20px;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
.header-logo {
|
| 62 |
+
height: 50px;
|
| 63 |
+
width: auto;
|
| 64 |
+
object-fit: contain;
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
/* Trust Header - only on welcome screen */
|
| 68 |
.trust-header {
|
| 69 |
font-family: 'Titillium Web', sans-serif;
|
| 70 |
text-align: center;
|
|
|
|
| 168 |
border-top: 1px solid #E5E7EB;
|
| 169 |
padding-top: 1rem;
|
| 170 |
margin-top: 2rem;
|
| 171 |
+
background-color: #FFFFFF;
|
| 172 |
}
|
| 173 |
|
| 174 |
.stChatInput > div {
|
|
|
|
| 190 |
color: #9CA3AF !important;
|
| 191 |
}
|
| 192 |
|
| 193 |
+
/* Chat messages container */
|
| 194 |
.chat-container {
|
| 195 |
+
margin-top: 1rem;
|
| 196 |
+
padding-bottom: 2rem;
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
/* Message row with avatar */
|
| 200 |
+
.message-row {
|
| 201 |
+
display: flex;
|
| 202 |
+
align-items: flex-start;
|
| 203 |
+
margin: 1rem 0;
|
| 204 |
+
gap: 12px;
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
.message-row.user {
|
| 208 |
+
flex-direction: row-reverse;
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
/* Avatar styling */
|
| 212 |
+
.avatar {
|
| 213 |
+
width: 40px;
|
| 214 |
+
height: 40px;
|
| 215 |
+
border-radius: 50%;
|
| 216 |
+
flex-shrink: 0;
|
| 217 |
+
display: flex;
|
| 218 |
+
align-items: center;
|
| 219 |
+
justify-content: center;
|
| 220 |
+
overflow: hidden;
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
.avatar.bot {
|
| 224 |
+
background-color: #FFFFFF;
|
| 225 |
+
border: 2px solid #E5E7EB;
|
| 226 |
+
padding: 4px;
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
.avatar.bot img {
|
| 230 |
+
width: 100%;
|
| 231 |
+
height: 100%;
|
| 232 |
+
object-fit: contain;
|
| 233 |
}
|
| 234 |
|
| 235 |
+
.avatar.user {
|
| 236 |
+
background-color: #10A37F;
|
| 237 |
+
color: white;
|
| 238 |
+
font-weight: 600;
|
| 239 |
+
font-size: 16px;
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
/* Message bubbles */
|
| 243 |
.user-message {
|
| 244 |
background-color: #F3F4F6;
|
| 245 |
padding: 1rem 1.25rem;
|
| 246 |
border-radius: 18px;
|
| 247 |
+
max-width: 75%;
|
|
|
|
|
|
|
| 248 |
font-family: 'Titillium Web', sans-serif;
|
| 249 |
+
line-height: 1.5;
|
| 250 |
}
|
| 251 |
|
| 252 |
.bot-message {
|
| 253 |
background-color: #FFFFFF;
|
| 254 |
padding: 1rem 1.25rem;
|
| 255 |
border-radius: 18px;
|
| 256 |
+
max-width: 75%;
|
|
|
|
| 257 |
border: 1px solid #E5E7EB;
|
| 258 |
font-family: 'Titillium Web', sans-serif;
|
| 259 |
+
line-height: 1.5;
|
| 260 |
}
|
| 261 |
|
| 262 |
/* Submit button styling */
|
|
|
|
| 311 |
|
| 312 |
/* Mobile responsive */
|
| 313 |
@media screen and (max-width: 600px) {
|
| 314 |
+
.stApp {
|
| 315 |
+
padding-top: 80px !important;
|
| 316 |
+
}
|
| 317 |
+
|
| 318 |
+
.fixed-header {
|
| 319 |
+
padding: 10px 0;
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
.header-logo {
|
| 323 |
+
height: 40px;
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
.trust-header {
|
| 327 |
font-size: 26px;
|
| 328 |
}
|
|
|
|
| 347 |
.prompt-subtitle {
|
| 348 |
font-size: 0.85rem;
|
| 349 |
}
|
| 350 |
+
|
| 351 |
+
.user-message, .bot-message {
|
| 352 |
+
max-width: 85%;
|
| 353 |
+
}
|
| 354 |
+
|
| 355 |
+
.avatar {
|
| 356 |
+
width: 32px;
|
| 357 |
+
height: 32px;
|
| 358 |
+
}
|
| 359 |
}
|
| 360 |
</style>
|
| 361 |
""",
|
|
|
|
| 466 |
if "conversation_started" not in st.session_state:
|
| 467 |
st.session_state.conversation_started = False
|
| 468 |
|
| 469 |
+
# ---------- FIXED HEADER ----------
|
| 470 |
+
st.markdown("""
|
| 471 |
+
<div class="fixed-header">
|
| 472 |
+
<div class="header-content">
|
| 473 |
+
<img src="https://raw.githubusercontent.com/yourusername/yourrepo/main/Trust%20Logic%20Logo_RGB_Standard.png" class="header-logo" alt="TrustLogic">
|
| 474 |
+
</div>
|
| 475 |
+
</div>
|
| 476 |
+
""", unsafe_allow_html=True)
|
| 477 |
|
| 478 |
# ---------- WELCOME SCREEN OR CHAT ----------
|
| 479 |
if not st.session_state.conversation_started:
|
|
|
|
| 536 |
st.markdown('<div class="chat-container">', unsafe_allow_html=True)
|
| 537 |
for msg in st.session_state.messages:
|
| 538 |
if msg["role"] == "user":
|
| 539 |
+
st.markdown(f'''
|
| 540 |
+
<div class="message-row user">
|
| 541 |
+
<div class="avatar user">U</div>
|
| 542 |
+
<div class="user-message">{msg["content"]}</div>
|
| 543 |
+
</div>
|
| 544 |
+
''', unsafe_allow_html=True)
|
| 545 |
else:
|
| 546 |
+
st.markdown(f'''
|
| 547 |
+
<div class="message-row bot">
|
| 548 |
+
<div class="avatar bot">
|
| 549 |
+
<img src="https://raw.githubusercontent.com/yourusername/yourrepo/main/Trust%20Logic%20Logo_RGB_Standard.png" alt="TrustLogic">
|
| 550 |
+
</div>
|
| 551 |
+
<div class="bot-message">{msg["content"]}</div>
|
| 552 |
+
</div>
|
| 553 |
+
''', unsafe_allow_html=True)
|
| 554 |
st.markdown('</div>', unsafe_allow_html=True)
|
| 555 |
|
| 556 |
# ---------- USER INPUT ----------
|
|
|
|
| 564 |
|
| 565 |
# Add user message
|
| 566 |
st.session_state.messages.append({"role": "user", "content": user_query})
|
| 567 |
+
|
| 568 |
+
# Rerun to hide welcome screen
|
| 569 |
+
st.rerun()
|
| 570 |
|
| 571 |
# ---------- RESPONSE LOGIC ----------
|
| 572 |
+
if st.session_state.conversation_started and len(st.session_state.messages) > 0:
|
| 573 |
+
# Display the latest user message
|
| 574 |
+
latest_user_msg = [msg for msg in st.session_state.messages if msg["role"] == "user"][-1]
|
| 575 |
+
|
| 576 |
+
st.markdown(f'''
|
| 577 |
+
<div class="message-row user">
|
| 578 |
+
<div class="avatar user">U</div>
|
| 579 |
+
<div class="user-message">{latest_user_msg["content"]}</div>
|
| 580 |
+
</div>
|
| 581 |
+
''', unsafe_allow_html=True)
|
| 582 |
+
|
| 583 |
+
response_text = ""
|
| 584 |
+
placeholder = st.empty()
|
| 585 |
+
|
| 586 |
+
with st.spinner("Analyzing with TrustLogic intelligence..."):
|
| 587 |
+
# Knowledge base query
|
| 588 |
+
kb_query_engine = index.as_query_engine(
|
| 589 |
+
similarity_top_k=5,
|
| 590 |
+
text_qa_template=KB_PROMPT_TEMPLATE
|
| 591 |
+
)
|
| 592 |
+
kb_response = kb_query_engine.query(latest_user_msg["content"])
|
| 593 |
|
| 594 |
+
# Decide if KB is enough or use web search
|
| 595 |
+
decision_prompt = f"""{SYSTEM_INSTRUCTION}
|
| 596 |
|
| 597 |
Evaluate if this knowledge base response adequately answers the user's question:
|
| 598 |
|
| 599 |
+
User Question: {latest_user_msg["content"]}
|
| 600 |
Knowledge Base Response: {str(kb_response)}
|
| 601 |
|
| 602 |
Decision criteria:
|
|
|
|
| 606 |
|
| 607 |
Reply with only: USE_KB or USE_WEB"""
|
| 608 |
|
| 609 |
+
decision = client.chat.completions.create(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 610 |
model="gpt-4o",
|
| 611 |
+
messages=[{"role": "user", "content": decision_prompt}],
|
|
|
|
|
|
|
|
|
|
|
|
|
| 612 |
)
|
| 613 |
+
decision_text = decision.choices[0].message.content.strip()
|
| 614 |
|
| 615 |
+
if "USE_KB" in decision_text:
|
| 616 |
+
response_text = str(kb_response) + FOOTER_MESSAGE
|
| 617 |
+
else:
|
| 618 |
+
results = tavily.search(query=latest_user_msg["content"], max_results=5)
|
| 619 |
+
web_results_list = results.get("results", [])
|
| 620 |
+
web_results = "\n".join([
|
| 621 |
+
f"• **{r['title']}** — {r['url']}\n {r.get('content', '')[:300]}..."
|
| 622 |
+
for r in web_results_list
|
| 623 |
+
])
|
| 624 |
+
prompt = WEB_SEARCH_PROMPT.format(query=latest_user_msg["content"], web_results=web_results)
|
| 625 |
+
|
| 626 |
+
stream = client.chat.completions.create(
|
| 627 |
+
model="gpt-4o",
|
| 628 |
+
messages=[
|
| 629 |
+
{"role": "system", "content": SYSTEM_INSTRUCTION},
|
| 630 |
+
{"role": "user", "content": prompt}
|
| 631 |
+
],
|
| 632 |
+
stream=True
|
| 633 |
+
)
|
| 634 |
+
|
| 635 |
+
for chunk in stream:
|
| 636 |
+
if chunk.choices[0].delta.content:
|
| 637 |
+
token = chunk.choices[0].delta.content
|
| 638 |
+
response_text += token
|
| 639 |
+
placeholder.markdown(f'''
|
| 640 |
+
<div class="message-row bot">
|
| 641 |
+
<div class="avatar bot">
|
| 642 |
+
<img src="https://raw.githubusercontent.com/yourusername/yourrepo/main/Trust%20Logic%20Logo_RGB_Standard.png" alt="TrustLogic">
|
| 643 |
+
</div>
|
| 644 |
+
<div class="bot-message">{response_text}▌</div>
|
| 645 |
+
</div>
|
| 646 |
+
''', unsafe_allow_html=True)
|
| 647 |
+
|
| 648 |
+
if "trustlogic.center" not in response_text.lower():
|
| 649 |
+
response_text += FOOTER_MESSAGE
|
| 650 |
+
|
| 651 |
+
placeholder.markdown(f'''
|
| 652 |
+
<div class="message-row bot">
|
| 653 |
+
<div class="avatar bot">
|
| 654 |
+
<img src="https://raw.githubusercontent.com/yourusername/yourrepo/main/Trust%20Logic%20Logo_RGB_Standard.png" alt="TrustLogic">
|
| 655 |
+
</div>
|
| 656 |
+
<div class="bot-message">{response_text}</div>
|
| 657 |
+
</div>
|
| 658 |
+
''', unsafe_allow_html=True)
|
| 659 |
+
|
| 660 |
+
st.session_state.messages.append({"role": "assistant", "content": response_text})
|