Drop the indirection around what a client covers
`covers_several_databases` had one line of body and two call sites. `_db_path_given` guarded a default path manufactured in `__init__` and overwritten in `__aenter__`; `_requested_db_path` is what the caller asked for, and the effective path falls out of the resolved scope.
This commit is contained in:
parent
1b3334b5af
commit
4c2bfc4fc1
6 changed files with 15 additions and 35 deletions
|
|
@ -131,17 +131,6 @@ class EvidenceState(BaseModel):
|
|||
self.searches.clear()
|
||||
|
||||
|
||||
def covers_several_databases(scope: DatabaseScope, rag: "HaikuRAG | None") -> bool:
|
||||
"""Whether the capability will read from more than one database.
|
||||
|
||||
A lent client already covers what it covers; otherwise the scope says.
|
||||
Instructions follow coverage, not configuration.
|
||||
"""
|
||||
if rag is not None:
|
||||
return rag.covers_multiple
|
||||
return scope.covers_multiple
|
||||
|
||||
|
||||
def _awaits_the_model(messages: list[ModelMessage]) -> bool:
|
||||
"""Whether the history unmistakably leaves the model something to answer.
|
||||
|
||||
|
|
@ -637,6 +626,5 @@ class RAGCapabilityBase[StateT: EvidenceState](AbstractCapability[Any]):
|
|||
__all__ = [
|
||||
"CodeExecutionEntry",
|
||||
"RAGCapabilityBase",
|
||||
"covers_several_databases",
|
||||
"resolve_scope",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ from haiku.rag.capabilities._base import (
|
|||
CodeExecutionEntry,
|
||||
EvidenceState,
|
||||
RAGCapabilityBase,
|
||||
covers_several_databases,
|
||||
resolve_scope,
|
||||
)
|
||||
from haiku.rag.capabilities._tools import merge_results
|
||||
|
|
@ -215,7 +214,9 @@ def create_capability(
|
|||
analysis_model = config.analysis.model or config.qa.model
|
||||
scope = resolve_scope(db_path, config)
|
||||
instruction_text = instructions()
|
||||
if covers_several_databases(scope, rag):
|
||||
# A lent client covers what it covers; otherwise the scope says.
|
||||
several = rag.covers_multiple if rag is not None else scope.covers_multiple
|
||||
if several:
|
||||
instruction_text += several_databases_instructions()
|
||||
return AnalysisCapability(
|
||||
scope=scope,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ if TYPE_CHECKING:
|
|||
from haiku.rag.capabilities._base import (
|
||||
EvidenceState,
|
||||
RAGCapabilityBase,
|
||||
covers_several_databases,
|
||||
resolve_scope,
|
||||
)
|
||||
from haiku.rag.config.models import AppConfig
|
||||
|
|
@ -118,7 +117,9 @@ def create_capability(
|
|||
config = get_config()
|
||||
scope = resolve_scope(db_path, config)
|
||||
instruction_text = instructions()
|
||||
if covers_several_databases(scope, rag):
|
||||
# A lent client covers what it covers; otherwise the scope says.
|
||||
several = rag.covers_multiple if rag is not None else scope.covers_multiple
|
||||
if several:
|
||||
instruction_text += several_databases_instructions()
|
||||
return RAGCapability(
|
||||
scope=scope,
|
||||
|
|
|
|||
|
|
@ -148,11 +148,7 @@ class HaikuRAG:
|
|||
# single-database configuration from it, and asking again has to see the
|
||||
# same set rather than the answer from last time.
|
||||
self._config = self._configured
|
||||
self._db_path_given = db_path is not None
|
||||
if db_path is None:
|
||||
db_path = self._config.storage.data_dir / "haiku.rag.lancedb"
|
||||
|
||||
self._db_path = db_path
|
||||
self._requested_db_path = Path(db_path) if db_path is not None else None
|
||||
self._skip_validation = skip_validation
|
||||
self._create = create
|
||||
self._read_only = read_only
|
||||
|
|
@ -285,10 +281,9 @@ class HaikuRAG:
|
|||
if self._scope is not None:
|
||||
return self._scope
|
||||
scope = DatabaseScope.resolve(
|
||||
self._configured,
|
||||
database_path=self._db_path if self._db_path_given else None,
|
||||
self._configured, database_path=self._requested_db_path
|
||||
)
|
||||
if self._requested_sources is not None and not self._db_path_given:
|
||||
if self._requested_sources is not None and self._requested_db_path is None:
|
||||
scope = scope.select(self._requested_sources)
|
||||
return scope
|
||||
|
||||
|
|
@ -326,12 +321,9 @@ class HaikuRAG:
|
|||
|
||||
[ref] = scope.databases
|
||||
self._config, db_path = ref.connection(self._configured)
|
||||
self._db_path = (
|
||||
db_path if db_path is not None else default_db_path(self._config)
|
||||
)
|
||||
|
||||
self._session = await SingleDatabaseSession(
|
||||
self._db_path,
|
||||
db_path if db_path is not None else default_db_path(self._config),
|
||||
self._config,
|
||||
skip_validation=self._skip_validation,
|
||||
create=self._create,
|
||||
|
|
|
|||
|
|
@ -117,12 +117,10 @@ SearchType = Literal["vector", "fts", "hybrid"]
|
|||
|
||||
|
||||
def qualified_id(source: str | None, id: str | None) -> tuple[str | None, str | None]:
|
||||
"""What tells one chunk from another: a chunk id is unique within a database
|
||||
and says nothing across them.
|
||||
"""What tells one chunk from another: an id is unique within a database only.
|
||||
|
||||
For in-memory structures only. Everything serialized records the id alone
|
||||
and rejects ambiguity instead. `id` is optional, and results built by hand
|
||||
carry none and cannot be told apart.
|
||||
For in-memory structures. Serialized ones record the id alone and reject
|
||||
ambiguity instead. Results built by hand carry no id and cannot be told apart.
|
||||
"""
|
||||
return (source, id)
|
||||
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@ def test_default_db_path_comes_from_storage_data_dir(tmp_path):
|
|||
config = AppConfig()
|
||||
config.storage.data_dir = tmp_path
|
||||
|
||||
client = HaikuRAG(config=config)
|
||||
[ref] = HaikuRAG(config=config)._resolve_scope().databases
|
||||
|
||||
assert client._db_path == tmp_path / "haiku.rag.lancedb"
|
||||
assert ref.db_path == tmp_path / "haiku.rag.lancedb"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
|
|||
Loading…
Reference in a new issue