
### 🐛 Bug Fixes

- Citation handlers and the report structure generator now route LLM responses through `get_llm_response_text`, stripping `<think>` reasoning blocks from synthesized answers and reports (previously leaked verbatim with reasoning models) and normalizing string/message responses in one place.
- Cross-engine filtering now deduplicates repeated LLM-ranked result indices so the same source does not appear multiple times with different citation numbers.
- Fix `AttributeError` in citation handlers during follow-up research when LLMs return string responses instead of message objects.
- Restore `str()` coercion in the precision citation handler's key-fact extraction so it always returns a string (fixes a mypy `no-any-return` failure introduced in #3884).
