diff --git a/haiku_rag_slim/haiku/rag/cli.py b/haiku_rag_slim/haiku/rag/cli.py index b6d3539c..c7ab75cd 100644 --- a/haiku_rag_slim/haiku/rag/cli.py +++ b/haiku_rag_slim/haiku/rag/cli.py @@ -23,6 +23,7 @@ from haiku.rag.config import ( # noqa: E402 from haiku.rag.logging import configure_cli_logging # noqa: E402 from haiku.rag.store.exceptions import ( # noqa: E402 AmbiguousDatabaseError, + ConfigMismatchError, MigrationRequiredError, ReadOnlyError, SourceUnavailableError, @@ -42,10 +43,6 @@ _cli = typer.Typer( def cli(): - # Imported here rather than at module scope: the settings module pulls in - # lancedb, and the CLI's startup must not pay for it. - from haiku.rag.store.repositories.settings import ConfigMismatchError - try: _cli() except ( diff --git a/haiku_rag_slim/haiku/rag/client/__init__.py b/haiku_rag_slim/haiku/rag/client/__init__.py index bbc59db5..8003381f 100644 --- a/haiku_rag_slim/haiku/rag/client/__init__.py +++ b/haiku_rag_slim/haiku/rag/client/__init__.py @@ -20,6 +20,7 @@ from haiku.rag.converters import get_converter from haiku.rag.reranking import get_reranker from haiku.rag.store.engine import Store from haiku.rag.store.exceptions import ( + ConfigMismatchError, MigrationRequiredError, ReadOnlyError, SourceUnavailableError, @@ -30,10 +31,7 @@ from haiku.rag.store.models.document_item import extract_items from haiku.rag.store.repositories.chunk import ChunkRepository from haiku.rag.store.repositories.document import DocumentRepository from haiku.rag.store.repositories.document_item import DocumentItemRepository -from haiku.rag.store.repositories.settings import ( - ConfigMismatchError, - SettingsRepository, -) +from haiku.rag.store.repositories.settings import SettingsRepository from haiku.rag.utils import escape_sql_string, locate_database if TYPE_CHECKING: diff --git a/haiku_rag_slim/haiku/rag/client/rebuild.py b/haiku_rag_slim/haiku/rag/client/rebuild.py index 6b1c568b..3f5f6b3f 100644 --- a/haiku_rag_slim/haiku/rag/client/rebuild.py +++ b/haiku_rag_slim/haiku/rag/client/rebuild.py @@ -161,7 +161,7 @@ async def _set_embedder(client: "HaikuRAG") -> None: usable, so just the recorded provider/name are updated. A changed dimension requires regenerating every embedding via a full rebuild. """ - from haiku.rag.store.repositories.settings import ConfigMismatchError + from haiku.rag.store.exceptions import ConfigMismatchError settings_repo = SettingsRepository(client.store) stored = await settings_repo.get_current_settings() diff --git a/haiku_rag_slim/haiku/rag/store/__init__.py b/haiku_rag_slim/haiku/rag/store/__init__.py index d8edff9e..81521f90 100644 --- a/haiku_rag_slim/haiku/rag/store/__init__.py +++ b/haiku_rag_slim/haiku/rag/store/__init__.py @@ -1,5 +1,6 @@ from .exceptions import ( AmbiguousDatabaseError, + ConfigMismatchError, MigrationRequiredError, ReadOnlyError, SourceUnavailableError, @@ -12,5 +13,6 @@ __all__ = [ "MigrationRequiredError", "ReadOnlyError", "AmbiguousDatabaseError", + "ConfigMismatchError", "SourceUnavailableError", ] diff --git a/haiku_rag_slim/haiku/rag/store/exceptions.py b/haiku_rag_slim/haiku/rag/store/exceptions.py index 61a5b55c..3ad60070 100644 --- a/haiku_rag_slim/haiku/rag/store/exceptions.py +++ b/haiku_rag_slim/haiku/rag/store/exceptions.py @@ -4,6 +4,12 @@ class ReadOnlyError(Exception): pass +class ConfigMismatchError(Exception): + """Raised when stored config doesn't match current config.""" + + pass + + class MigrationRequiredError(Exception): """Database requires migration. Run 'haiku-rag migrate' to upgrade.""" diff --git a/haiku_rag_slim/haiku/rag/store/repositories/settings.py b/haiku_rag_slim/haiku/rag/store/repositories/settings.py index a8b2c16c..80ff54d7 100644 --- a/haiku_rag_slim/haiku/rag/store/repositories/settings.py +++ b/haiku_rag_slim/haiku/rag/store/repositories/settings.py @@ -2,17 +2,12 @@ import json import logging from haiku.rag.store.engine import Store +from haiku.rag.store.exceptions import ConfigMismatchError from haiku.rag.store.schema import SettingsRecord, query_to_pydantic logger = logging.getLogger(__name__) -class ConfigMismatchError(Exception): - """Raised when stored config doesn't match current config.""" - - pass - - class SettingsRepository: """Repository for Settings operations.""" diff --git a/tests/store/test_read_only.py b/tests/store/test_read_only.py index 7ff281b1..26e74b1d 100644 --- a/tests/store/test_read_only.py +++ b/tests/store/test_read_only.py @@ -394,7 +394,7 @@ class TestAppReadVerbsDoNotWrite: """A write CLI verb opens writable: drift raises before any write.""" from haiku.rag.app import HaikuRAGApp from haiku.rag.config import AppConfig - from haiku.rag.store.repositories.settings import ConfigMismatchError + from haiku.rag.store.exceptions import ConfigMismatchError async with Store(temp_db_path, create=True) as store: stored_name_before = ( diff --git a/tests/test_cli.py b/tests/test_cli.py index 17c1df41..597fe2a4 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -332,7 +332,7 @@ class TestCliConfigMismatchError: def test_a_config_mismatch_exits_with_its_remedy(self): """The message says which database and what to run, so it is worth more than a traceback.""" - from haiku.rag.store.repositories.settings import ConfigMismatchError + from haiku.rag.store.exceptions import ConfigMismatchError with patch("haiku.rag.cli._cli") as mock_cli: mock_cli.side_effect = ConfigMismatchError( diff --git a/tests/test_mcp.py b/tests/test_mcp.py index 860bf2a7..191549f9 100644 --- a/tests/test_mcp.py +++ b/tests/test_mcp.py @@ -645,7 +645,7 @@ class TestMCPClientLifetime: read-only mode and raises in writable mode. The MCP server no longer opts out of it for deletion.""" from haiku.rag.config import get_config - from haiku.rag.store.repositories.settings import ConfigMismatchError + from haiku.rag.store.exceptions import ConfigMismatchError drifted = get_config().model_copy(deep=True) drifted.embeddings.model.name = "a-different-model" diff --git a/tests/test_rebuild.py b/tests/test_rebuild.py index 971f797b..f9b0e951 100644 --- a/tests/test_rebuild.py +++ b/tests/test_rebuild.py @@ -1059,7 +1059,7 @@ async def test_rebuild_set_embedder_works_on_empty_database(temp_db_path): async def test_rebuild_set_embedder_raises_on_vector_dim_mismatch(temp_db_path): """SET_EMBEDDER refuses when the vector dimension changed — a full rebuild is needed.""" from haiku.rag.config import AppConfig - from haiku.rag.store.repositories.settings import ConfigMismatchError + from haiku.rag.store.exceptions import ConfigMismatchError async with HaikuRAG(temp_db_path, create=True): pass diff --git a/tests/test_settings.py b/tests/test_settings.py index 704b9eda..7b271d39 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -3,7 +3,7 @@ import logging import pytest from haiku.rag.config import AppConfig, get_config -from haiku.rag.store.repositories.settings import ConfigMismatchError +from haiku.rag.store.exceptions import ConfigMismatchError @pytest.mark.asyncio