Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/lightspeed_evaluation/core/models/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,14 @@ class EvaluationData(BaseModel):
min_length=1,
description="Tag for grouping and filtering conversations",
)
skip: bool = Field(
default=False,
description="Skip this conversation during evaluation",
)
skip_reason: Optional[str] = Field(
default=None,
description="Why this conversation is skipped (documentation only)",
)

# Conversation-level metrics
conversation_metrics: Optional[list[str]] = Field(
Expand Down
3 changes: 3 additions & 0 deletions src/lightspeed_evaluation/core/system/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ def load_evaluation_data(
# Filter by scope before validation
evaluation_data = self._filter_by_scope(evaluation_data, tags, conv_ids)

# Remove skipped conversations
evaluation_data = [e for e in evaluation_data if not e.skip]

# Filter turn_metrics if --metrics was specified
if metrics:
metrics_set = set(metrics)
Expand Down
41 changes: 41 additions & 0 deletions tests/unit/core/system/test_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,3 +581,44 @@ def test_filter_by_scope_no_match_returns_empty(self) -> None:
]
result = validator._filter_by_scope(data, tags=["nonexistent"])
assert len(result) == 0

def test_skip_removes_conversation(self, mocker: MockerFixture) -> None:
"""Test that conversations with skip=True are excluded."""
yaml_data = [
{
"conversation_group_id": "active",
"turns": [{"turn_id": "t1", "query": "Q", "response": "A"}],
},
{
"conversation_group_id": "skipped",
"skip": True,
"skip_reason": "Test needs rewrite",
"turns": [{"turn_id": "t1", "query": "Q", "response": "A"}],
},
{
"conversation_group_id": "also_active",
"turns": [{"turn_id": "t1", "query": "Q", "response": "A"}],
},
]
mocker.patch("builtins.open", mocker.mock_open(read_data=""))
mocker.patch("yaml.safe_load", return_value=yaml_data)
validator = DataValidator()
result = validator.load_evaluation_data("dummy.yaml")
assert len(result) == 2
assert {r.conversation_group_id for r in result} == {"active", "also_active"}

def test_skip_false_keeps_conversation(self, mocker: MockerFixture) -> None:
"""Test that skip=False does not exclude the conversation."""
yaml_data = [
{
"conversation_group_id": "explicit_no_skip",
"skip": False,
"turns": [{"turn_id": "t1", "query": "Q", "response": "A"}],
},
]
mocker.patch("builtins.open", mocker.mock_open(read_data=""))
mocker.patch("yaml.safe_load", return_value=yaml_data)
validator = DataValidator()
result = validator.load_evaluation_data("dummy.yaml")
assert len(result) == 1
assert result[0].conversation_group_id == "explicit_no_skip"
Loading