HemanM commited on
Commit
45789c8
·
verified ·
1 Parent(s): 6a117f9

Create evo_inference.py

Browse files
Files changed (1) hide show
  1. evo_inference.py +40 -93
evo_inference.py CHANGED
@@ -1,96 +1,40 @@
1
  """
2
- evo_inference.py
3
- Step 8: Evo-ready synthesis with plugin support + safe fallback.
4
-
5
- (Objective)
6
- - Try to import your real Evo plugin: `evo_plugin.load_model()`.
7
- - If not present, fall back to `evo_plugin_example.load_model()`.
8
- - Provide `synthesize_with_evo(...)` that builds a grounded prompt from retrieved hits
9
- and either:
10
- a) calls the generator (generative mode), or
11
- b) returns a clean extractive answer (safe mode).
12
  """
13
 
14
- from typing import List, Dict, Optional
15
  from utils_lang import L, normalize_lang
16
 
17
- # Try to load your real Evo plugin first; else example plugin
18
  _GENERATOR = None
19
  try:
20
- from evo_plugin import load_model as _load_real # your file (optional)
21
  _GENERATOR = _load_real()
22
  except Exception:
23
  try:
24
  from evo_plugin_example import load_model as _load_example
25
  _GENERATOR = _load_example()
26
  except Exception:
27
- _GENERATOR = None # fallback to extractive-only
28
-
29
- MAX_SNIPPET_CHARS = 400 # (Objective) keep context concise
30
 
 
31
 
32
  def _snippet(text: str) -> str:
33
  text = " ".join(text.split())
34
  return text[:MAX_SNIPPET_CHARS] + ("..." if len(text) > MAX_SNIPPET_CHARS else "")
35
 
36
-
37
- def _build_grounded_prompt(question: str, lang: str, hits: List[Dict]) -> str:
38
- """
39
- (Objective) Construct a compact prompt that includes:
40
- - role + response style instruction (language-aware),
41
- - the user's question,
42
- - the top retrieved chunks as "Context #i".
43
- """
44
- lang = normalize_lang(lang)
45
- if lang == "fr":
46
- system = (
47
- "Tu es le Copilote Gouvernemental de Maurice. Réponds dans la langue demandée, "
48
- "clairement et étape par étape, en te basant STRICTEMENT sur le contexte. "
49
- "Inclure: documents requis, frais, où postuler, délais. Si une info manque, dis-le."
50
- )
51
- elif lang == "mfe":
52
- system = (
53
- "To enn Copilot Gouv Moris. Reponn dan langaz itilizater, kler ek pas-a-pas, "
54
- "bas lor KI SUIVAN. Met: ki dokiman bizin, fre, kot pou al, delai. "
55
- "Si pa ase info, dir li."
56
- )
57
- else:
58
- system = (
59
- "You are the Mauritius Government Copilot. Answer in the user's language, "
60
- "clearly and step-by-step, using ONLY the provided context. Include: required documents, "
61
- "fees, where to apply, processing time. If something is missing, say so."
62
- )
63
-
64
- ctx_lines = []
65
- for i, h in enumerate(hits[:6], 1):
66
- ctx_lines.append(f"[Context #{i}] { _snippet(h['text']) }")
67
-
68
- ctx_block = "\n".join(ctx_lines) if ctx_lines else "[Context] (none)"
69
- prompt = (
70
- f"{system}\n\n"
71
- f"[Question]\n{question}\n\n"
72
- f"{ctx_block}\n\n"
73
- f"[Instructions]\n"
74
- f"- Be concise (6–10 lines).\n"
75
- f"- Use bullet steps.\n"
76
- f"- Do not invent links or fees; mention if unknown.\n"
77
- f"- Answer in language code: {lang}.\n"
78
- f"[Answer]\n"
79
- )
80
- return prompt
81
-
82
-
83
  def _extractive_answer(user_query: str, lang: str, hits: List[Dict]) -> str:
84
- """
85
- (Objective) The safe fallback: bullet points from hits + standard steps.
86
- """
87
  if not hits:
88
  return L(lang, "intro_err")
