Spaces:
Sleeping
Sleeping
Update evo_inference.py
Browse files- evo_inference.py +38 -7
evo_inference.py
CHANGED
@@ -1,12 +1,16 @@
|
|
1 |
"""
|
2 |
-
evo_inference.py — Step 8
|
3 |
Adds a GENERATIVE path using a small plugin (FLAN-T5 stand-in) while keeping the
|
4 |
old EXTRACTIVE fallback (bullet points) if generation isn't available.
|
5 |
|
|
|
|
|
|
|
|
|
6 |
How it works:
|
7 |
- We try to import your real evo plugin (evo_plugin.py). If not found, we load
|
8 |
evo_plugin_example.py instead. If both fail, we stay in extractive mode.
|
9 |
-
- synthesize_with_evo(...)
|
10 |
"""
|
11 |
|
12 |
from typing import List, Dict
|
@@ -26,14 +30,17 @@ except Exception:
|
|
26 |
|
27 |
MAX_SNIPPET_CHARS = 400
|
28 |
|
|
|
29 |
def _snippet(text: str) -> str:
|
30 |
text = " ".join(text.split())
|
31 |
return text[:MAX_SNIPPET_CHARS] + ("..." if len(text) > MAX_SNIPPET_CHARS else "")
|
32 |
|
|
|
33 |
def _extractive_answer(user_query: str, lang: str, hits: List[Dict]) -> str:
|
34 |
-
"""Old safe mode: show top snippets + standard steps."""
|
35 |
if not hits:
|
36 |
-
return L(lang, "intro_err")
|
|
|
37 |
bullets = [f"- {_snippet(h['text'])}" for h in hits[:4]]
|
38 |
steps = {
|
39 |
"en": [
|
@@ -55,13 +62,16 @@ def _extractive_answer(user_query: str, lang: str, hits: List[Dict]) -> str:
|
|
55 |
"• Step 4: Gard referans/reso; swiv letan tretman.",
|
56 |
],
|
57 |
}[normalize_lang(lang)]
|
|
|
58 |
return (
|
|
|
59 |
f"**{L(lang, 'intro_ok')}**\n\n"
|
60 |
f"**Q:** {user_query}\n\n"
|
61 |
f"**Key information:**\n" + "\n".join(bullets) + "\n\n"
|
62 |
f"**Suggested steps:**\n" + "\n".join(steps)
|
63 |
)
|
64 |
|
|
|
65 |
def _build_grounded_prompt(question: str, lang: str, hits: List[Dict]) -> str:
|
66 |
"""Create a compact prompt that includes the question + top retrieved snippets."""
|
67 |
lang = normalize_lang(lang)
|
@@ -76,6 +86,7 @@ def _build_grounded_prompt(question: str, lang: str, hits: List[Dict]) -> str:
|
|
76 |
system = ("You are the Mauritius Government Copilot. Answer clearly and step-by-step using "
|
77 |
"ONLY the provided context. Include: required documents, fees, where to apply, "
|
78 |
"processing time. State if anything is missing.")
|
|
|
79 |
ctx = "\n".join([f"[Context #{i+1}] {_snippet(h['text'])}" for i, h in enumerate(hits[:6])]) or "[Context] (none)"
|
80 |
return (
|
81 |
f"{system}\n\n[Question]\n{question}\n\n{ctx}\n\n"
|
@@ -83,6 +94,7 @@ def _build_grounded_prompt(question: str, lang: str, hits: List[Dict]) -> str:
|
|
83 |
f"- Do not invent links/fees\n- Answer in language code: {lang}\n[Answer]\n"
|
84 |
)
|
85 |
|
|
|
86 |
def synthesize_with_evo(
|
87 |
user_query: str,
|
88 |
lang: str,
|
@@ -91,13 +103,32 @@ def synthesize_with_evo(
|
|
91 |
max_new_tokens: int = 192,
|
92 |
temperature: float = 0.4,
|
93 |
) -> str:
|
94 |
-
"""
|
|
|
|
|
|
|
95 |
lang = normalize_lang(lang)
|
|
|
|
|
|
|
|
|
|
|
96 |
if mode != "generative" or _GENERATOR is None:
|
97 |
return _extractive_answer(user_query, lang, hits)
|
|
|
98 |
prompt = _build_grounded_prompt(user_query, lang, hits)
|
99 |
try:
|
100 |
-
text = _GENERATOR.generate(
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
except Exception:
|
|
|
103 |
return _extractive_answer(user_query, lang, hits)
|
|
|
1 |
"""
|
2 |
+
evo_inference.py — Step 8 (refined)
|
3 |
Adds a GENERATIVE path using a small plugin (FLAN-T5 stand-in) while keeping the
|
4 |
old EXTRACTIVE fallback (bullet points) if generation isn't available.
|
5 |
|
6 |
+
What's new in this refinement:
|
7 |
+
- Answers are explicitly labeled **[Generative]** or **[Extractive]** so you
|
8 |
+
can tell which path ran at a glance.
|
9 |
+
|
10 |
How it works:
|
11 |
- We try to import your real evo plugin (evo_plugin.py). If not found, we load
|
12 |
evo_plugin_example.py instead. If both fail, we stay in extractive mode.
|
13 |
+
- synthesize_with_evo(...) accepts mode/temp/max_tokens from the UI.
|
14 |
"""
|
15 |
|
16 |
from typing import List, Dict
|
|
|
30 |
|
31 |
MAX_SNIPPET_CHARS = 400
|
32 |
|
33 |
+
|
34 |
def _snippet(text: str) -> str:
|
35 |
text = " ".join(text.split())
|
36 |
return text[:MAX_SNIPPET_CHARS] + ("..." if len(text) > MAX_SNIPPET_CHARS else "")
|
37 |
|
38 |
+
|
39 |
def _extractive_answer(user_query: str, lang: str, hits: List[Dict]) -> str:
|
40 |
+
"""Old safe mode: show top snippets + standard steps, now labeled."""
|
41 |
if not hits:
|
42 |
+
return "**[Extractive]**\n\n" + L(lang, "intro_err")
|
43 |
+
|
44 |
bullets = [f"- {_snippet(h['text'])}" for h in hits[:4]]
|
45 |
steps = {
|
46 |
"en": [
|
|
|
62 |
"• Step 4: Gard referans/reso; swiv letan tretman.",
|
63 |
],
|
64 |
}[normalize_lang(lang)]
|
65 |
+
|
66 |
return (
|
67 |
+
"**[Extractive]**\n\n"
|
68 |
f"**{L(lang, 'intro_ok')}**\n\n"
|
69 |
f"**Q:** {user_query}\n\n"
|
70 |
f"**Key information:**\n" + "\n".join(bullets) + "\n\n"
|
71 |
f"**Suggested steps:**\n" + "\n".join(steps)
|
72 |
)
|
73 |
|
74 |
+
|
75 |
def _build_grounded_prompt(question: str, lang: str, hits: List[Dict]) -> str:
|
76 |
"""Create a compact prompt that includes the question + top retrieved snippets."""
|
77 |
lang = normalize_lang(lang)
|
|
|
86 |
system = ("You are the Mauritius Government Copilot. Answer clearly and step-by-step using "
|
87 |
"ONLY the provided context. Include: required documents, fees, where to apply, "
|
88 |
"processing time. State if anything is missing.")
|
89 |
+
|
90 |
ctx = "\n".join([f"[Context #{i+1}] {_snippet(h['text'])}" for i, h in enumerate(hits[:6])]) or "[Context] (none)"
|
91 |
return (
|
92 |
f"{system}\n\n[Question]\n{question}\n\n{ctx}\n\n"
|
|
|
94 |
f"- Do not invent links/fees\n- Answer in language code: {lang}\n[Answer]\n"
|
95 |
)
|
96 |
|
97 |
+
|
98 |
def synthesize_with_evo(
|
99 |
user_query: str,
|
100 |
lang: str,
|
|
|
103 |
max_new_tokens: int = 192,
|
104 |
temperature: float = 0.4,
|
105 |
) -> str:
|
106 |
+
"""
|
107 |
+
If mode=='generative' and a generator exists, generate a grounded answer
|
108 |
+
and label it **[Generative]**. Otherwise, return the labeled extractive fallback.
|
109 |
+
"""
|
110 |
lang = normalize_lang(lang)
|
111 |
+
|
112 |
+
# No retrieved context? Stay safe.
|
113 |
+
if not hits:
|
114 |
+
return _extractive_answer(user_query, lang, hits)
|
115 |
+
|
116 |
if mode != "generative" or _GENERATOR is None:
|
117 |
return _extractive_answer(user_query, lang, hits)
|
118 |
+
|
119 |
prompt = _build_grounded_prompt(user_query, lang, hits)
|
120 |
try:
|
121 |
+
text = _GENERATOR.generate(
|
122 |
+
prompt,
|
123 |
+
max_new_tokens=int(max_new_tokens),
|
124 |
+
temperature=float(temperature),
|
125 |
+
).strip()
|
126 |
+
|
127 |
+
if not text:
|
128 |
+
return _extractive_answer(user_query, lang, hits)
|
129 |
+
|
130 |
+
return "**[Generative]**\n\n" + text
|
131 |
+
|
132 |
except Exception:
|
133 |
+
# Any runtime issue falls back to safe mode
|
134 |
return _extractive_answer(user_query, lang, hits)
|