haiku.rag/haiku_rag_slim/haiku/rag/chat/__init__.py
Yiorgis Gozadinos 9baa213b34
Hand storage the database location, not the configuration that placed it
Store, connect_lancedb, gather_database_info and run_doctor take a
location, a path or a URI, and classify it with ConnectionMode.of.
SingleDatabaseSession owns the resolved DatabaseRef and passes its
location down. This removes DatabaseRef.connection(), default_db_path,
the placeholder path for URI-backed databases and the per-database
config copies, so the configuration a client holds is the one the caller
gave it. The chat hands its capabilities the scope it opened along with
the client it lends, and the v0.58.0 migration no longer checks local
free disk for a database behind a URI.
2026-09-03 15:11:37 +03:00

88 lines
2.8 KiB
Python

from pathlib import Path
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from haiku.rag.client.scope import DatabaseScope
def run_chat(
db_path: Path | None = None,
read_only: bool = False,
model: str | None = None,
capabilities: list[str] | None = None,
scope: "DatabaseScope | None" = None,
) -> None:
"""Run the chat TUI.
Args:
db_path: Path to the LanceDB database, when no scope is given.
scope: The databases to cover, resolved by the caller.
read_only: Whether to open the database in read-only mode.
model: Model to use for the chat.
capabilities: Capabilities to enable ("rag", "analysis"). Defaults to ["rag"].
"""
try:
from haiku.rag.chat.app import ChatApp
except ImportError as e:
raise ImportError(
"textual is not installed. Please install it with `pip install 'haiku.rag-slim[tui]'` or use the full haiku.rag package."
) from e
from haiku.rag.config import get_config
from haiku.rag.utils import get_model, parse_model_option
config = get_config()
if scope is None:
from haiku.rag.client.scope import DatabaseScope
scope = DatabaseScope.resolve(config, database_path=db_path)
if model:
model_config = parse_model_option(model)
config.qa.model = model_config
config.analysis.model = model_config
# The app opens the scope and lends that client to the capabilities, which
# read what `--db PATH` or `--db-name NAME` selected.
enabled = capabilities or ["rag"]
capability_list = []
defer_loading = len(enabled) > 1
# One agent drives every attached capability, so a capability's
# image-attachment gate must track that single model: analysis.model only
# when analysis runs alone, otherwise qa.model. Passing it to every
# capability keeps their vision flag aligned with the model actually running.
if "rag" not in enabled and "analysis" in enabled:
driving_model = config.analysis.model or config.qa.model
else:
driving_model = config.qa.model
if "rag" in enabled:
from haiku.rag.capabilities.rag import create_capability
capability_list.append(
create_capability(
config=config,
defer_loading=defer_loading,
vision=driving_model.vision,
)
)
if "analysis" in enabled:
from haiku.rag.capabilities.analysis import create_capability
capability_list.append(
create_capability(
config=config,
defer_loading=defer_loading,
vision=driving_model.vision,
)
)
app = ChatApp(
capabilities=capability_list,
read_only=read_only,
model=model or get_model(driving_model, config),
scope=scope,
)
app.run()