omkarkudalkar222 commited on
Commit
f3310a2
·
1 Parent(s): fa364c7

fix: InternalCorpusProvider last_error; None novelty/cf scores crash report agent

Browse files
memory/graph_memory.py CHANGED
@@ -344,7 +344,7 @@ class GraphMemory(BaseMemory):
344
  concerns = r.get("concerns", []) or []
345
  strengths = r.get("strengths", []) or []
346
  lines = [
347
- f"Overall counterfactuality score: {r.get('overall_score', 0):.2f}/1.0",
348
  f"Most common type: {r.get('common_type', 'factual')}",
349
  f"Summary: {r.get('summary', '')}",
350
  ]
@@ -369,7 +369,7 @@ class GraphMemory(BaseMemory):
369
  for cr in claim_rows:
370
  lines.append(
371
  f" - [{cr.get('cf_type', 'unknown')}] "
372
- f"(score={cr.get('cf_score', 0):.2f}) {cr.get('text', '')}"
373
  )
374
 
375
  return format_context_block("Counterfactuality Analysis", "\n".join(lines))
@@ -389,7 +389,7 @@ class GraphMemory(BaseMemory):
389
  return ""
390
  r = rows[0]
391
  lines = [
392
- f"Novelty score: {r.get('novelty_score', 0):.1f}/10 ({r.get('verdict', 'UNKNOWN')})",
393
  f"Problem statement: {r.get('problem_statement', '')}",
394
  f"Rationale: {r.get('rationale', '')}",
395
  ]
 
344
  concerns = r.get("concerns", []) or []
345
  strengths = r.get("strengths", []) or []
346
  lines = [
347
+ f"Overall counterfactuality score: {(r.get('overall_score') or 0):.2f}/1.0",
348
  f"Most common type: {r.get('common_type', 'factual')}",
349
  f"Summary: {r.get('summary', '')}",
350
  ]
 
369
  for cr in claim_rows:
370
  lines.append(
371
  f" - [{cr.get('cf_type', 'unknown')}] "
372
+ f"(score={(cr.get('cf_score') or 0):.2f}) {cr.get('text', '')}"
373
  )
374
 
375
  return format_context_block("Counterfactuality Analysis", "\n".join(lines))
 
389
  return ""
390
  r = rows[0]
391
  lines = [
392
+ f"Novelty score: {(r.get('novelty_score') or 0):.1f}/10 ({r.get('verdict', 'UNKNOWN')})",
393
  f"Problem statement: {r.get('problem_statement', '')}",
394
  f"Rationale: {r.get('rationale', '')}",
395
  ]
similarity/corpus/internal.py CHANGED
@@ -45,6 +45,7 @@ class InternalCorpusProvider:
45
  self._job_id = job_id
46
  self._k = k or settings.kgram_size
47
  self._w = w or settings.window_size
 
48
 
49
  async def search_phrase(self, phrase: str, limit: int) -> list[Candidate]:
50
  if not settings.enable_internal:
 
45
  self._job_id = job_id
46
  self._k = k or settings.kgram_size
47
  self._w = w or settings.window_size
48
+ self.last_error: str | None = None
49
 
50
  async def search_phrase(self, phrase: str, limit: int) -> list[Candidate]:
51
  if not settings.enable_internal:
tests/similarity/test_privacy.py CHANGED
@@ -55,6 +55,13 @@ def test_neutral_label_without_date():
55
  assert _submitted_label(None) == "CitationEdge Corpus · submitted unknown-date"
56
 
57
 
 
 
 
 
 
 
 
58
  async def test_indexed_document_is_found_by_internal_provider(fake_mongo):
59
  assert await _index(fake_mongo) is True
60
 
 
55
  assert _submitted_label(None) == "CitationEdge Corpus · submitted unknown-date"
56
 
57
 
58
+ def test_internal_provider_exposes_last_error(internal_provider):
59
+ """Regression: pipeline reads provider.last_error; InternalCorpusProvider
60
+ must define it like every other provider (prod crash: AttributeError)."""
61
+ provider = internal_provider(doc_id="doc_new")
62
+ assert provider.last_error is None
63
+
64
+
65
  async def test_indexed_document_is_found_by_internal_provider(fake_mongo):
66
  assert await _index(fake_mongo) is True
67
 
tests/test_graph_memory.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Regression tests for GraphMemory report-context formatting.
2
+
3
+ Incident: job_829f9c99 - when the novelty agent's LLM call failed under the
4
+ Groq quota storm it stored novelty_score=None, and get_novelty_context raised
5
+ "unsupported format string passed to NoneType.__format__", crashing the report
6
+ agent and stopping the whole pipeline (no PDF, no email).
7
+ """
8
+
9
+ from unittest.mock import MagicMock
10
+
11
+ import pytest
12
+
13
+ from memory.graph_memory import GraphMemory
14
+
15
+
16
+ @pytest.fixture
17
+ def graph_memory(mock_neo4j, mock_embedder):
18
+ return GraphMemory(neo4j=mock_neo4j, embedder=mock_embedder)
19
+
20
+
21
+ def test_novelty_context_with_none_score(graph_memory):
22
+ """novelty_score=None (LLM failure) must render as 0.0, not crash."""
23
+ graph_memory.neo4j.run.return_value = [
24
+ {"novelty_score": None, "verdict": "UNKNOWN",
25
+ "problem_statement": "ps", "rationale": "r", "similar_works": []}
26
+ ]
27
+ ctx = graph_memory.get_novelty_context("doc_x")
28
+ assert "Novelty score: 0.0/10 (UNKNOWN)" in ctx
29
+
30
+
31
+ def test_novelty_context_with_real_score(graph_memory):
32
+ graph_memory.neo4j.run.return_value = [
33
+ {"novelty_score": 7.3, "verdict": "NOVEL",
34
+ "problem_statement": "ps", "rationale": "r", "similar_works": []}
35
+ ]
36
+ ctx = graph_memory.get_novelty_context("doc_x")
37
+ assert "Novelty score: 7.3/10 (NOVEL)" in ctx
38
+
39
+
40
+ def test_counterfactuality_context_with_none_scores(graph_memory):
41
+ """None overall_score/cf_score (LLM failure) must not crash the report."""
42
+ graph_memory.neo4j.run.side_effect = [
43
+ [{"overall_score": None, "common_type": "factual", "concerns": [],
44
+ "strengths": [], "summary": "s"}],
45
+ [{"text": "c1", "cf_type": "unsupported", "cf_score": None}],
46
+ ]
47
+ ctx = graph_memory.get_counterfactuality_context("doc_x")
48
+ assert "Overall counterfactuality score: 0.00/1.0" in ctx
49
+ assert "(score=0.00) c1" in ctx