Remove unecessary tests, add no coverage pragmas where appropriate
This commit is contained in:
parent
0ea3717497
commit
4f0f214f26
17 changed files with 21 additions and 110 deletions
|
|
@ -5,7 +5,7 @@ from openai import AsyncOpenAI
|
||||||
from haiku.rag.embeddings.base import EmbedderBase
|
from haiku.rag.embeddings.base import EmbedderBase
|
||||||
|
|
||||||
|
|
||||||
class Embedder(EmbedderBase):
|
class Embedder(EmbedderBase): # pragma: no cover
|
||||||
@overload
|
@overload
|
||||||
async def embed(self, text: str) -> list[float]: ...
|
async def embed(self, text: str) -> list[float]: ...
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from openai import AsyncOpenAI
|
||||||
from haiku.rag.embeddings.base import EmbedderBase
|
from haiku.rag.embeddings.base import EmbedderBase
|
||||||
|
|
||||||
|
|
||||||
class Embedder(EmbedderBase):
|
class Embedder(EmbedderBase): # pragma: no cover
|
||||||
@overload
|
@overload
|
||||||
async def embed(self, text: str) -> list[float]: ...
|
async def embed(self, text: str) -> list[float]: ...
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,9 @@ def format_sse_event(event: AGUIEvent) -> str:
|
||||||
return f"data: {event_json}\n\n"
|
return f"data: {event_json}\n\n"
|
||||||
|
|
||||||
|
|
||||||
def create_agui_server(config: "AppConfig", db_path: Path | None = None) -> Starlette:
|
def create_agui_server( # pragma: no cover
|
||||||
|
config: "AppConfig", db_path: Path | None = None
|
||||||
|
) -> Starlette:
|
||||||
"""Create AG-UI server with both research and deep ask endpoints.
|
"""Create AG-UI server with both research and deep ask endpoints.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ except ImportError:
|
||||||
App = object # type: ignore
|
App = object # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class InspectorApp(App): # type: ignore[misc]
|
class InspectorApp(App): # type: ignore[misc] # pragma: no cover
|
||||||
"""Textual TUI for inspecting LanceDB data."""
|
"""Textual TUI for inspecting LanceDB data."""
|
||||||
|
|
||||||
TITLE = "haiku.rag DB Inspector"
|
TITLE = "haiku.rag DB Inspector"
|
||||||
|
|
@ -193,7 +193,7 @@ class InspectorApp(App): # type: ignore[misc]
|
||||||
await self.push_screen(VisualGroundingModal(chunk=chunk, client=self.client))
|
await self.push_screen(VisualGroundingModal(chunk=chunk, client=self.client))
|
||||||
|
|
||||||
|
|
||||||
def run_inspector(db_path: Path | None = None) -> None:
|
def run_inspector(db_path: Path | None = None) -> None: # pragma: no cover
|
||||||
"""Run the inspector TUI.
|
"""Run the inspector TUI.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ from haiku.rag.client import HaikuRAG
|
||||||
from haiku.rag.store.models import Chunk
|
from haiku.rag.store.models import Chunk
|
||||||
|
|
||||||
|
|
||||||
class ChunkList(VerticalScroll):
|
class ChunkList(VerticalScroll): # pragma: no cover
|
||||||
"""Widget for displaying and browsing chunks."""
|
"""Widget for displaying and browsing chunks."""
|
||||||
|
|
||||||
can_focus = False
|
can_focus = False
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class ProvenanceData(Protocol):
|
||||||
doc_item_refs: list[str]
|
doc_item_refs: list[str]
|
||||||
|
|
||||||
|
|
||||||
class DetailView(VerticalScroll):
|
class DetailView(VerticalScroll): # pragma: no cover
|
||||||
"""Widget for displaying detailed content of documents or chunks."""
|
"""Widget for displaying detailed content of documents or chunks."""
|
||||||
|
|
||||||
can_focus = True
|
can_focus = True
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ from haiku.rag.client import HaikuRAG
|
||||||
from haiku.rag.store.models import Document
|
from haiku.rag.store.models import Document
|
||||||
|
|
||||||
|
|
||||||
class DocumentList(VerticalScroll):
|
class DocumentList(VerticalScroll): # pragma: no cover
|
||||||
"""Widget for displaying and browsing documents."""
|
"""Widget for displaying and browsing documents."""
|
||||||
|
|
||||||
can_focus = False
|
can_focus = False
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ from haiku.rag.inspector.widgets.detail_view import DetailView
|
||||||
from haiku.rag.store.models import Chunk, SearchResult
|
from haiku.rag.store.models import Chunk, SearchResult
|
||||||
|
|
||||||
|
|
||||||
class SearchModal(Screen):
|
class SearchModal(Screen): # pragma: no cover
|
||||||
"""Screen for searching chunks."""
|
"""Screen for searching chunks."""
|
||||||
|
|
||||||
BINDINGS = [
|
BINDINGS = [
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ if TYPE_CHECKING:
|
||||||
from haiku.rag.store.models import Chunk
|
from haiku.rag.store.models import Chunk
|
||||||
|
|
||||||
|
|
||||||
class VisualGroundingModal(Screen):
|
class VisualGroundingModal(Screen): # pragma: no cover
|
||||||
"""Modal screen for displaying visual grounding with bounding boxes."""
|
"""Modal screen for displaying visual grounding with bounding boxes."""
|
||||||
|
|
||||||
BINDINGS = [
|
BINDINGS = [
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ except ImportError as e:
|
||||||
) from e
|
) from e
|
||||||
|
|
||||||
|
|
||||||
class CohereReranker(RerankerBase):
|
class CohereReranker(RerankerBase): # pragma: no cover
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Cohere SDK reads CO_API_KEY from environment by default
|
# Cohere SDK reads CO_API_KEY from environment by default
|
||||||
self._client = cohere.ClientV2()
|
self._client = cohere.ClientV2()
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from haiku.rag.reranking.base import RerankerBase
|
||||||
from haiku.rag.store.models.chunk import Chunk
|
from haiku.rag.store.models.chunk import Chunk
|
||||||
|
|
||||||
|
|
||||||
class VLLMReranker(RerankerBase):
|
class VLLMReranker(RerankerBase): # pragma: no cover
|
||||||
def __init__(self, model: str):
|
def __init__(self, model: str):
|
||||||
self._model = model
|
self._model = model
|
||||||
self._base_url = Config.providers.vllm.rerank_base_url
|
self._base_url = Config.providers.vllm.rerank_base_url
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ from haiku.rag.reranking.base import RerankerBase
|
||||||
from haiku.rag.store.models.chunk import Chunk
|
from haiku.rag.store.models.chunk import Chunk
|
||||||
|
|
||||||
|
|
||||||
class ZeroEntropyReranker(RerankerBase):
|
class ZeroEntropyReranker(RerankerBase): # pragma: no cover
|
||||||
"""Zero Entropy reranker implementation using the zerank-1 model."""
|
"""Zero Entropy reranker implementation using the zerank-1 model."""
|
||||||
|
|
||||||
def __init__(self, model: str = "zerank-1"):
|
def __init__(self, model: str = "zerank-1"):
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ from haiku.rag.store.engine import Store
|
||||||
from haiku.rag.store.upgrades import Upgrade
|
from haiku.rag.store.upgrades import Upgrade
|
||||||
|
|
||||||
|
|
||||||
def _apply_add_document_title(store: Store) -> None:
|
def _apply_add_document_title(store: Store) -> None: # pragma: no cover
|
||||||
"""Add a nullable 'title' column to the documents table."""
|
"""Add a nullable 'title' column to the documents table."""
|
||||||
|
|
||||||
# Read existing rows using Arrow for schema-agnostic access
|
# Read existing rows using Arrow for schema-agnostic access
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ from haiku.rag.store.upgrades import Upgrade
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def _apply_embeddings_model_config(store: Store) -> None:
|
def _apply_embeddings_model_config(store: Store) -> None: # pragma: no cover
|
||||||
"""Migrate embeddings config from flat to nested EmbeddingModelConfig structure."""
|
"""Migrate embeddings config from flat to nested EmbeddingModelConfig structure."""
|
||||||
results = list(
|
results = list(
|
||||||
store.settings_table.search()
|
store.settings_table.search()
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ from haiku.rag.store.engine import Store
|
||||||
from haiku.rag.store.upgrades import Upgrade
|
from haiku.rag.store.upgrades import Upgrade
|
||||||
|
|
||||||
|
|
||||||
def _apply_add_docling_document_columns(store: Store) -> None:
|
def _apply_add_docling_document_columns(store: Store) -> None: # pragma: no cover
|
||||||
"""Add 'docling_document_json' and 'docling_version' columns to documents table."""
|
"""Add 'docling_document_json' and 'docling_version' columns to documents table."""
|
||||||
|
|
||||||
# Read existing rows using Arrow for schema-agnostic access
|
# Read existing rows using Arrow for schema-agnostic access
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ from haiku.rag.store.engine import Store
|
||||||
from haiku.rag.store.upgrades import Upgrade
|
from haiku.rag.store.upgrades import Upgrade
|
||||||
|
|
||||||
|
|
||||||
def _infer_vector_dim(store: Store) -> int:
|
def _infer_vector_dim(store: Store) -> int: # pragma: no cover
|
||||||
"""Infer vector dimension from existing data; fallback to embedder config."""
|
"""Infer vector dimension from existing data; fallback to embedder config."""
|
||||||
try:
|
try:
|
||||||
arrow = store.chunks_table.search().limit(1).to_arrow()
|
arrow = store.chunks_table.search().limit(1).to_arrow()
|
||||||
|
|
@ -22,7 +22,7 @@ def _infer_vector_dim(store: Store) -> int:
|
||||||
return getattr(store.embedder, "_vector_dim", 1024)
|
return getattr(store.embedder, "_vector_dim", 1024)
|
||||||
|
|
||||||
|
|
||||||
def _apply_chunk_order(store: Store) -> None:
|
def _apply_chunk_order(store: Store) -> None: # pragma: no cover
|
||||||
"""Add integer 'order' column to chunks and backfill from metadata."""
|
"""Add integer 'order' column to chunks and backfill from metadata."""
|
||||||
|
|
||||||
vector_dim = _infer_vector_dim(store)
|
vector_dim = _infer_vector_dim(store)
|
||||||
|
|
@ -95,7 +95,7 @@ upgrade_order = Upgrade(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _apply_fts_phrase_support(store: Store) -> None:
|
def _apply_fts_phrase_support(store: Store) -> None: # pragma: no cover
|
||||||
"""Recreate FTS index with phrase query support and no stop-word removal."""
|
"""Recreate FTS index with phrase query support and no stop-word removal."""
|
||||||
try:
|
try:
|
||||||
store.chunks_table.create_fts_index(
|
store.chunks_table.create_fts_index(
|
||||||
|
|
|
||||||
|
|
@ -1,102 +1,11 @@
|
||||||
import pytest
|
import pytest
|
||||||
from datasets import Dataset
|
from datasets import Dataset
|
||||||
|
|
||||||
from haiku.rag.client import HaikuRAG
|
|
||||||
from haiku.rag.config import Config
|
|
||||||
from haiku.rag.store.engine import Store
|
from haiku.rag.store.engine import Store
|
||||||
from haiku.rag.store.models.document import Document
|
from haiku.rag.store.models.document import Document
|
||||||
from haiku.rag.store.repositories.document import DocumentRepository
|
from haiku.rag.store.repositories.document import DocumentRepository
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_create_document_with_chunks(qa_corpus: Dataset, temp_db_path):
|
|
||||||
"""Test creating a document with chunks from the qa_corpus using repository."""
|
|
||||||
# Create client
|
|
||||||
client = HaikuRAG(db_path=temp_db_path, config=Config, create=True)
|
|
||||||
|
|
||||||
# Get the first document from the corpus
|
|
||||||
first_doc = qa_corpus[0]
|
|
||||||
document_text = first_doc["document_extracted"]
|
|
||||||
|
|
||||||
# Create the document with chunks in the database
|
|
||||||
created_document = await client.create_document(
|
|
||||||
content=document_text,
|
|
||||||
metadata={"source": "qa_corpus", "topic": first_doc.get("document_topic", "")},
|
|
||||||
)
|
|
||||||
|
|
||||||
# Verify the document was created
|
|
||||||
assert created_document.id is not None
|
|
||||||
assert created_document.content == document_text
|
|
||||||
|
|
||||||
# Check that chunks were created using repository
|
|
||||||
chunks = await client.chunk_repository.get_by_document_id(created_document.id)
|
|
||||||
|
|
||||||
assert len(chunks) > 0
|
|
||||||
|
|
||||||
# Verify chunk order is set correctly
|
|
||||||
for i, chunk in enumerate(chunks):
|
|
||||||
assert chunk.order == i
|
|
||||||
|
|
||||||
client.close()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_document_repository_crud(qa_corpus: Dataset, temp_db_path):
|
|
||||||
"""Test CRUD operations in DocumentRepository."""
|
|
||||||
# Create a store and repository
|
|
||||||
store = Store(temp_db_path, create=True)
|
|
||||||
doc_repo = DocumentRepository(store)
|
|
||||||
|
|
||||||
# Get the first document from the corpus
|
|
||||||
first_doc = qa_corpus[0]
|
|
||||||
document_text = first_doc["document_extracted"]
|
|
||||||
|
|
||||||
# Create a document with URI
|
|
||||||
test_uri = "file:///path/to/test.txt"
|
|
||||||
document = Document(
|
|
||||||
content=document_text, uri=test_uri, metadata={"source": "test"}
|
|
||||||
)
|
|
||||||
created_document = await doc_repo.create(document)
|
|
||||||
|
|
||||||
# Test get_by_id
|
|
||||||
assert created_document.id is not None
|
|
||||||
retrieved_document = await doc_repo.get_by_id(created_document.id)
|
|
||||||
assert retrieved_document is not None
|
|
||||||
assert retrieved_document.content == document_text
|
|
||||||
assert retrieved_document.uri == test_uri
|
|
||||||
|
|
||||||
# Test get_by_uri
|
|
||||||
retrieved_by_uri = await doc_repo.get_by_uri(test_uri)
|
|
||||||
assert retrieved_by_uri is not None
|
|
||||||
assert retrieved_by_uri.id == created_document.id
|
|
||||||
assert retrieved_by_uri.content == document_text
|
|
||||||
assert retrieved_by_uri.uri == test_uri
|
|
||||||
|
|
||||||
# Test get_by_uri with non-existent URI
|
|
||||||
non_existent = await doc_repo.get_by_uri("file:///non/existent.txt")
|
|
||||||
assert non_existent is None
|
|
||||||
|
|
||||||
# Test update (should regenerate chunks)
|
|
||||||
retrieved_document.content = "Updated content for testing"
|
|
||||||
updated_document = await doc_repo.update(retrieved_document)
|
|
||||||
assert updated_document.content == "Updated content for testing"
|
|
||||||
|
|
||||||
# Test list_all
|
|
||||||
all_documents = await doc_repo.list_all()
|
|
||||||
assert len(all_documents) == 1
|
|
||||||
assert all_documents[0].id == created_document.id
|
|
||||||
|
|
||||||
# Test delete
|
|
||||||
deleted = await doc_repo.delete(created_document.id)
|
|
||||||
assert deleted is True
|
|
||||||
|
|
||||||
# Verify document is gone
|
|
||||||
retrieved_document = await doc_repo.get_by_id(created_document.id)
|
|
||||||
assert retrieved_document is None
|
|
||||||
|
|
||||||
store.close()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_document_list_with_filter(qa_corpus: Dataset, temp_db_path):
|
async def test_document_list_with_filter(qa_corpus: Dataset, temp_db_path):
|
||||||
"""Test listing documents with filter clause."""
|
"""Test listing documents with filter clause."""
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue