File size: 4,559 Bytes
03291e0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import os
from dotenv import load_dotenv
from langchain_groq import ChatGroq

load_dotenv()

llm = ChatGroq(
    model_name="llama-3.3-70b-versatile",
    groq_api_key=os.getenv("GROQ_API_KEY"),
    temperature=0.3
)


def generate_answer(question, retrieved_chunks, language="arabic",

                     recent_history=None, conversation_summary=None):
    """

    Generates the final answer using Groq, grounded in retrieved

    document chunks and aware of conversation context.



    recent_history: list of the last 1-2 (question, answer) tuples,

                     kept in full detail

    conversation_summary: short summary of everything OLDER than

                     the recent history, kept compact

    """

    context = "\n\n".join(retrieved_chunks)

    history_text = ""
    if conversation_summary:
        history_text += f"Summary of earlier conversation:\n{conversation_summary}\n\n"
    if recent_history:
        history_text += "Most recent exchange(s):\n"
        for past_question, past_answer in recent_history:
            history_text += f"Q: {past_question}\nA: {past_answer}\n\n"

    if language == "arabic":
        prompt = f"""أنت مساعد ذكي متخصص في الإجابة على الأسئلة بناءً على النص المعطى فقط.



{history_text if history_text else ""}



السياق المتاح من الوثيقة:

{context}



السؤال الحالي:

{question}



التعليمات:

- أجب باللغة العربية فقط

- إذا كان السؤال يشير إلى محادثة سابقة (مثل "ذلك" أو "هذا")، استخدم ملخص المحادثة أو آخر تبادل لفهم المرجع

- استخدم فقط المعلومات الموجودة في السياق أعلاه

- لا تضف أي معلومات غير موجودة في الوثيقة، حتى لو كانت معلومات عامة صحيحة

- إذا لم تجد الإجابة، قل بوضوح أنك لا تملك معلومات كافية



الإجابة:"""
    else:
        prompt = f"""You are a helpful assistant that answers questions based on the provided document context.



{history_text if history_text else ""}



Document context (in Arabic):

{context}



Current question:

{question}



Instructions:

- Answer ONLY in English

- If the question refers to earlier conversation (like "that" or "it"), use the summary or recent exchange to understand the reference

- Use the information found in the context above

- If the answer is not in the context, clearly say you don't have enough information

- Don't give information which is not in the PDF if something is not there in the PDF simply say you don't have enough information



Answer:"""

    response = llm.invoke(prompt)
    return response.content


def translate_to_arabic(english_text):
    """

    Translates an English question into Arabic using Groq,

    so we can search our all-Arabic vector store accurately.

    This fixes cross-lingual retrieval failures on larger,

    more complex documents.

    """
    prompt = f"""Translate the following English question into Modern Standard Arabic.

Only output the Arabic translation, nothing else - no explanation, no quotes.



English: {english_text}



Arabic translation:"""

    response = llm.invoke(prompt)
    return response.content.strip()


def summarize_conversation(existing_summary, old_question, old_answer):
    """

    Takes the current running summary plus one older exchange

    that's about to fall out of the "recent" window, and asks

    Groq to fold it into an updated, still-short summary.



    This keeps conversation memory compact regardless of how

    long the chat gets, instead of sending the full raw history

    every time.

    """
    prompt = f"""You are maintaining a brief running summary of a conversation between a user and an assistant about a document.



Existing summary so far:

{existing_summary if existing_summary else "(no summary yet - this is the first exchange to summarize)"}



New exchange to fold in:

User asked: {old_question}

Assistant answered: {old_answer}



Update the summary to include this new exchange, staying concise.

Keep it to 2-4 sentences maximum. Focus on WHAT TOPICS were discussed

and any specific facts/numbers that might be referenced later, not

the exact wording. Output ONLY the updated summary, nothing else.



Updated summary:"""

    response = llm.invoke(prompt)
    return response.content.strip()