Sync backend Docker context from GitHub main
Browse files- backend/routes/predict_stream.py +1 -1
- retriever/generator.py +27 -5
backend/routes/predict_stream.py
CHANGED
|
@@ -100,7 +100,7 @@ def predict_stream(payload: PredictRequest) -> StreamingResponse:
|
|
| 100 |
yield to_ndjson({"type": "token", "token": token})
|
| 101 |
|
| 102 |
inference_time = time.perf_counter() - inference_start
|
| 103 |
-
answer = "".join(answer_parts)
|
| 104 |
retrieved_chunks = build_retrieved_chunks(contexts=contexts, chunk_lookup=chunk_lookup)
|
| 105 |
|
| 106 |
yield to_ndjson(
|
|
|
|
| 100 |
yield to_ndjson({"type": "token", "token": token})
|
| 101 |
|
| 102 |
inference_time = time.perf_counter() - inference_start
|
| 103 |
+
answer = rag_engine.truncate_incomplete_tail("".join(answer_parts))
|
| 104 |
retrieved_chunks = build_retrieved_chunks(contexts=contexts, chunk_lookup=chunk_lookup)
|
| 105 |
|
| 106 |
yield to_ndjson(
|
retriever/generator.py
CHANGED
|
@@ -1,7 +1,29 @@
|
|
| 1 |
#changed the prompt to output as markdown, plus some formating details
|
| 2 |
#also added get answer stream for incremental token rendering on the frontend
|
| 3 |
# --@Qamar
|
|
|
|
|
|
|
|
|
|
| 4 |
class RAGGenerator:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
def generate_prompt(self, query, retrieved_contexts, context_urls=None):
|
| 6 |
if context_urls:
|
| 7 |
context_text = "\n\n".join([f"[Source {i+1}] {url}: {c}" for i, (c, url) in enumerate(zip(retrieved_contexts, context_urls))])
|
|
@@ -14,9 +36,8 @@ INSTRUCTIONS:
|
|
| 14 |
1. THERAPEUTIC DIALOGUE: Respond directly to the user as your client. Start by briefly validating their feelings, then gently apply CBT concepts, psychoeducation, or interventions found STRICTLY in the provided documents.
|
| 15 |
2. PATIENT EXAMPLES & NAMES (CRITICAL): The provided documents contain transcripts and examples of other patients and therapists (e.g., Abe, Judith, Joseph). These are illustrative case studies ONLY. DO NOT assume the user is "Abe" or any other person mentioned in the text. NEVER address or refer to the user by these names. Extract the CBT concepts/techniques demonstrated in these transcripts and apply them to the current user's unique situation.
|
| 16 |
3. GROUNDING (NO OPINIONS): Do not give your own opinions, general life advice, or use outside knowledge. Every therapeutic concept, identified cognitive distortion, or suggested exercise must come directly from the provided text.
|
| 17 |
-
4.
|
| 18 |
-
5.
|
| 19 |
-
6. MISSING INFO: If the provided excerpts do not contain relevant CBT concepts to address the client's specific statement, explicitly state: "While I hear how difficult this is for you, the clinical materials I have right now do not contain specific steps to address this." Do not invent therapeutic advice.
|
| 20 |
|
| 21 |
RETRIEVED CLINICAL CONTEXT:
|
| 22 |
{context_text}
|
|
@@ -28,7 +49,8 @@ THERAPEUTIC RESPONSE (GROUNDED IN SOURCES):"""
|
|
| 28 |
def get_answer(self, model_instance, query, retrieved_contexts, context_urls=None, **kwargs):
|
| 29 |
"""Uses a specific model instance to generate the final answer."""
|
| 30 |
prompt = self.generate_prompt(query, retrieved_contexts, context_urls)
|
| 31 |
-
|
|
|
|
| 32 |
|
| 33 |
def get_answer_stream(self, model_instance, query, retrieved_contexts, context_urls=None, **kwargs):
|
| 34 |
"""Streams model output token-by-token for incremental UI updates."""
|
|
@@ -43,4 +65,4 @@ THERAPEUTIC RESPONSE (GROUNDED IN SOURCES):"""
|
|
| 43 |
# Fallback for model wrappers that only expose sync generation.
|
| 44 |
answer = model_instance.generate(prompt, **kwargs)
|
| 45 |
if answer:
|
| 46 |
-
yield answer
|
|
|
|
| 1 |
#changed the prompt to output as markdown, plus some formating details
|
| 2 |
#also added get answer stream for incremental token rendering on the frontend
|
| 3 |
# --@Qamar
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
# called in get_answer_stream, to truncate to last full stop
|
| 7 |
class RAGGenerator:
|
| 8 |
+
def truncate_incomplete_tail(self, answer: str) -> str:
|
| 9 |
+
"""Trim incomplete trailing text so responses end on a full stop."""
|
| 10 |
+
if not answer:
|
| 11 |
+
return answer
|
| 12 |
+
|
| 13 |
+
trimmed = answer.rstrip()
|
| 14 |
+
if not trimmed:
|
| 15 |
+
return trimmed
|
| 16 |
+
|
| 17 |
+
if trimmed.endswith("."):
|
| 18 |
+
return trimmed
|
| 19 |
+
|
| 20 |
+
last_full_stop = trimmed.rfind(".")
|
| 21 |
+
if last_full_stop == -1:
|
| 22 |
+
# If no sentence boundary exists, keep original text.
|
| 23 |
+
return trimmed
|
| 24 |
+
|
| 25 |
+
return trimmed[: last_full_stop + 1].rstrip()
|
| 26 |
+
|
| 27 |
def generate_prompt(self, query, retrieved_contexts, context_urls=None):
|
| 28 |
if context_urls:
|
| 29 |
context_text = "\n\n".join([f"[Source {i+1}] {url}: {c}" for i, (c, url) in enumerate(zip(retrieved_contexts, context_urls))])
|
|
|
|
| 36 |
1. THERAPEUTIC DIALOGUE: Respond directly to the user as your client. Start by briefly validating their feelings, then gently apply CBT concepts, psychoeducation, or interventions found STRICTLY in the provided documents.
|
| 37 |
2. PATIENT EXAMPLES & NAMES (CRITICAL): The provided documents contain transcripts and examples of other patients and therapists (e.g., Abe, Judith, Joseph). These are illustrative case studies ONLY. DO NOT assume the user is "Abe" or any other person mentioned in the text. NEVER address or refer to the user by these names. Extract the CBT concepts/techniques demonstrated in these transcripts and apply them to the current user's unique situation.
|
| 38 |
3. GROUNDING (NO OPINIONS): Do not give your own opinions, general life advice, or use outside knowledge. Every therapeutic concept, identified cognitive distortion, or suggested exercise must come directly from the provided text.
|
| 39 |
+
4. FORMAT: Use clear Markdown formatting. Use paragraphs for conversational tone, and bullet points if you are breaking down specific steps, questions, or exercises found in the text.
|
| 40 |
+
5. MISSING INFO: If the provided excerpts do not contain relevant CBT concepts to address the client's specific statement, explicitly state: "While I hear how difficult this is for you, the clinical materials I have right now do not contain specific steps to address this." Do not invent therapeutic advice.
|
|
|
|
| 41 |
|
| 42 |
RETRIEVED CLINICAL CONTEXT:
|
| 43 |
{context_text}
|
|
|
|
| 49 |
def get_answer(self, model_instance, query, retrieved_contexts, context_urls=None, **kwargs):
|
| 50 |
"""Uses a specific model instance to generate the final answer."""
|
| 51 |
prompt = self.generate_prompt(query, retrieved_contexts, context_urls)
|
| 52 |
+
answer = model_instance.generate(prompt, **kwargs)
|
| 53 |
+
return self.truncate_incomplete_tail(answer)
|
| 54 |
|
| 55 |
def get_answer_stream(self, model_instance, query, retrieved_contexts, context_urls=None, **kwargs):
|
| 56 |
"""Streams model output token-by-token for incremental UI updates."""
|
|
|
|
| 65 |
# Fallback for model wrappers that only expose sync generation.
|
| 66 |
answer = model_instance.generate(prompt, **kwargs)
|
| 67 |
if answer:
|
| 68 |
+
yield self.truncate_incomplete_tail(answer)
|