diff --git a/app/frontend/lib/sessionStorage.ts b/app/frontend/lib/sessionStorage.ts index 47737433..22a6b75f 100644 --- a/app/frontend/lib/sessionStorage.ts +++ b/app/frontend/lib/sessionStorage.ts @@ -9,20 +9,12 @@ export interface Citation { content: string; } -export interface DocumentInfo { - id: string; - title: string; - uri: string; - created: string; -} - // Matches RAGState from the backend skill export interface RAGState { citation_index: Record; citations: string[][]; document_filter: string | null; searches: Record; - documents: DocumentInfo[]; } export interface StoredMessage { @@ -50,7 +42,6 @@ export function normalizeRAGState(state?: Partial): RAGState { citations: state?.citations ?? [], document_filter: state?.document_filter ?? null, searches: state?.searches ?? {}, - documents: state?.documents ?? [], }; } diff --git a/haiku_rag_slim/haiku/rag/skill_generator/templates/__init__.py.j2 b/haiku_rag_slim/haiku/rag/skill_generator/templates/__init__.py.j2 index 829d006b..f342e6ee 100644 --- a/haiku_rag_slim/haiku/rag/skill_generator/templates/__init__.py.j2 +++ b/haiku_rag_slim/haiku/rag/skill_generator/templates/__init__.py.j2 @@ -8,9 +8,6 @@ from haiku.skills.parser import parse_skill_md {% if "cite" in tool_names %} from haiku.rag.agents.research.models import Citation {% endif %} -{% if "search" in tool_names or "list_documents" in tool_names or "get_document" in tool_names %} -from haiku.rag.tools.document import DocumentInfo -{% endif %} {% if "search" in tool_names %} from haiku.rag.store.models.chunk import SearchResult {% endif %} @@ -38,9 +35,6 @@ class SkillState(BaseModel): {% if "search" in tool_names %} searches: dict[str, list[SearchResult]] = Field(default_factory=dict) {% endif %} -{% if "search" in tool_names or "list_documents" in tool_names or "get_document" in tool_names %} - documents: list[DocumentInfo] = Field(default_factory=list) -{% endif %} {% if "execute_code" in tool_names %} executions: list[CodeExecutionEntry] = Field(default_factory=list) {% endif %} diff --git a/haiku_rag_slim/haiku/rag/skills/_tools.py b/haiku_rag_slim/haiku/rag/skills/_tools.py index de37cf4a..8e7f9270 100644 --- a/haiku_rag_slim/haiku/rag/skills/_tools.py +++ b/haiku_rag_slim/haiku/rag/skills/_tools.py @@ -7,7 +7,6 @@ from pydantic_ai import RunContext from haiku.rag.agents.research.models import Citation from haiku.rag.config.models import AppConfig from haiku.rag.store.models.chunk import SearchResult -from haiku.rag.tools.document import DocumentInfo from haiku.skills.state import SkillRunDeps @@ -86,21 +85,6 @@ async def skill_get_document( } -def update_documents_state( - documents_state: list[DocumentInfo], - doc_dicts: list[dict[str, Any]], -) -> None: - for doc_dict in doc_dicts: - doc_info = DocumentInfo( - id=str(doc_dict["id"]), - title=doc_dict["title"] or "Untitled", - uri=doc_dict.get("uri") or "", - created=doc_dict.get("created_at", ""), - ) - if not any(d.id == doc_info.id for d in documents_state): - documents_state.append(doc_info) - - def _get_state(ctx: RunContext[SkillRunDeps], state_type: type[BaseModel]) -> Any: if ctx.deps and ctx.deps.state and isinstance(ctx.deps.state, state_type): return ctx.deps.state @@ -237,8 +221,6 @@ def create_skill_tools( config, filter=state.document_filter if state else None, ) - if state: - update_documents_state(state.documents, result) return result tools["list_documents"] = list_documents @@ -253,12 +235,7 @@ def create_skill_tools( Args: query: Document ID, title, or URI to look up. """ - result = await skill_get_document(db_path, config, query) - if result is not None: - state = _get_state(ctx, state_type) - if state: - update_documents_state(state.documents, [result]) - return result + return await skill_get_document(db_path, config, query) tools["get_document"] = get_document diff --git a/haiku_rag_slim/haiku/rag/skills/analysis.py b/haiku_rag_slim/haiku/rag/skills/analysis.py index 97f099cc..63d2ea2c 100644 --- a/haiku_rag_slim/haiku/rag/skills/analysis.py +++ b/haiku_rag_slim/haiku/rag/skills/analysis.py @@ -8,7 +8,6 @@ from haiku.rag.agents.research.models import Citation from haiku.rag.config.models import AppConfig from haiku.rag.skills._tools import CodeExecutionEntry from haiku.rag.store.models.chunk import SearchResult -from haiku.rag.tools.document import DocumentInfo from haiku.skills.models import Skill, SkillMetadata, SkillSource, StateMetadata from haiku.skills.parser import parse_skill_md @@ -19,7 +18,6 @@ class AnalysisState(BaseModel): citation_index: dict[str, Citation] = Field(default_factory=dict) citations: list[list[str]] = Field(default_factory=list) searches: dict[str, list[SearchResult]] = Field(default_factory=dict) - documents: list[DocumentInfo] = Field(default_factory=list) STATE_TYPE = AnalysisState diff --git a/haiku_rag_slim/haiku/rag/skills/rag.py b/haiku_rag_slim/haiku/rag/skills/rag.py index c1044831..a660c723 100644 --- a/haiku_rag_slim/haiku/rag/skills/rag.py +++ b/haiku_rag_slim/haiku/rag/skills/rag.py @@ -7,7 +7,6 @@ from pydantic import BaseModel, Field from haiku.rag.agents.research.models import Citation from haiku.rag.config.models import AppConfig from haiku.rag.store.models.chunk import SearchResult -from haiku.rag.tools.document import DocumentInfo from haiku.skills.models import Skill, SkillMetadata, SkillSource, StateMetadata from haiku.skills.parser import parse_skill_md @@ -34,7 +33,6 @@ class RAGState(BaseModel): citations: list[list[str]] = Field(default_factory=list) document_filter: str | None = None searches: dict[str, list[SearchResult]] = Field(default_factory=dict) - documents: list[DocumentInfo] = Field(default_factory=list) STATE_TYPE = RAGState diff --git a/tests/skills/test_rag.py b/tests/skills/test_rag.py index 10184bb6..d39f080b 100644 --- a/tests/skills/test_rag.py +++ b/tests/skills/test_rag.py @@ -8,7 +8,6 @@ from haiku.rag.skills.rag import ( state_metadata, ) from haiku.rag.store.models.chunk import SearchResult -from haiku.rag.tools.document import DocumentInfo from haiku.skills.models import SkillMetadata, StateMetadata from .conftest import _get_tool, _make_ctx @@ -213,17 +212,6 @@ class TestListDocumentsTool: assert isinstance(results, list) assert len(results) == 2 - async def test_list_documents_updates_state(self, rag_db): - from haiku.rag.skills.rag import RAGState, create_skill - - skill = create_skill(db_path=rag_db) - list_docs = _get_tool(skill, "list_documents") - state = RAGState() - ctx = _make_ctx(state) - await list_docs(ctx) - assert len(state.documents) == 2 - assert isinstance(state.documents[0], DocumentInfo) - async def test_list_documents_applies_document_filter_from_state(self, rag_db): from haiku.rag.skills.rag import RAGState, create_skill diff --git a/tests/test_skill_generator.py b/tests/test_skill_generator.py index d76f053b..40fde312 100644 --- a/tests/test_skill_generator.py +++ b/tests/test_skill_generator.py @@ -23,9 +23,8 @@ class TestAvailableTools: "list_documents", "get_document", "search", - "ask", - "research", - "analyze", + "execute_code", + "cite", } @@ -43,7 +42,7 @@ class TestValidateTools: validate_tools(["search"]) def test_valid_multiple_tools(self): - validate_tools(["list_documents", "get_document", "search", "ask"]) + validate_tools(["list_documents", "get_document", "search", "cite"]) def test_valid_all_tools(self): validate_tools(list(AVAILABLE_TOOLS)) @@ -97,7 +96,7 @@ class TestRenderTemplates: output_dir=tmp_path, name="recipes", description="A recipe skill.", - tool_names=["list_documents", "get_document", "search", "ask"], + tool_names=["list_documents", "get_document", "search", "cite"], ) assert result == tmp_path / "recipes-skill" assert result.is_dir() @@ -112,7 +111,7 @@ class TestRenderTemplates: output_dir=tmp_path, name="my-recipes", description="A recipe skill.", - tool_names=["search", "ask"], + tool_names=["search", "cite"], ) assert result == tmp_path / "my-recipes-skill" pkg = result / "my_recipes_skill" @@ -129,11 +128,11 @@ class TestRenderTemplates: output_dir=tmp_path, name="docs", description="A docs skill.", - tool_names=["search", "ask"], + tool_names=["search", "cite"], ) init = tmp_path / "docs-skill" / "docs_skill" / "__init__.py" content = init.read_text() - assert '["search", "ask"]' in content + assert '["search", "cite"]' in content def test_create_skill_tools_called(self, tmp_path): render_templates( @@ -151,12 +150,12 @@ class TestRenderTemplates: output_dir=tmp_path, name="recipes", description="A recipe skill.", - tool_names=["search", "ask"], + tool_names=["search", "cite"], ) init = tmp_path / "recipes-skill" / "recipes_skill" / "__init__.py" content = init.read_text() assert '"search"' in content - assert '"ask"' in content + assert '"cite"' in content def test_pyproject_toml(self, tmp_path): render_templates( @@ -184,24 +183,23 @@ class TestRenderTemplates: ) skill_md = tmp_path / "docs-skill" / "docs_skill" / "SKILL.md" content = skill_md.read_text() - assert "**search**" in content - assert "**ask**" not in content - assert "**list_documents**" not in content - assert "**research**" not in content - assert "**analyze**" not in content + assert "### search" in content + assert "### cite" not in content + assert "### list_documents" not in content + assert "### execute_code" not in content def test_skill_md_includes_all_selected(self, tmp_path): render_templates( output_dir=tmp_path, name="docs", description="A docs skill.", - tool_names=["search", "ask", "analyze"], + tool_names=["search", "execute_code", "cite"], ) skill_md = tmp_path / "docs-skill" / "docs_skill" / "SKILL.md" content = skill_md.read_text() - assert "**search**" in content - assert "**ask**" in content - assert "**analyze**" in content + assert "search" in content + assert "execute_code" in content + assert "cite" in content def test_custom_preamble(self, tmp_path): render_templates( @@ -226,23 +224,23 @@ class TestRenderTemplates: content = init.read_text() assert 'state_namespace="recipes"' in content - def test_analyze_state_fields(self, tmp_path): + def test_execute_code_state_fields(self, tmp_path): render_templates( output_dir=tmp_path, name="docs", description="A docs skill.", - tool_names=["search", "analyze"], + tool_names=["search", "execute_code"], ) init = tmp_path / "docs-skill" / "docs_skill" / "__init__.py" content = init.read_text() - assert "analyses" in content + assert "executions" in content def test_imports_from_shared_tools(self, tmp_path): render_templates( output_dir=tmp_path, name="recipes", description="A recipe skill.", - tool_names=["search", "ask", "analyze"], + tool_names=["search", "execute_code", "cite"], ) init = tmp_path / "recipes-skill" / "recipes_skill" / "__init__.py" content = init.read_text() @@ -329,7 +327,7 @@ class TestGenerateSkill: output_dir=tmp_path, name="recipes", description="A recipe skill.", - tool_names=["search", "ask"], + tool_names=["search", "cite"], ) assert result == tmp_path / "recipes-skill" assets = result / "recipes_skill" / "assets" @@ -479,7 +477,7 @@ class TestGenerateSkillRemote: output_dir=tmp_path, name="recipes", description="A recipe skill.", - tool_names=["search", "ask"], + tool_names=["search", "cite"], config_path=config_file, ) assets = result / "recipes_skill" / "assets"