fix skill analyze tool ignores state.document_filter
This commit is contained in:
parent
99af4fe11d
commit
a51b922be3
5 changed files with 58 additions and 5 deletions
|
|
@ -9,6 +9,7 @@
|
|||
### Fixed
|
||||
|
||||
- **Skill `list_documents` ignores `document_filter`**: `list_documents` tool now respects `state.document_filter`, consistent with `search`, `ask`, and `research`
|
||||
- **Skill `analyze` ignores `document_filter`**: `analyze` tool now uses `state.document_filter` (combined with any explicit `filter` parameter). Added `document_filter` field to `RLMState`
|
||||
|
||||
## [0.38.0] - 2026-04-07
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ The skill manages an `RLMState` under the `"rlm"` namespace:
|
|||
|
||||
```python
|
||||
class RLMState(BaseModel):
|
||||
document_filter: str | None = None
|
||||
analyses: list[AnalysisEntry] = []
|
||||
|
||||
class AnalysisEntry(BaseModel):
|
||||
|
|
@ -41,7 +42,8 @@ class AnalysisEntry(BaseModel):
|
|||
program: str | None = None
|
||||
```
|
||||
|
||||
Each `analyze` call appends an `AnalysisEntry` with the question, answer, and executed program.
|
||||
- **document_filter** — SQL WHERE clause applied to `analyze` calls (combined with any explicit `filter` parameter). Set this to scope analysis to specific documents.
|
||||
- **analyses** — Each `analyze` call appends an `AnalysisEntry` with the question, answer, and executed program.
|
||||
|
||||
## Usage with RAG Skill
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ 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.rag.tools.filters import combine_filters
|
||||
from haiku.rag.tools.qa import QAHistoryEntry
|
||||
from haiku.skills.state import SkillRunDeps
|
||||
|
||||
|
|
@ -476,11 +477,12 @@ def create_skill_tools(
|
|||
document: Optional document ID or title to pre-load for analysis.
|
||||
filter: Optional SQL WHERE clause to filter documents.
|
||||
"""
|
||||
output, answer, program = await skill_analyze(
|
||||
db_path, config, question, document=document, filter=filter
|
||||
)
|
||||
|
||||
state = _get_state(ctx, state_type)
|
||||
state_filter = state.document_filter if state else None
|
||||
effective_filter = combine_filters(state_filter, filter)
|
||||
output, answer, program = await skill_analyze(
|
||||
db_path, config, question, document=document, filter=effective_filter
|
||||
)
|
||||
if state:
|
||||
state.analyses.append(
|
||||
AnalysisEntry(
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from haiku.skills.parser import parse_skill_md
|
|||
|
||||
|
||||
class RLMState(BaseModel):
|
||||
document_filter: str | None = None
|
||||
analyses: list[AnalysisEntry] = []
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -155,6 +155,53 @@ class TestAnalyzeTool:
|
|||
assert state.analyses[0].answer == "42"
|
||||
assert state.analyses[0].program == "print(42)"
|
||||
|
||||
async def test_analyze_applies_document_filter_from_state(
|
||||
self, rag_db, monkeypatch
|
||||
):
|
||||
from haiku.rag.skills.rlm import RLMState, create_skill
|
||||
|
||||
captured_kwargs = {}
|
||||
|
||||
async def mock_rlm(self, question, **kwargs):
|
||||
captured_kwargs.update(kwargs)
|
||||
return RLMResult(answer="42", program="print(42)")
|
||||
|
||||
monkeypatch.setattr(HaikuRAG, "rlm", mock_rlm)
|
||||
|
||||
skill = create_skill(db_path=rag_db)
|
||||
analyze = _get_tool(skill, "analyze")
|
||||
state = RLMState(document_filter="title = 'AI Overview'")
|
||||
ctx = _make_ctx(state)
|
||||
await analyze(ctx, question="How many documents?")
|
||||
assert captured_kwargs.get("filter") == "title = 'AI Overview'"
|
||||
|
||||
async def test_analyze_combines_state_filter_with_explicit_filter(
|
||||
self, rag_db, monkeypatch
|
||||
):
|
||||
from haiku.rag.skills.rlm import RLMState, create_skill
|
||||
|
||||
captured_kwargs = {}
|
||||
|
||||
async def mock_rlm(self, question, **kwargs):
|
||||
captured_kwargs.update(kwargs)
|
||||
return RLMResult(answer="Result", program="code()")
|
||||
|
||||
monkeypatch.setattr(HaikuRAG, "rlm", mock_rlm)
|
||||
|
||||
skill = create_skill(db_path=rag_db)
|
||||
analyze = _get_tool(skill, "analyze")
|
||||
state = RLMState(document_filter="title = 'AI Overview'")
|
||||
ctx = _make_ctx(state)
|
||||
await analyze(
|
||||
ctx,
|
||||
question="Count pages",
|
||||
filter="uri LIKE '%test%'",
|
||||
)
|
||||
result_filter = captured_kwargs["filter"]
|
||||
assert isinstance(result_filter, str)
|
||||
assert "title = 'AI Overview'" in result_filter
|
||||
assert "uri LIKE '%test%'" in result_filter
|
||||
|
||||
async def test_analyze_with_document_and_filter(self, rag_db, monkeypatch):
|
||||
from haiku.rag.skills.rlm import create_skill
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue