(prompt_text: str, model: str)
| 533 | |
| 534 | # ─── Response generation ────────────────────────────────────────────────────── |
| 535 | def generate_response(prompt_text: str, model: str): |
| 536 | chat_history = "\n".join( |
| 537 | f"{m['role'].capitalize()}: {m['content']}" |
| 538 | for m in st.session_state.messages[-6:] |
| 539 | ) |
| 540 | |
| 541 | # ── RAG retrieval ── |
| 542 | context = "" |
| 543 | sources = [] |
| 544 | if st.session_state.rag_enabled and st.session_state.retrieval_pipeline: |
| 545 | try: |
| 546 | docs = retrieve_documents(prompt_text, OLLAMA_API_URL, model, chat_history) |
| 547 | sources = [doc.page_content for doc in docs] |
| 548 | context = "\n\n".join(f"[Source {i+1}]:\n{doc.page_content}" for i, doc in enumerate(docs)) |
| 549 | except Exception as e: |
| 550 | st.warning(f"Retrieval error: {e}") |
| 551 | elif st.session_state.rag_enabled: |
| 552 | st.info("Upload documents in the sidebar to enable RAG retrieval.") |
| 553 | |
| 554 | # ── CRAG relevance feedback ── |
| 555 | crag = st.session_state.get("_crag_status") |
| 556 | crag_low = False |
| 557 | if crag: |
| 558 | status, kept, total = crag |
| 559 | if status == "ok": |
| 560 | st.markdown( |
| 561 | f'<span class="status-badge status-ok">✅ CRAG: {kept}/{total} sources relevant</span>', |
| 562 | unsafe_allow_html=True) |
| 563 | else: |
| 564 | crag_low = True |
| 565 | st.markdown( |
| 566 | '<span class="status-badge status-err">⚠️ CRAG: no clearly relevant sources — answering with low confidence</span>', |
| 567 | unsafe_allow_html=True) |
| 568 | |
| 569 | # ── Build prompt ── |
| 570 | ctx_block = f"\nContext:\n{context}\n" if context else "" |
| 571 | ctx_instruction = ( |
| 572 | "\n- Answer based on the provided context. Cite [Source N] when referencing specific info." |
| 573 | if context else "" |
| 574 | ) |
| 575 | |
| 576 | show_thinking = st.session_state.get("enable_thinking", True) |
| 577 | |
| 578 | if show_thinking: |
| 579 | think_instruction = ( |
| 580 | "Before answering, reason through the problem step by step inside <think>...</think> tags. " |
| 581 | "Then give your final answer outside those tags.\n\n" |
| 582 | ) |
| 583 | else: |
| 584 | think_instruction = "" |
| 585 | |
| 586 | system_prompt = ( |
| 587 | f"{think_instruction}" |
| 588 | f"You are a helpful, thorough AI assistant.\n\n" |
| 589 | f"Chat History:\n{chat_history}\n" |
| 590 | f"{ctx_block}" |
| 591 | f"Question: {prompt_text}\n\n" |
| 592 | f"Instructions:\n" |
no test coverage detected