feat: natural language queries respect UI filters (v1.2.0)
- AskRequest now accepts optional filter fields: services, actor, operation, result, start, end, include_tags, exclude_tags - ask_question merges NL-extracted constraints with explicit UI filters - Frontend sends active filter state with every ask request - Show filter hint below ask input when filters are active - Add tests for service+result filtering and actor filtering in /api/ask Bump version to 1.2.0
This commit is contained in:
@@ -277,3 +277,76 @@ class TestAskEndpoint:
|
||||
assert data["llm_used"] is False # Falls back
|
||||
assert len(data["events"]) == 1
|
||||
assert "Found 1 event" in data["answer"]
|
||||
|
||||
def test_ask_with_explicit_filters(self, client, mock_events_collection):
|
||||
now = datetime.now(UTC)
|
||||
mock_events_collection.insert_one(
|
||||
{
|
||||
"id": "evt-exchange",
|
||||
"timestamp": now.isoformat(),
|
||||
"service": "Exchange",
|
||||
"operation": "Update",
|
||||
"result": "failure",
|
||||
"actor_display": "Alice",
|
||||
"target_displays": ["LAPTOP-001"],
|
||||
"display_summary": "summary",
|
||||
"raw_text": "raw",
|
||||
}
|
||||
)
|
||||
mock_events_collection.insert_one(
|
||||
{
|
||||
"id": "evt-directory",
|
||||
"timestamp": now.isoformat(),
|
||||
"service": "Directory",
|
||||
"operation": "Add user",
|
||||
"result": "success",
|
||||
"actor_display": "Alice",
|
||||
"target_displays": ["LAPTOP-001"],
|
||||
"display_summary": "summary",
|
||||
"raw_text": "raw",
|
||||
}
|
||||
)
|
||||
response = client.post(
|
||||
"/api/ask",
|
||||
json={"question": "What happened to LAPTOP-001?", "services": ["Exchange"], "result": "failure"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["query_info"]["event_count"] == 1
|
||||
assert data["events"][0]["id"] == "evt-exchange"
|
||||
|
||||
def test_ask_with_explicit_actor_filter(self, client, mock_events_collection):
|
||||
now = datetime.now(UTC)
|
||||
mock_events_collection.insert_one(
|
||||
{
|
||||
"id": "evt-bob",
|
||||
"timestamp": now.isoformat(),
|
||||
"service": "Directory",
|
||||
"operation": "Add user",
|
||||
"result": "success",
|
||||
"actor_display": "Bob",
|
||||
"actor_upn": "bob@example.com",
|
||||
"target_displays": ["USER-001"],
|
||||
"display_summary": "summary",
|
||||
"raw_text": "raw",
|
||||
}
|
||||
)
|
||||
mock_events_collection.insert_one(
|
||||
{
|
||||
"id": "evt-alice",
|
||||
"timestamp": now.isoformat(),
|
||||
"service": "Directory",
|
||||
"operation": "Remove user",
|
||||
"result": "success",
|
||||
"actor_display": "Alice",
|
||||
"actor_upn": "alice@example.com",
|
||||
"target_displays": ["USER-001"],
|
||||
"display_summary": "summary",
|
||||
"raw_text": "raw",
|
||||
}
|
||||
)
|
||||
response = client.post("/api/ask", json={"question": "What happened to USER-001?", "actor": "bob"})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["query_info"]["event_count"] == 1
|
||||
assert data["events"][0]["id"] == "evt-bob"
|
||||
|
||||
Reference in New Issue
Block a user