NoiwaDEX commited on
Commit
4a474b7
·
verified ·
1 Parent(s): 80b7807

Deploy SvaraSetu Docker Space

Browse files
svarasetu/engine.py CHANGED
@@ -1085,15 +1085,14 @@ class RAGPipelineOrchestrator:
1085
  stage="gemini_grounded",
1086
  ms=round((time.perf_counter() - polish_t) * 1000, 2),
1087
  success=False,
1088
- fallback_used=True,
1089
- details="Grounded Gemini abstained; trying an uncited open answer",
1090
  ))
1091
- return await self._finish_without_corpus(
1092
- request=request,
1093
  query=raw_query_text,
1094
  transcript=transcript,
1095
  language=target_lang,
1096
- reason=gen_details,
1097
  guardrails=guardrails,
1098
  timings=timings,
1099
  start_t=start_pipeline_t,
@@ -1374,10 +1373,9 @@ class RAGPipelineOrchestrator:
1374
  "UNSAFE_CONTENT",
1375
  "EMPTY_QUERY",
1376
  }
1377
- gemini_requested = bool(getattr(request, "gemini_enabled", False))
1378
  use_open = (
1379
- (getattr(config, "USE_GEMINI_OPEN", False) or gemini_requested)
1380
- and (getattr(config, "ALLOW_NETWORK_CALLS_IN_PIPELINE", False) or gemini_requested)
1381
  and gemini.configured
1382
  and not skip
1383
  and not blocked
 
1085
  stage="gemini_grounded",
1086
  ms=round((time.perf_counter() - polish_t) * 1000, 2),
1087
  success=False,
1088
+ fallback_used=False,
1089
+ details="Grounded Gemini abstained; refusing without using general knowledge",
1090
  ))
1091
+ return self._build_declined_response(
 
1092
  query=raw_query_text,
1093
  transcript=transcript,
1094
  language=target_lang,
1095
+ reason="The retrieved passages do not contain enough evidence to answer.",
1096
  guardrails=guardrails,
1097
  timings=timings,
1098
  start_t=start_pipeline_t,
 
1373
  "UNSAFE_CONTENT",
1374
  "EMPTY_QUERY",
1375
  }
 
