diff --git a/CHANGELOG.md b/CHANGELOG.md index 51c3e281..0dcd837a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - **Document virtual filesystem in analysis sandbox**: Documents are mounted at `/documents/{id}/` with `metadata.json` (eager), `content.txt` (lazy), and `items.jsonl` (lazy). The agent uses standard Python `pathlib.Path` to browse and read document content and structure. - **`doc_item_refs` and `labels` in search results**: Search results now include document item references and labels for cross-referencing with `items.jsonl`. +- **`--skill` flag for chat TUI**: `haiku-rag chat -s rag -s analysis` to enable specific skills. Defaults to `rag`. Use `-s analysis` for code execution, or both for the full toolset. ### Changed diff --git a/docs/apps.md b/docs/apps.md index 570c78bb..b15ef5db 100644 --- a/docs/apps.md +++ b/docs/apps.md @@ -14,6 +14,12 @@ Conversational RAG from the terminal with streaming responses and session memory ```bash haiku-rag chat haiku-rag chat --db /path/to/database.lancedb + +# Enable analysis skill (code execution) +haiku-rag chat -s rag -s analysis + +# Analysis only +haiku-rag chat -s analysis ``` ### Interface diff --git a/docs/cli.md b/docs/cli.md index 842e9293..835597b8 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -165,11 +165,18 @@ Launch an interactive chat session for multi-turn conversations: ```bash haiku-rag chat haiku-rag chat --db /path/to/database.lancedb + +# Enable analysis skill (code execution) +haiku-rag chat -s rag -s analysis ``` !!! note Requires the `tui` extra: `pip install haiku.rag-slim[tui]` (included in full `haiku.rag` package) +Flags: + +- `--skill` / `-s`: Skills to enable — `rag` (default), `analysis`. Can be repeated for multiple skills. + The chat interface provides: - Streaming responses with real-time tool execution diff --git a/haiku_rag_slim/haiku/rag/chat/__init__.py b/haiku_rag_slim/haiku/rag/chat/__init__.py index 78a1d341..d635c10d 100644 --- a/haiku_rag_slim/haiku/rag/chat/__init__.py +++ b/haiku_rag_slim/haiku/rag/chat/__init__.py @@ -7,6 +7,7 @@ def run_chat( read_only: bool = False, before: datetime | None = None, model: str | None = None, + skills: list[str] | None = None, ) -> None: """Run the chat TUI. @@ -15,6 +16,7 @@ def run_chat( read_only: Whether to open the database in read-only mode. before: Query database as it existed before this datetime. model: Model to use for the chat. + skills: Skills to enable ("rag", "analysis"). Defaults to ["rag"]. """ try: from haiku.rag.chat.app import ChatApp @@ -24,18 +26,29 @@ def run_chat( ) from e from haiku.rag.config import get_config - from haiku.rag.skills.rag import create_skill from haiku.rag.utils import get_model + from haiku.skills.models import Skill config = get_config() if db_path is None: db_path = config.storage.data_dir / "haiku.rag.lancedb" - skill = create_skill(db_path=db_path, config=config) + enabled = skills or ["rag"] + skill_list: list[Skill] = [] + + if "rag" in enabled: + from haiku.rag.skills.rag import create_skill as create_rag_skill + + skill_list.append(create_rag_skill(db_path=db_path, config=config)) + + if "analysis" in enabled: + from haiku.rag.skills.analysis import create_skill as create_analysis_skill + + skill_list.append(create_analysis_skill(db_path=db_path, config=config)) app = ChatApp( db_path, - skill=skill, + skills=skill_list, read_only=read_only, before=before, model=model or get_model(config.qa.model, config), diff --git a/haiku_rag_slim/haiku/rag/chat/app.py b/haiku_rag_slim/haiku/rag/chat/app.py index 5d6bcb14..834b66a0 100644 --- a/haiku_rag_slim/haiku/rag/chat/app.py +++ b/haiku_rag_slim/haiku/rag/chat/app.py @@ -86,14 +86,14 @@ class ChatApp(App): def __init__( self, db_path: Path, - skill: Skill, + skills: list[Skill], read_only: bool = False, before: datetime | None = None, model: str | None = None, ) -> None: super().__init__() self.db_path = db_path - self._skill = skill + self._skills = skills self.read_only = read_only self.before = before self._model = model @@ -153,7 +153,7 @@ class ChatApp(App): ) await self.client.__aenter__() - self._toolset = SkillToolset(skills=[self._skill]) + self._toolset = SkillToolset(skills=self._skills) self._agent = Agent( self._model, instructions=build_system_prompt( diff --git a/haiku_rag_slim/haiku/rag/cli.py b/haiku_rag_slim/haiku/rag/cli.py index 30d14657..1210d73b 100644 --- a/haiku_rag_slim/haiku/rag/cli.py +++ b/haiku_rag_slim/haiku/rag/cli.py @@ -645,17 +645,25 @@ def chat( # pragma: no cover "--model", help="Model to use for the chat (e.g. openai:gpt-4o)", ), + skill: list[str] | None = typer.Option( + None, + "--skill", + "-s", + help="Skills to enable: rag, analysis (can repeat, default: rag)", + ), ): """Launch the chat TUI for conversational RAG.""" from haiku.rag.chat import run_chat db_path = db if db else get_config().storage.data_dir / "haiku.rag.lancedb" + skills = skill if skill else ["rag"] run_chat( db_path, read_only=_read_only, before=_before, model=model, + skills=skills, ) diff --git a/tests/chat/test_chat_app.py b/tests/chat/test_chat_app.py index dcfd572a..84324bb1 100644 --- a/tests/chat/test_chat_app.py +++ b/tests/chat/test_chat_app.py @@ -57,7 +57,7 @@ def _make_app(db_path: Path, mock_client: AsyncMock | None = None): return ChatApp( db_path=db_path, - skill=skill, + skills=[skill], read_only=True, ), mock_client @@ -80,7 +80,7 @@ def _make_app_with_state(db_path: Path, mock_client: AsyncMock | None = None): return ChatApp( db_path=db_path, - skill=skill, + skills=[skill], read_only=True, ), mock_client