From 01f607f92df4d3b9c3abcba6e459ddc95eec66e3 Mon Sep 17 00:00:00 2001 From: Yiorgis Gozadinos Date: Fri, 5 Jun 2026 16:20:11 +0300 Subject: [PATCH] Run analysis sandbox VFS reads on the calling loop via the skill connection --- haiku_rag_slim/haiku/rag/sandbox/sandbox.py | 138 ++++++------------ haiku_rag_slim/haiku/rag/skills/_deps.py | 1 + ...st_close_is_idempotent_after_vfs_read.yaml | 42 ++++++ ...nnection.test_close_stops_loop_thread.yaml | 42 ------ ...st_vfs_loop_and_connection_are_reused.yaml | 42 ------ ..._read_concurrent_with_connection_read.yaml | 42 ++++++ ..._vfs_reads_repeatable_across_executes.yaml | 42 ++++++ ...est_vfs_reads_use_injected_connection.yaml | 42 ++++++ tests/sandbox/test_sandbox.py | 96 ++++++++++-- tests/sandbox/test_sandbox_toc.py | 15 +- 10 files changed, 307 insertions(+), 195 deletions(-) create mode 100644 tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_close_is_idempotent_after_vfs_read.yaml delete mode 100644 tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_close_stops_loop_thread.yaml delete mode 100644 tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_loop_and_connection_are_reused.yaml create mode 100644 tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_read_concurrent_with_connection_read.yaml create mode 100644 tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_reads_repeatable_across_executes.yaml create mode 100644 tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_reads_use_injected_connection.yaml diff --git a/haiku_rag_slim/haiku/rag/sandbox/sandbox.py b/haiku_rag_slim/haiku/rag/sandbox/sandbox.py index 00c5db72..64642be1 100644 --- a/haiku_rag_slim/haiku/rag/sandbox/sandbox.py +++ b/haiku_rag_slim/haiku/rag/sandbox/sandbox.py @@ -1,9 +1,8 @@ import asyncio import json import os -import threading -import weakref -from collections.abc import Callable, Coroutine +from collections.abc import AsyncIterator, Callable, Coroutine +from contextlib import asynccontextmanager from dataclasses import dataclass from pathlib import Path from typing import TYPE_CHECKING, Any, Literal @@ -31,15 +30,6 @@ class SandboxResult: success: bool -def _stop_loop(loop: asyncio.AbstractEventLoop, thread: threading.Thread) -> None: - """Stop a background loop and join its thread. Safe if already stopped.""" - if loop.is_closed(): - return - loop.call_soon_threadsafe(loop.stop) - thread.join() - loop.close() - - def _build_toc( items: list["DocumentItem"], chunk_index: dict[str, list[str]], @@ -130,17 +120,19 @@ class Sandbox: result = await sandbox.execute("x = await search('query')") result = await sandbox.execute("print(x[0]['content'])") # x persists - The virtual filesystem reads run on a dedicated background event loop with a - single read-only connection held for the sandbox's lifetime. Monty's file - callbacks are synchronous and cannot ``await``, so they bridge to that loop - via ``run_coroutine_threadsafe``. Call ``close()`` to release the loop and - connection; if it is not called they are released when the instance is - garbage collected. + All database access runs on the event loop that drives ``execute()``. Monty's + file callbacks are synchronous and run on the interpreter's worker thread, so + they bridge back to that loop via ``run_coroutine_threadsafe``; the loop is + free during ``feed_run_async`` (the VM runs on the worker thread), so the + bridge does not deadlock. When a ``rag`` connection is supplied it is used + for every read, so an analysis run drives a single connection on a single + loop; otherwise each read opens an ephemeral read-only connection. """ _db_path: Path _config: AppConfig _context: AnalysisContext + _rag: "HaikuRAG | None" _search_results: "list[SearchResult]" _doc_items: dict[str, list["DocumentItem"]] _doc_chunk_index: dict[str, dict[str, list[str]]] @@ -149,19 +141,18 @@ class Sandbox: _repl: MontyRepl | None _vfs: OSAccess | None _loop: asyncio.AbstractEventLoop | None - _loop_thread: threading.Thread | None - _vfs_rag: "HaikuRAG | None" - _finalizer: weakref.finalize | None def __init__( self, db_path: Path, config: AppConfig, context: AnalysisContext, + rag: "HaikuRAG | None" = None, ): self._db_path = db_path self._config = config self._context = context + self._rag = rag self._search_results = [] self._doc_items = {} self._doc_chunk_index = {} @@ -170,64 +161,35 @@ class Sandbox: self._repl = None self._vfs = None self._loop = None - self._loop_thread = None - self._vfs_rag = None - self._finalizer = None - def _ensure_vfs_loop(self) -> None: - """Start the background loop and open the read-only connection once.""" - if self._loop is not None: + @asynccontextmanager + async def _connection(self) -> "AsyncIterator[HaikuRAG]": + """Yield the supplied connection, or an ephemeral read-only one.""" + if self._rag is not None: + yield self._rag return from haiku.rag.client import HaikuRAG - loop = asyncio.new_event_loop() - thread = threading.Thread( - target=loop.run_forever, daemon=True, name="sandbox-vfs" - ) - thread.start() - self._loop = loop - self._loop_thread = thread - - async def _open() -> "HaikuRAG": - rag = HaikuRAG(self._db_path, config=self._config, read_only=True) - await rag.__aenter__() - return rag - - self._vfs_rag = self._run_on_loop(_open()) - # GC backstop: capture only the loop + thread, never ``self`` (which - # would pin the instance and prevent collection). - self._finalizer = weakref.finalize(self, _stop_loop, loop, thread) + async with HaikuRAG(self._db_path, config=self._config, read_only=True) as rag: + yield rag def _run_on_loop(self, coro: Coroutine[Any, Any, Any]) -> Any: - """Run a coroutine on the background loop from a synchronous caller.""" - self._ensure_vfs_loop() - assert self._loop is not None + """Run a coroutine on the execute() loop from a synchronous callback. + + Called from Monty's worker thread while ``feed_run_async`` leaves the + loop free, so scheduling onto it and blocking for the result is safe. + """ + assert self._loop is not None, ( + "VFS reads happen during execute(); the loop must be captured first." + ) return asyncio.run_coroutine_threadsafe(coro, self._loop).result() def close(self) -> None: - """Release the background loop and read-only connection. - - Idempotent and safe to call when no VFS read ever started the loop. - """ - loop, thread, rag = self._loop, self._loop_thread, self._vfs_rag - if loop is None or thread is None: - return - self._loop = None - self._loop_thread = None - self._vfs_rag = None - if self._finalizer is not None: - self._finalizer.detach() - self._finalizer = None - if rag is not None and not loop.is_closed(): - asyncio.run_coroutine_threadsafe( - rag.__aexit__(None, None, None), loop - ).result() - _stop_loop(loop, thread) + """Retained for API compatibility; the sandbox owns no resources.""" + return def _build_external_functions(self) -> dict[str, Any]: """Build async external functions for the Monty interpreter.""" - db_path = self._db_path - config = self._config context = self._context async def search(query: str, limit: int = 10) -> list[dict[str, Any]]: @@ -236,9 +198,7 @@ class Sandbox: # agent's Python can't do anything with them. The driving model # gets figures through the top-level `search` tool when the # question is visual; in-code search is for structural work. - from haiku.rag.client import HaikuRAG - - async with HaikuRAG(db_path, config=config, read_only=True) as rag: + async with self._connection() as rag: results = await rag.search(query, limit=limit, filter=context.filter) expanded = await rag.expand_context(results) self._search_results.extend(expanded) @@ -265,9 +225,7 @@ class Sandbox: return out async def list_documents() -> list[dict[str, Any]]: - from haiku.rag.client import HaikuRAG - - async with HaikuRAG(db_path, config=config, read_only=True) as rag: + async with self._connection() as rag: docs = await rag.list_documents(filter=context.filter) return [ { @@ -293,16 +251,12 @@ class Sandbox: - items.jsonl: CallbackFile (lazy, bulk-cached) - toc.json: CallbackFile (lazy, bulk-cached) """ - from haiku.rag.client import HaikuRAG - - db_path = self._db_path - config = self._config files: list[MemoryFile | CallbackFile] = [] def _deny_write(_path: "PurePosixPath", _content: str | bytes) -> None: raise PermissionError(f"Document files are read-only: {_path}") - async with HaikuRAG(db_path, config=config, read_only=True) as rag: + async with self._connection() as rag: docs = await rag.list_documents(filter=self._context.filter) doc_titles = {doc.id: doc.title for doc in docs if doc.id} @@ -316,10 +270,8 @@ class Sandbox: return cached async def _fetch() -> list[DocumentItem]: - assert sandbox._vfs_rag is not None - return await sandbox._vfs_rag.document_item_repository.get_all_items( - did - ) + async with sandbox._connection() as rag: + return await rag.document_item_repository.get_all_items(did) items = sandbox._run_on_loop(_fetch()) sandbox._doc_items[did] = items @@ -332,11 +284,13 @@ class Sandbox: return cached async def _fetch() -> dict[str, list[str]]: - assert sandbox._vfs_rag is not None - index = await sandbox._vfs_rag.chunk_repository.get_chunk_ids_by_self_ref_grouped( - [did] - ) - return index.get(did, {}) + async with sandbox._connection() as rag: + index = ( + await rag.chunk_repository.get_chunk_ids_by_self_ref_grouped( + [did] + ) + ) + return index.get(did, {}) chunk_index = sandbox._run_on_loop(_fetch()) sandbox._doc_chunk_index[did] = chunk_index @@ -414,11 +368,9 @@ class Sandbox: ) -> Callable[["PurePosixPath"], str]: def read_content(_path: "PurePosixPath") -> str: async def _fetch() -> str: - assert sandbox._vfs_rag is not None - content = ( - await sandbox._vfs_rag.document_repository.get_content(did) - ) - return content or "" + async with sandbox._connection() as rag: + content = await rag.document_repository.get_content(did) + return content or "" return sandbox._run_on_loop(_fetch()) @@ -469,6 +421,8 @@ class Sandbox: Variables persist across calls within the same Sandbox instance. """ + # Monty's synchronous file callbacks bridge DB reads back to this loop. + self._loop = asyncio.get_running_loop() repl, vfs = await self._ensure_initialized() external_fns = self._build_external_functions() diff --git a/haiku_rag_slim/haiku/rag/skills/_deps.py b/haiku_rag_slim/haiku/rag/skills/_deps.py index ed053e22..1f8efb01 100644 --- a/haiku_rag_slim/haiku/rag/skills/_deps.py +++ b/haiku_rag_slim/haiku/rag/skills/_deps.py @@ -71,6 +71,7 @@ def make_analysis_lifespan(db_path: Path, config: AppConfig): db_path=db_path, config=config, context=AnalysisContext(filter=doc_filter), + rag=rag, ) deps.sandbox = sandbox _reset_invocation_state(deps.state) diff --git a/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_close_is_idempotent_after_vfs_read.yaml b/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_close_is_idempotent_after_vfs_read.yaml new file mode 100644 index 00000000..3a145b39 --- /dev/null +++ b/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_close_is_idempotent_after_vfs_read.yaml @@ -0,0 +1,42 @@ +interactions: +- request: + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate, zstd + connection: + - keep-alive + content-length: + - '85' + content-type: + - application/json + host: + - localhost:11434 + method: POST + parsed_body: + encoding_format: base64 + input: + - Foxes and dogs. + model: qwen3-embedding:4b + uri: http://localhost:11434/v1/embeddings + response: + headers: + content-type: + - application/json + transfer-encoding: + - chunked + parsed_body: + data: + - embedding: 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 + index: 0 + object: embedding + model: qwen3-embedding:4b + object: list + usage: + prompt_tokens: 6 + total_tokens: 6 + status: + code: 200 + message: OK +version: 1 diff --git a/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_close_stops_loop_thread.yaml b/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_close_stops_loop_thread.yaml deleted file mode 100644 index e0676a57..00000000 --- a/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_close_stops_loop_thread.yaml +++ /dev/null @@ -1,42 +0,0 @@ -interactions: -- request: - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate, zstd - connection: - - keep-alive - content-length: - - '85' - content-type: - - application/json - host: - - localhost:11434 - method: POST - parsed_body: - encoding_format: base64 - input: - - Foxes and dogs. - model: qwen3-embedding:4b - uri: http://localhost:11434/v1/embeddings - response: - headers: - content-type: - - application/json - transfer-encoding: - - chunked - parsed_body: - data: - - embedding: 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 - index: 0 - object: embedding - model: qwen3-embedding:4b - object: list - usage: - prompt_tokens: 6 - total_tokens: 6 - status: - code: 200 - message: OK -version: 1 diff --git a/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_loop_and_connection_are_reused.yaml b/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_loop_and_connection_are_reused.yaml deleted file mode 100644 index e0676a57..00000000 --- a/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_loop_and_connection_are_reused.yaml +++ /dev/null @@ -1,42 +0,0 @@ -interactions: -- request: - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate, zstd - connection: - - keep-alive - content-length: - - '85' - content-type: - - application/json - host: - - localhost:11434 - method: POST - parsed_body: - encoding_format: base64 - input: - - Foxes and dogs. - model: qwen3-embedding:4b - uri: http://localhost:11434/v1/embeddings - response: - headers: - content-type: - - application/json - transfer-encoding: - - chunked - parsed_body: - data: - - embedding: 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 - index: 0 - object: embedding - model: qwen3-embedding:4b - object: list - usage: - prompt_tokens: 6 - total_tokens: 6 - status: - code: 200 - message: OK -version: 1 diff --git a/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_read_concurrent_with_connection_read.yaml b/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_read_concurrent_with_connection_read.yaml new file mode 100644 index 00000000..5844934d --- /dev/null +++ b/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_read_concurrent_with_connection_read.yaml @@ -0,0 +1,42 @@ +interactions: +- request: + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate, zstd + connection: + - keep-alive + content-length: + - '106' + content-type: + - application/json + host: + - localhost:11434 + method: POST + parsed_body: + encoding_format: base64 + input: + - Foxes and dogs roam the quiet hills. + model: qwen3-embedding:4b + uri: http://localhost:11434/v1/embeddings + response: + headers: + content-type: + - application/json + transfer-encoding: + - chunked + parsed_body: + data: + - embedding: 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 + index: 0 + object: embedding + model: qwen3-embedding:4b + object: list + usage: + prompt_tokens: 10 + total_tokens: 10 + status: + code: 200 + message: OK +version: 1 diff --git a/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_reads_repeatable_across_executes.yaml b/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_reads_repeatable_across_executes.yaml new file mode 100644 index 00000000..3a145b39 --- /dev/null +++ b/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_reads_repeatable_across_executes.yaml @@ -0,0 +1,42 @@ +interactions: +- request: + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate, zstd + connection: + - keep-alive + content-length: + - '85' + content-type: + - application/json + host: + - localhost:11434 + method: POST + parsed_body: + encoding_format: base64 + input: + - Foxes and dogs. + model: qwen3-embedding:4b + uri: http://localhost:11434/v1/embeddings + response: + headers: + content-type: + - application/json + transfer-encoding: + - chunked + parsed_body: + data: + - embedding: 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 + index: 0 + object: embedding + model: qwen3-embedding:4b + object: list + usage: + prompt_tokens: 6 + total_tokens: 6 + status: + code: 200 + message: OK +version: 1 diff --git a/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_reads_use_injected_connection.yaml b/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_reads_use_injected_connection.yaml new file mode 100644 index 00000000..21665a96 --- /dev/null +++ b/tests/cassettes/test_sandbox/TestSandboxHeldConnection.test_vfs_reads_use_injected_connection.yaml @@ -0,0 +1,42 @@ +interactions: +- request: + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate, zstd + connection: + - keep-alive + content-length: + - '106' + content-type: + - application/json + host: + - localhost:11434 + method: POST + parsed_body: + encoding_format: base64 + input: + - Foxes and dogs roam the quiet hills. + model: qwen3-embedding:4b + uri: http://localhost:11434/v1/embeddings + response: + headers: + content-type: + - application/json + transfer-encoding: + - chunked + parsed_body: + data: + - embedding: 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 + index: 0 + object: embedding + model: qwen3-embedding:4b + object: list + usage: + prompt_tokens: 10 + total_tokens: 10 + status: + code: 200 + message: OK +version: 1 diff --git a/tests/sandbox/test_sandbox.py b/tests/sandbox/test_sandbox.py index 78c5b258..ed370f24 100644 --- a/tests/sandbox/test_sandbox.py +++ b/tests/sandbox/test_sandbox.py @@ -1,3 +1,5 @@ +import asyncio +import threading from pathlib import Path import pytest @@ -455,8 +457,76 @@ class TestSandboxHeldConnection: @pytest.mark.asyncio @pytest.mark.vcr() - async def test_vfs_loop_and_connection_are_reused(self, temp_db_path): - """The background loop + read-only connection are created once and reused.""" + async def test_vfs_reads_use_injected_connection(self, temp_db_path): + """An injected connection services VFS reads on the calling loop. + + No dedicated background loop/thread is spawned: all DB access for the + sandbox runs on the loop driving execute(), through the one connection. + """ + config = AppConfig() + async with HaikuRAG(temp_db_path, create=True) as client: + doc = await client.create_document( + content="Foxes and dogs roam the quiet hills.", + uri="test://doc", + title="Doc", + ) + assert doc.id + + async with HaikuRAG(temp_db_path, config=config, read_only=True) as rag: + sb = Sandbox( + db_path=temp_db_path, + config=config, + context=AnalysisContext(), + rag=rag, + ) + result = await sb.execute( + "from pathlib import Path\n" + f"print(Path('/documents/{doc.id}/content.txt').read_text())" + ) + assert result.success, result.stderr + assert "Foxes" in result.stdout + assert not any(t.name == "sandbox-vfs" for t in threading.enumerate()) + + @pytest.mark.asyncio + @pytest.mark.vcr() + async def test_vfs_read_concurrent_with_connection_read(self, temp_db_path): + """A VFS read and a direct read on the shared connection run together. + + Both go through one connection on one loop, so the concurrency that + used to cross two event loops no longer borrows the same LanceDB state. + """ + config = AppConfig() + async with HaikuRAG(temp_db_path, create=True) as client: + doc = await client.create_document( + content="Foxes and dogs roam the quiet hills.", + uri="test://doc", + title="Doc", + ) + assert doc.id + + async with HaikuRAG(temp_db_path, config=config, read_only=True) as rag: + sb = Sandbox( + db_path=temp_db_path, + config=config, + context=AnalysisContext(), + rag=rag, + ) + read_code = ( + "from pathlib import Path\n" + f"print(Path('/documents/{doc.id}/content.txt').read_text())" + ) + exec_result, content = await asyncio.gather( + sb.execute(read_code), + rag.document_repository.get_content(doc.id), + ) + assert exec_result.success, exec_result.stderr + assert "Foxes" in exec_result.stdout + assert content and "Foxes" in content + + @pytest.mark.asyncio + @pytest.mark.vcr() + async def test_vfs_reads_repeatable_across_executes(self, temp_db_path): + """Repeated VFS reads across execute() calls return consistent content.""" config = AppConfig() async with HaikuRAG(temp_db_path, create=True) as client: doc = await client.create_document( @@ -469,17 +539,16 @@ class TestSandboxHeldConnection: context = AnalysisContext() sb = Sandbox(db_path=temp_db_path, config=config, context=context) try: - assert sb._loop is None and sb._vfs_rag is None read = ( "from pathlib import Path\n" f"print(Path('/documents/{doc.id}/content.txt').read_text())" ) - assert (await sb.execute(read)).success - loop, rag = sb._loop, sb._vfs_rag - assert loop is not None and rag is not None - assert (await sb.execute(read)).success - assert sb._loop is loop - assert sb._vfs_rag is rag + first = await sb.execute(read) + second = await sb.execute(read) + assert first.success and second.success + assert "Foxes" in first.stdout + assert first.stdout == second.stdout + assert not any(t.name == "sandbox-vfs" for t in threading.enumerate()) finally: sb.close() @@ -516,14 +585,13 @@ class TestSandboxHeldConnection: async with HaikuRAG(temp_db_path, create=True): config = AppConfig() sb = Sandbox(db_path=temp_db_path, config=config, context=AnalysisContext()) - assert sb._loop is None sb.close() sb.close() @pytest.mark.asyncio @pytest.mark.vcr() - async def test_close_stops_loop_thread(self, temp_db_path): - """close() tears down the background loop thread and is idempotent.""" + async def test_close_is_idempotent_after_vfs_read(self, temp_db_path): + """close() is a safe no-op after a VFS read; no background thread lingers.""" config = AppConfig() async with HaikuRAG(temp_db_path, create=True) as client: doc = await client.create_document( @@ -540,8 +608,6 @@ class TestSandboxHeldConnection: f"print(Path('/documents/{doc.id}/content.txt').read_text())" ) assert result.success - thread = sb._loop_thread - assert thread is not None and thread.is_alive() + assert not any(t.name == "sandbox-vfs" for t in threading.enumerate()) sb.close() - assert not thread.is_alive() sb.close() diff --git a/tests/sandbox/test_sandbox_toc.py b/tests/sandbox/test_sandbox_toc.py index 27a4e2a4..9146603e 100644 --- a/tests/sandbox/test_sandbox_toc.py +++ b/tests/sandbox/test_sandbox_toc.py @@ -7,6 +7,7 @@ list of siblings; HTML/markdown corpora with real heading hierarchy get a nested tree. Items with no section_header at all produce `tree: []`. """ +import asyncio import json from pathlib import PurePosixPath @@ -56,15 +57,21 @@ def _header( ) -async def _read_toc(sandbox: Sandbox, doc_id: str) -> dict: +async def _read_vfs_text(sandbox: Sandbox, path: str) -> str: + """Read a VFS file the way execute() does: the synchronous reader runs on a + worker thread and bridges DB access back to the (free) calling loop.""" vfs = await sandbox._build_vfs() - raw = vfs.path_read_text(PurePosixPath(f"/documents/{doc_id}/toc.json")) + sandbox._loop = asyncio.get_running_loop() + return await asyncio.to_thread(vfs.path_read_text, PurePosixPath(path)) + + +async def _read_toc(sandbox: Sandbox, doc_id: str) -> dict: + raw = await _read_vfs_text(sandbox, f"/documents/{doc_id}/toc.json") return json.loads(raw) async def _read_items_jsonl(sandbox: Sandbox, doc_id: str) -> list[dict]: - vfs = await sandbox._build_vfs() - raw = vfs.path_read_text(PurePosixPath(f"/documents/{doc_id}/items.jsonl")) + raw = await _read_vfs_text(sandbox, f"/documents/{doc_id}/items.jsonl") return [json.loads(line) for line in raw.strip().splitlines()] if raw else []