Cover sandbox VFS reads, binary part dedup and picture spans

This commit is contained in:
Yiorgis Gozadinos 2026-07-26 19:41:09 +03:00
parent 2afe1bd28c
commit 7c120587f0
No known key found for this signature in database
4 changed files with 119 additions and 2 deletions

View file

@ -356,7 +356,8 @@ class Sandbox:
return read_toc
for doc in docs:
if not doc.id:
if not doc.id: # pragma: no cover - rows read from LanceDB always
# carry an id; only a hand-built Document could be id-less.
continue
doc_id: str = doc.id
doc_dir = f"/documents/{doc_id}"
@ -438,7 +439,10 @@ class Sandbox:
stdout_lines: list[str] = []
def print_callback(_stream: Literal["stdout"], text: str) -> None:
stdout_lines.append(text)
# pragma: no cover - Monty invokes this from its own Rust-owned
# thread, which coverage cannot trace. The captured stdout is
# asserted by test_execute_simple_code.
stdout_lines.append(text) # pragma: no cover
max_chars = self._config.analysis.max_output_chars

View file

@ -364,3 +364,57 @@ class TestItemsJsonlSurfacesNewFields:
assert expected <= set(r)
assert "position" not in r
assert "tree_depth" not in r
@pytest.mark.asyncio
class TestVfsReadPaths:
"""The synchronous VFS readers bridge back to the event loop; drive them
through a worker thread the way execute() does."""
async def test_content_txt_is_read_lazily_per_document(self, temp_db_path):
async with HaikuRAG(temp_db_path, create=True) as client:
doc = await client.document_repository.create(
Document(content="the stored body", uri="test://body", title="Body")
)
doc_id = doc.id
sandbox = Sandbox(temp_db_path, AppConfig(), AnalysisContext())
content = await _read_vfs_text(sandbox, f"/documents/{doc_id}/content.txt")
assert content == "the stored body"
async def test_document_files_are_read_only(self, temp_db_path):
async with HaikuRAG(temp_db_path, create=True) as client:
doc = await client.document_repository.create(
Document(content="x", uri="test://ro", title="RO")
)
doc_id = doc.id
sandbox = Sandbox(temp_db_path, AppConfig(), AnalysisContext())
vfs = await sandbox._build_vfs()
sandbox._loop = asyncio.get_running_loop()
with pytest.raises(PermissionError, match="read-only"):
await asyncio.to_thread(
vfs.path_write_text,
PurePosixPath(f"/documents/{doc_id}/content.txt"),
"nope",
)
async def test_toc_skips_gaps_in_item_positions(self, temp_db_path):
"""Positions need not be contiguous — a heading's span may cover
positions that carry no item."""
async with HaikuRAG(temp_db_path, create=True) as client:
doc_id = await _empty_doc(client, uri="test://gaps", title="Gaps")
# Positions 1 and 2 are absent between the header and the paragraph.
items = [
_header(doc_id, 0, 1, "Intro"),
_para(doc_id, 3),
]
await client.document_item_repository.create_items(doc_id, items)
sandbox = Sandbox(temp_db_path, AppConfig(), AnalysisContext())
toc = await _read_toc(sandbox, doc_id)
assert [n["title"] for n in toc["tree"]] == ["Intro"]

View file

@ -1360,3 +1360,16 @@ class TestExpandWithItemsPictureBytes:
e_low = by_chunk["c-low"]
assert e_low.image_data == {"#/pictures/0": "LOWBYTES"}
assert "HIGHBYTES" not in (e_low.image_data or {}).values()
class TestSpanInWindow:
def test_zero_width_span_is_inside_when_position_is_in_window(self):
from haiku.rag.context import _span_in_window
from haiku.rag.store.models.document_item import DocumentItem
item = DocumentItem(
document_id="d1", position=0, self_ref="#/pictures/0", label="picture"
)
# A picture occupies no characters, so containment is by position.
assert _span_in_window((10, 10, item), 0, 20) is True
assert _span_in_window((30, 30, item), 0, 20) is False

View file

@ -214,3 +214,49 @@ def search_config():
from haiku.rag.config import Config
return Config
class TestBuildBinaryPartsFromResults:
"""Picture bytes are attached once per (document, self_ref) pair."""
def test_results_without_image_data_contribute_nothing(self):
from haiku.rag.tools.search import build_binary_parts_from_results
results = [
SearchResult(content="text only", score=0.5, chunk_id="c1", image_data=None)
]
assert build_binary_parts_from_results(results) == []
def test_duplicate_document_and_ref_is_attached_once(self):
import base64
from io import BytesIO
from PIL import Image as PILImage
from haiku.rag.tools.search import build_binary_parts_from_results
buf = BytesIO()
PILImage.new("RGB", (4, 4), "red").save(buf, format="PNG")
png = base64.b64encode(buf.getvalue()).decode()
shared = {"#/pictures/0": png}
results = [
SearchResult(
content="a",
score=0.9,
chunk_id="c1",
document_id="doc-1",
image_data=shared,
),
SearchResult(
content="b",
score=0.8,
chunk_id="c2",
document_id="doc-1",
image_data=shared,
),
]
parts = build_binary_parts_from_results(results)
assert len(parts) == 1