89
-
90
- bullets = []
91
- for h in hits[:4]:
92
- bullets.append(f"- {_snippet(h['text'])}")
93
-
94
  steps = {
95
  "en": [
96
  "• Step 1: Check eligibility & gather required documents.",
@@ -111,46 +55,49 @@ def _extractive_answer(user_query: str, lang: str, hits: List[Dict]) -> str:
111
  "• Step 4: Gard referans/reso; swiv letan tretman.",
112
  ],
113
  }[normalize_lang(lang)]
114
-
115
- md = (
116
  f"**{L(lang, 'intro_ok')}**\n\n"
117
  f"**Q:** {user_query}\n\n"
118
  f"**Key information:**\n" + "\n".join(bullets) + "\n\n"
119
  f"**Suggested steps:**\n" + "\n".join(steps)
120
  )
121
- return md
122
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
  def synthesize_with_evo(
125
  user_query: str,
126
  lang: str,
127
  hits: List[Dict],
128
- mode: str = "extractive", # "extractive" | "generative"
129
  max_new_tokens: int = 192,
130
  temperature: float = 0.4,
131
  ) -> str:
132
- """
133
- (Objective)
134
- - If mode == 'generative' and a generator is available, build a grounded prompt and generate.
135
- - Else, return the safe extractive answer.
136
- """
137
  lang = normalize_lang(lang)
138
-
139
  if mode != "generative" or _GENERATOR is None:
140
  return _extractive_answer(user_query, lang, hits)
141
-
142
  prompt = _build_grounded_prompt(user_query, lang, hits)
143
  try:
144
- text = _GENERATOR.generate(
145
- prompt=prompt,
146
- max_new_tokens=int(max_new_tokens),
147
- temperature=float(temperature),
148
- )
149
- # In case the generator echos or misses structure, still return something readable
150
- text = text.strip()
151
- if not text:
152
- return _extractive_answer(user_query, lang, hits)
153
- return text
154
  except Exception:
155
- # Any runtime issue falls back to safe mode
156
  return _extractive_answer(user_query, lang, hits)
 
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(...) now accepts mode/temp/max_tokens from the UI.
 
 
10
  """
11
 
12
+ from typing import List, Dict
13
  from utils_lang import L, normalize_lang
14
 
15
+ # Try to load your real Evo plugin first; else use the example; else None.
16
  _GENERATOR = None
17
  try:
18
+ from evo_plugin import load_model as _load_real # <- your future file (optional)
19
  _GENERATOR = _load_real()
20
  except Exception:
21
  try:
22
  from evo_plugin_example import load_model as _load_example
23
  _GENERATOR = _load_example()
24
  except Exception:
25
+ _GENERATOR = None # no generator available
 
 
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": [
40
  "• Step 1: Check eligibility & gather required documents.",
 
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)
68
+ if lang == "fr":
69
+ system = ("Tu es le Copilote Gouvernemental de Maurice. Réponds clairement, étape "
70
+ "par étape, en te basant UNIQUEMENT sur le contexte. Inclure: documents requis, "
71
+ "frais, où postuler, délais. Dire si une info manque.")
72
+ elif lang == "mfe":
73
+ system = ("To enn Copilot Gouv Moris. Reponn kler ek pas-a-pas, servi zis konteks ki donn. "
74
+ "Met: ki dokiman bizin, fre, kot pou al, delai. Dir si info manke.")
75
+ else:
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"
82
+ f"[Instructions]\n- Be concise (6–10 lines)\n- Use bullet steps\n"
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,
89
  hits: List[Dict],
90
+ mode: str = "extractive",
91
  max_new_tokens: int = 192,
92
  temperature: float = 0.4,
93
  ) -> str:
94
+ """If mode=='generative' and a generator exists, generate; else use extractive fallback."""
 
 
 
 
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(prompt, max_new_tokens=int(max_new_tokens), temperature=float(temperature))
101
+ return text.strip() or _extractive_answer(user_query, lang, hits)
 
 
 
 
 
 
 
 
102
  except Exception:
 
103
  return _extractive_answer(user_query, lang, hits)