Render a citation whose pictures no database claims

Chat asked the covering client for a picture with the citation's source, which
raises when there is none, losing the answer to one figure. It resolves the
reader first and omits the bytes when the database cannot be placed, as the rich
formatter already did.
This commit is contained in:
Yiorgis Gozadinos 2026-08-28 08:41:48 +03:00
parent 202cbd2d3f
commit bd8c1a6d15
No known key found for this signature in database
2 changed files with 53 additions and 3 deletions

View file

@ -300,11 +300,15 @@ class ChatApp(App):
refs = list(citation.picture_refs or [])
if not refs:
continue
# Evidence recorded before databases could be named carries no
# source, and across databases nothing places its pictures. The
# citation still renders, with its figure markers.
owner = await self.client.reader_for(citation.source)
if owner is None:
continue
blobs: list[bytes] = []
for ref in refs:
data = await self.client.get_picture_bytes(
citation.document_id, ref, citation.source
)
data = await owner.get_picture_bytes(citation.document_id, ref)
if data:
blobs.append(data)
if blobs:

View file

@ -687,6 +687,52 @@ class TestDocumentSelectionIdentity:
assert modal._selected == {"id-one"}
class TestRenderingUnattributedPictures:
@pytest.mark.asyncio
async def test_a_sourceless_picture_citation_does_not_fail_the_answer(
self, temp_db_path: Path
):
"""Evidence recorded before databases could be named carries no source,
and across databases nothing places its pictures. The citation still
renders, with its figure markers."""
from haiku.rag.chat.app import RAG_STATE_NAMESPACE
from haiku.rag.store.models.citation import Citation
covering = _make_mock_client()
covering.covers_multiple = True
covering.source_names = ("alpha", "beta")
covering.reader_for = AsyncMock(return_value=None)
covering.get_picture_bytes = AsyncMock(
side_effect=AssertionError("asked a set for a picture it cannot place")
)
citation = Citation(
document_id="d1",
chunk_id="c1",
content="body",
document_uri="test://doc",
picture_refs=["#/pictures/0"],
)
app, _ = _make_app(temp_db_path, covering)
with (
patch("haiku.rag.chat.app.HaikuRAG") as stub,
_covering_returns(stub, covering),
):
async with app.run_test() as pilot:
app._state[RAG_STATE_NAMESPACE] = {
"citations": ["c1"],
"citation_index": {"c1": citation.model_dump(mode="json")},
}
from haiku.rag.chat.widgets.chat_history import ChatHistory
await app._show_citations_and_programs(app.query_one(ChatHistory))
await pilot.pause()
covering.reader_for.assert_awaited_once_with(None)
covering.get_picture_bytes.assert_not_awaited()
class TestKeepingSelectionsReachable:
"""A selection applies whether or not the page shows it, and a checkbox is
the only way to remove one."""