Mark a picture no database claims
`format_citations_rich` asked a client covering a set for a picture whose citation named no database, which raises, losing the whole answer to one figure. Citations recorded before databases could be named carry no source, so the figure marker the caller already renders stands in.
This commit is contained in:
parent
de6da8b375
commit
64b1096865
2 changed files with 37 additions and 1 deletions
|
|
@ -447,9 +447,15 @@ async def format_citations_rich(
|
|||
async def _render_picture(
|
||||
client: "HaikuRAG | None", document_id: str, ref: str, source: str | None = None
|
||||
) -> "RenderableType | None":
|
||||
"""Fetch a picture and return a Rich renderable, or None on failure/no client."""
|
||||
"""A picture as a Rich renderable, or None where it cannot be rendered.
|
||||
|
||||
None where no client, no source to place it across databases, or bytes that
|
||||
do not decode. The caller renders its figure marker instead.
|
||||
"""
|
||||
if client is None:
|
||||
return None
|
||||
if source is None and client.covers_multiple:
|
||||
return None
|
||||
from io import BytesIO
|
||||
|
||||
from PIL import Image as PILImage
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import importlib.util
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
import pytest
|
||||
from pydantic_ai.models.openai import OpenAIChatModel
|
||||
|
|
@ -793,6 +794,34 @@ async def test_format_citations_rich_names_the_database_when_federating():
|
|||
assert "papers" in output
|
||||
|
||||
|
||||
async def test_an_unattributable_picture_renders_its_marker(tmp_path):
|
||||
"""Evidence recorded before databases could be named carries no source, so
|
||||
across databases nothing says which holds the picture. One unrenderable
|
||||
figure must not cost the answer."""
|
||||
from rich.console import Console
|
||||
|
||||
from haiku.rag.store.models.citation import Citation
|
||||
from haiku.rag.utils import format_citations_rich
|
||||
|
||||
covering = AsyncMock()
|
||||
covering.covers_multiple = True
|
||||
citation = Citation(
|
||||
document_id="d1",
|
||||
chunk_id="c1",
|
||||
content="body",
|
||||
document_uri="test://doc",
|
||||
picture_refs=["#/pictures/0"],
|
||||
)
|
||||
|
||||
renderables = await format_citations_rich([citation], covering)
|
||||
|
||||
console = Console(record=True, width=200)
|
||||
for renderable in renderables:
|
||||
console.print(renderable)
|
||||
assert "[Figure: #/pictures/0]" in console.export_text()
|
||||
covering.get_picture_bytes.assert_not_awaited()
|
||||
|
||||
|
||||
def test_truncated_marks_what_it_dropped():
|
||||
"""An unmarked cut reads as the value: a sentence ending "in 1991" becomes
|
||||
one ending "in 1"."""
|
||||
|
|
@ -999,6 +1028,7 @@ async def test_render_picture_handles_stored_bytes(stored, renders):
|
|||
stored = buf.getvalue()
|
||||
|
||||
client = AsyncMock()
|
||||
client.covers_multiple = False
|
||||
client.get_picture_bytes = AsyncMock(return_value=stored)
|
||||
|
||||
result = await _render_picture(client, "doc1", "#/pictures/0")
|
||||
|
|
|
|||
Loading…
Reference in a new issue