Correct what the client and the docs claim
`HaikuRAG.__init__` said an omitted `db_path` uses `storage.data_dir`, which is the last of three; and that `sources` is ignored for a single `uri`, where it raises, since only `lancedb.databases` names databases. The name is not the only identity leaving the configuration: results, citations, model input and errors opening a named database carry it, while `info`, `init` and `tag` print the location. `sources=[]` returns no search results, but `ask` and `analyze` still answer, without evidence. Trim the comments that still narrated a failure or an alternative to the invariant they were there for.
This commit is contained in:
parent
ca2e28559e
commit
8f41d42ab2
7 changed files with 31 additions and 40 deletions
|
|
@ -214,9 +214,10 @@ lancedb:
|
|||
A location is a URI or a local path. `databases` and `uri` are mutually
|
||||
exclusive, and setting both fails validation.
|
||||
|
||||
The name is the only identity that leaves the configuration. Results, citations
|
||||
and error messages carry it, so a path or a bucket never reaches a log, a trace
|
||||
or a model.
|
||||
Results, citations, model input and errors opening a named database carry the
|
||||
configured name rather than the location, so a path or a bucket does not reach a
|
||||
trace or a model. Commands that report on a database — `info`, `init`, `tag` —
|
||||
print its location, as does an error about a path.
|
||||
|
||||
Every database in the set is opened with the same embedding configuration. A
|
||||
different `vector_dim` raises `ConfigMismatchError` on open. A different provider
|
||||
|
|
|
|||
|
|
@ -258,8 +258,9 @@ result = await client.analyze("How many documents mention it?", sources=["medic"
|
|||
A question scoped to some databases can only cite those, and the analysis
|
||||
sandbox mounts only their documents.
|
||||
|
||||
`sources=None` covers every database the client covers; `sources=[]` covers none
|
||||
and returns nothing, which is not the same thing.
|
||||
`sources=None` covers every database the client covers. `sources=[]` covers
|
||||
none: `search` returns no results, and `ask` and `analyze` run with no evidence
|
||||
from any database.
|
||||
|
||||
#### Asking a client what it covers
|
||||
|
||||
|
|
|
|||
|
|
@ -59,9 +59,8 @@ class HaikuRAGApp:
|
|||
def _connection(self) -> "tuple[AppConfig, Path]":
|
||||
"""How to open the one database this command works on, directly.
|
||||
|
||||
The configuration a command was given names a *set*; the one it opens
|
||||
needs its own, or a named database behind a URI is opened as the local
|
||||
path that stands in for it.
|
||||
Derived per database: opening one of a set against the set's own
|
||||
configuration would reach the local path that stands in for it.
|
||||
"""
|
||||
from haiku.rag.client.session import default_db_path
|
||||
|
||||
|
|
|
|||
|
|
@ -146,9 +146,8 @@ class DocumentFilterModal(ModalScreen):
|
|||
filter_list = self.query_one("#filter-list", VerticalScroll)
|
||||
await filter_list.remove_children()
|
||||
|
||||
# The page is picked to represent every database; sorting is so it reads
|
||||
# like a list rather than in whatever order the tables returned. The label
|
||||
# names the database, since a title alone does not say which one it is in.
|
||||
# Sort the interleaved page and label each document's database, which
|
||||
# a title alone does not say.
|
||||
labelled = sorted(
|
||||
(
|
||||
(
|
||||
|
|
|
|||
|
|
@ -133,15 +133,17 @@ class HaikuRAG:
|
|||
"""Initialize the RAG client with a database path.
|
||||
|
||||
Args:
|
||||
db_path: Path or string path to the database file. If None, uses
|
||||
config.storage.data_dir.
|
||||
db_path: Path or string path to the database. When omitted, resolves
|
||||
``lancedb.databases``, then ``lancedb.uri``, then the default
|
||||
path under ``storage.data_dir``.
|
||||
config: Configuration to use. Defaults to the current global config.
|
||||
skip_validation: Whether to skip configuration validation on database load.
|
||||
create: Whether to create the database if it doesn't exist.
|
||||
read_only: Whether to open the database in read-only mode.
|
||||
sources: Names from ``config.lancedb.databases`` this client covers.
|
||||
None means all of them. Ignored when a single ``uri`` or an
|
||||
explicit ``db_path`` is given.
|
||||
sources: Names from ``config.lancedb.databases`` this client covers,
|
||||
None for all of them. Only that setting names databases, so a
|
||||
name raises when ``lancedb.uri`` placed the database. Ignored
|
||||
when ``db_path`` says which database to open.
|
||||
"""
|
||||
self._configured = config if config is not None else get_config()
|
||||
# What the caller configured, kept intact: entering derives a
|
||||
|
|
@ -290,14 +292,9 @@ class HaikuRAG:
|
|||
async def __aenter__(self):
|
||||
"""Async context manager entry — initializes store and repositories.
|
||||
|
||||
A client borrowing a database is already open and returns itself.
|
||||
Opening a second session would leak it: teardown declines to close what
|
||||
this client did not open.
|
||||
|
||||
A client covering several databases opens none of them here: which are
|
||||
searched is a per-query choice, so they open on first use. `store` and the
|
||||
repositories stay unset in that case, since they have no unambiguous
|
||||
meaning across a set.
|
||||
A borrowed client reuses its session, which its owner closes. A client
|
||||
covering several opens their sessions lazily, so `store` and the
|
||||
repositories stay unset until one database is named.
|
||||
"""
|
||||
if not self._owns_session:
|
||||
assert self._session is not None
|
||||
|
|
|
|||
|
|
@ -93,32 +93,27 @@ class SingleDatabaseSession:
|
|||
create=self._create,
|
||||
read_only=self.read_only,
|
||||
)
|
||||
# If _initialize fails mid-way (e.g. migration check raises after
|
||||
# connect), close the store so we don't leak the LanceDB connection —
|
||||
# the caller's `async with` never entered, so its exit won't run.
|
||||
# Close a partially initialized store: the caller's `async with`
|
||||
# never entered, so its exit will not run.
|
||||
try:
|
||||
await self.store._initialize()
|
||||
except BaseException:
|
||||
self.store.close()
|
||||
raise
|
||||
except _NAMEABLE_FAILURES as error:
|
||||
# These say what to run and never where the database is, so the name
|
||||
# is added to the message rather than replacing it: the operator needs
|
||||
# both which database failed and what to do about it.
|
||||
# These name the remedy and not the database, so the name is added
|
||||
# rather than substituted.
|
||||
if self.source is None:
|
||||
raise
|
||||
raise type(error)(f"database {self.source!r}: {error}") from error
|
||||
except Exception as error:
|
||||
# A legacy `uri` or `db_path` session has no name to report instead,
|
||||
# so its error passes through as it always has.
|
||||
# Without a name there is nothing to report in the location's place.
|
||||
if self.source is None:
|
||||
raise
|
||||
failure = type(error).__name__
|
||||
if failure is not None:
|
||||
# Raised outside the except block on purpose. A database named in
|
||||
# config is reported by name, and the original spells out the path or
|
||||
# the bucket: `from None` would only stop it being *printed*, leaving
|
||||
# it on `__context__` for anything that walks the chain.
|
||||
# Raised outside the handler to discard the location-bearing
|
||||
# context, which `from None` would only stop printing.
|
||||
raise SourceUnavailableError(
|
||||
f"database {self.source!r} could not be opened: {failure}"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -247,10 +247,9 @@ class Sandbox:
|
|||
async def _documents(self) -> "tuple[list[Any], dict[str, HaikuRAG]]":
|
||||
"""Every document in scope, and the client holding each of them.
|
||||
|
||||
The owners are empty where one connection serves every read: a single
|
||||
database, or the ephemeral connection opened per read when no client was
|
||||
supplied. The selection is resolved the same way a search resolves it, so
|
||||
a database the question excluded cannot be mounted.
|
||||
Owners are empty where one connection serves every read. The selection
|
||||
resolves as a search resolves it, so a database the question excluded
|
||||
cannot be mounted.
|
||||
"""
|
||||
async with self._connection() as rag:
|
||||
if not rag.covers_multiple:
|
||||
|
|
|
|||
Loading…
Reference in a new issue