1376
  use_open = (
1377
+ getattr(config, "USE_GEMINI_OPEN", False)
1378
+ and getattr(config, "ALLOW_NETWORK_CALLS_IN_PIPELINE", False)
1379
  and gemini.configured
1380
  and not skip
1381
  and not blocked
svarasetu/types.py CHANGED
@@ -67,7 +67,7 @@ class QueryRequest(BaseModel):
67
  cross_lingual: bool = False # Multilingual federation across all indexed corpora (default: False)
68
  bypass_cache: bool = False # Bypass semantic cache to measure cold-start retrieval latency
69
  bypass_gemini: bool = False # Force extractive path for the 200 ms SLA bench
70
- gemini_enabled: bool = False # Opt in to grounded polish and open answers on index miss
71
 
72
 
73
  class QueryResponse(BaseModel):
 
67
  cross_lingual: bool = False # Multilingual federation across all indexed corpora (default: False)
68
  bypass_cache: bool = False # Bypass semantic cache to measure cold-start retrieval latency
69
  bypass_gemini: bool = False # Force extractive path for the 200 ms SLA bench
70
+ gemini_enabled: bool = False # Opt in to Gemini synthesis using retrieved evidence only
71
 
72
 
73
  class QueryResponse(BaseModel):
svarasetu/web/index.html CHANGED
@@ -253,7 +253,7 @@
253
  <label class="setting-row"><span><strong>Save chat history</strong><small>Keep conversations on this device</small></span><input id="saveHistoryToggle" type="checkbox" checked /><i></i></label>
254
  <label class="setting-row"><span><strong>Automatic spoken answers</strong><small>Play verified answers after each request</small></span><input id="autoSpeakToggle" type="checkbox" /><i></i></label>
255
  <label class="setting-row"><span><strong>Cross-lingual retrieval</strong><small>Search across supported languages</small></span><input id="crossLingualToggle" type="checkbox" /><i></i></label>
256
- <label class="setting-row"><span><strong>Gemini answers</strong><small>Use Gemini with retrieved evidence, or answer from general knowledge when the index has no match</small></span><input id="geminiToggle" type="checkbox" /><i></i></label>
257
  </section>
258
  <section class="settings-group">
259
  <h3>Appearance</h3>
 
253
  <label class="setting-row"><span><strong>Save chat history</strong><small>Keep conversations on this device</small></span><input id="saveHistoryToggle" type="checkbox" checked /><i></i></label>
254
  <label class="setting-row"><span><strong>Automatic spoken answers</strong><small>Play verified answers after each request</small></span><input id="autoSpeakToggle" type="checkbox" /><i></i></label>
255
  <label class="setting-row"><span><strong>Cross-lingual retrieval</strong><small>Search across supported languages</small></span><input id="crossLingualToggle" type="checkbox" /><i></i></label>
256
+ <label class="setting-row"><span><strong>Gemini + RAG</strong><small>Let Gemini answer only from passages retrieved by your RAG index</small></span><input id="geminiToggle" type="checkbox" /><i></i></label>
257
  </section>
258
  <section class="settings-group">
259
  <h3>Appearance</h3>
tests/test_api.py CHANGED
@@ -108,6 +108,8 @@ def test_home_ui_and_styles(client):
108
  assert "ingestBtn" not in home.text
109
  assert "Evidence-backed answers across 15 indexed languages" not in home.text
110
  assert 'id="geminiToggle"' in home.text
 
 
111
  assert "lang-btn" not in home.text
112
  assert "Tap once. Then talk naturally." in home.text
113
  assert "SILENCE_STOP_MS" in home.text
 
108
  assert "ingestBtn" not in home.text
109
  assert "Evidence-backed answers across 15 indexed languages" not in home.text
110
  assert 'id="geminiToggle"' in home.text
111
+ assert "answer from general knowledge" not in home.text
112
+ assert "Gemini + RAG" in home.text
113
  assert "lang-btn" not in home.text
114
  assert "Tap once. Then talk naturally." in home.text
115
  assert "SILENCE_STOP_MS" in home.text
tests/test_gemini_quality.py CHANGED
@@ -1,11 +1,15 @@
1
  """Gemini quality layer: embed rerank + live client. No network."""
2
 
 
3
  import sys
 
4
  from pathlib import Path
5
 
6
  sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
7
 
8
  from svarasetu.compose.polish import GeminiClient, _cosine, get_gemini_client
 
 
9
 
10
 
11
  class TestCosine:
@@ -85,6 +89,32 @@ class TestGeminiOpen:
85
  )
86
  assert resp.answer_source == "gemini_open"
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
  class TestGeminiClientFactory:
90
  def test_unconfigured_without_key(self):
 
1
  """Gemini quality layer: embed rerank + live client. No network."""
2
 
3
+ import asyncio
4
  import sys
5
+ import time
6
  from pathlib import Path
7
 
8
  sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
9
 
10
  from svarasetu.compose.polish import GeminiClient, _cosine, get_gemini_client
11
+ from svarasetu.engine import RAGPipelineOrchestrator
12
+ from svarasetu.types import GuardrailFlags, QueryRequest
13
 
14
 
15
  class TestCosine:
 
89
  )
90
  assert resp.answer_source == "gemini_open"
91
 
92
+ def test_request_gemini_setting_never_enables_open_answers(self, monkeypatch):
93
+ class FakeGemini:
94
+ configured = True
95
+
96
+ def generate_open(self, *_args, **_kwargs):
97
+ raise AssertionError("open-domain Gemini must not run for the RAG toggle")
98
+
99
+ monkeypatch.setattr("svarasetu.engine.get_gemini_client", lambda: FakeGemini())
100
+ monkeypatch.setattr("svarasetu.engine.config.USE_GEMINI_OPEN", False)
101
+ monkeypatch.setattr("svarasetu.engine.config.ALLOW_NETWORK_CALLS_IN_PIPELINE", False)
102
+
103
+ pipeline = RAGPipelineOrchestrator.__new__(RAGPipelineOrchestrator)
104
+ response = asyncio.run(
105
+ pipeline._finish_without_corpus(
106
+ request=QueryRequest(text="Not in the index", gemini_enabled=True),
107
+ query="Not in the index",
108
+ transcript="Not in the index",
109
+ language="en",
110
+ reason="No indexed evidence",
111
+ guardrails=GuardrailFlags(decline_reason_code="LOW_RETRIEVAL_CONFIDENCE"),
112
+ timings=[],
113
+ start_t=time.perf_counter(),
114
+ )
115
+ )
116
+ assert response.answer_source == "declined"
117
+
118
 
119
  class TestGeminiClientFactory:
120
  def test_unconfigured_without_key(self):