Skip to content

Commit b1f8cc5

Browse files
hherbclaude
andcommitted
Fix EvidenceSynthesizer callback signature mismatch
The EvidenceSynthesizer expects callback(message, current, total) with 3 args but the agent callback is callback(event, data) with 2 args. This caused: "takes 3 positional arguments but 4 were given" Fix: - Add _make_synthesis_callback() wrapper method to convert between formats - Emits "synthesis_progress" events with "X/Y | message" format - Update all 4 locations passing progress_callback to EvidenceSynthesizer - Add synthesis_progress to GUI progress map (87%) - Add activity log formatting with 📝 icon 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent b6f70be commit b1f8cc5

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

src/bmlibrarian/agents/systematic_review/agent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1295,7 +1295,7 @@ def run_review(
12951295
temperature=self.config.synthesis_temperature,
12961296
citation_min_relevance=self.config.citation_min_relevance,
12971297
max_citations_per_paper=self.config.max_citations_per_paper,
1298-
progress_callback=self.callback,
1298+
progress_callback=self._make_synthesis_callback(),
12991299
)
13001300

13011301
with self.documenter.log_step_with_timer(

src/bmlibrarian/agents/systematic_review/resume_mixin.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,25 @@ class CheckpointResumeMixin:
9797
- get_below_threshold_papers(): Get below threshold papers
9898
"""
9999

100+
def _make_synthesis_callback(self) -> Optional[Callable[[str, int, int], None]]:
101+
"""
102+
Create a callback wrapper for EvidenceSynthesizer.
103+
104+
The synthesizer expects callback(message, current, total) but the agent
105+
callback is callback(event, data). This wrapper converts between the two.
106+
107+
Returns:
108+
Wrapped callback or None if no callback is set.
109+
"""
110+
if not self.callback:
111+
return None
112+
113+
def synthesis_callback(message: str, current: int, total: int) -> None:
114+
# Convert to agent callback format: (event, data)
115+
self.callback("synthesis_progress", f"{current}/{total} | {message}")
116+
117+
return synthesis_callback
118+
100119
def run_review_from_checkpoint(
101120
self,
102121
checkpoint_path: str,
@@ -821,7 +840,7 @@ def _continue_from_quality_assessment(
821840
temperature=self.config.synthesis_temperature,
822841
citation_min_relevance=self.config.citation_min_relevance,
823842
max_citations_per_paper=self.config.max_citations_per_paper,
824-
progress_callback=self.callback,
843+
progress_callback=self._make_synthesis_callback(),
825844
)
826845

827846
with self.documenter.log_step_with_timer(
@@ -1016,7 +1035,7 @@ def _continue_from_composite_scoring(
10161035
temperature=self.config.synthesis_temperature,
10171036
citation_min_relevance=self.config.citation_min_relevance,
10181037
max_citations_per_paper=self.config.max_citations_per_paper,
1019-
progress_callback=self.callback,
1038+
progress_callback=self._make_synthesis_callback(),
10201039
)
10211040

10221041
with self.documenter.log_step_with_timer(
@@ -1360,7 +1379,7 @@ def _continue_from_scoring_phase(
13601379
temperature=self.config.synthesis_temperature,
13611380
citation_min_relevance=self.config.citation_min_relevance,
13621381
max_citations_per_paper=self.config.max_citations_per_paper,
1363-
progress_callback=self.callback,
1382+
progress_callback=self._make_synthesis_callback(),
13641383
)
13651384

13661385
with self.documenter.log_step_with_timer(

src/bmlibrarian/gui/qt/plugins/systematic_review/systematic_review_tab.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ def _progress_callback(self, event: str, data: str) -> None:
252252
"quality_progress": 80,
253253
"quality_complete": 85,
254254
"quality_assessment_completed": 85,
255+
"synthesis_progress": 87,
255256
"reporting_started": 90,
256257
"reporting_complete": 95,
257258
}
@@ -327,6 +328,12 @@ def _format_activity_entry(self, event: str, data: str) -> Optional[str]:
327328
return f"**[{timestamp}]** {data}\n"
328329
elif event == "quality_complete" or event == "quality_assessment_completed":
329330
return f"**[{timestamp}]** ✓ Quality assessment complete: {data}\n\n---\n"
331+
elif event == "synthesis_progress":
332+
# Format: "X/Y | message" - extract the meaningful part
333+
if " | " in data:
334+
_, info = data.split(" | ", 1)
335+
return f"**[{timestamp}]** 📝 {info}\n"
336+
return f"**[{timestamp}]** 📝 {data}\n"
330337
elif event == "reporting_started":
331338
return f"**[{timestamp}]** Generating report...\n"
332339
elif event == "reporting_complete":

0 commit comments

Comments
 (0)