fix(context): repair three errored semantic context search BDD scenarios
CI / push-validation (pull_request) Successful in 34s
CI / build (pull_request) Successful in 53s
CI / helm (pull_request) Successful in 56s
CI / lint (pull_request) Successful in 58s
CI / quality (pull_request) Successful in 59s
CI / security (pull_request) Successful in 1m10s
CI / typecheck (pull_request) Successful in 1m17s
CI / unit_tests (pull_request) Successful in 4m41s
CI / docker (pull_request) Successful in 1m37s
CI / coverage (pull_request) Failing after 8m45s
CI / integration_tests (pull_request) Failing after 23m39s
CI / status-check (pull_request) Has been cancelled

Three scenarios in features/semantic_context_search.feature were erroring
during behave execution, surfacing as test setup/teardown errors in CI's
unit_tests gate. Each had a distinct root cause:

1. "Filter fragments by minimum similarity threshold" (line 30) referenced
   context.ranked_fragments inside step_filter_by_threshold, but the
   scenario filters directly without first running the "rank fragments"
   step that populates that attribute. The filter step now computes
   per-fragment similarity inline from context.fragments +
   context.query_embedding so it works regardless of whether a prior
   ranking step ran.

2. "Semantic strategy selects relevant files" (line 41) constructed
   ContextFragment with a FragmentProvenance imported from
   cleveragents.domain.models.acms.crp. The core ContextFragment's
   provenance field is annotated with the core FragmentProvenance subclass
   (which adds resource_type), and pydantic v2's strict model_type check
   rejects a bare CRP-base instance. Switched the import to the core
   FragmentProvenance so the type matches.

3. "Embedding provider configuration" (line 53) stored its provider config
   on context.config. Behave's Context reserves the config attribute for
   its own Configuration object; user assignment raises KeyError inside
   Behave's scope-tracking __setattr__. Renamed to embedding_config.

Verified locally: behave on features/semantic_context_search.feature now
reports 6 scenarios passed / 0 errored. lint + typecheck both pass.

ISSUES CLOSED: #5254
This commit is contained in:
2026-06-04 12:11:29 -04:00
committed by drew
parent 1a5529fa0b
commit bb8f309874
@@ -9,10 +9,10 @@ from cleveragents.application.services.embedding_provider import (
SimpleWordEmbeddingProvider,
cosine_similarity,
)
from cleveragents.domain.models.acms.crp import FragmentProvenance
from cleveragents.domain.models.core.context_fragment import (
ContextBudget,
ContextFragment,
FragmentProvenance,
)
@@ -128,11 +128,19 @@ def step_have_threshold(context, threshold):
@when("I filter fragments by similarity threshold")
def step_filter_by_threshold(context):
"""Filter fragments by threshold."""
"""Filter fragments by threshold.
Computes similarity inline so the step works whether or not a prior
"rank fragments" step ran. Scenarios that filter directly (without an
intermediate ranking step) would otherwise hit an AttributeError on
``context.ranked_fragments``.
"""
scored = [
(frag, cosine_similarity(context.query_embedding, frag["embedding"]))
for frag in context.fragments
]
context.filtered_fragments = [
(frag, sim)
for frag, sim in context.ranked_fragments
if sim >= context.threshold
(frag, sim) for frag, sim in scored if sim >= context.threshold
]
@@ -214,8 +222,14 @@ def step_check_ranking(context):
@given("I have an embedding provider configuration")
def step_have_config(context):
"""Initialize embedding provider configuration."""
context.config = {
"""Initialize embedding provider configuration.
Stored under ``embedding_config`` rather than ``config`` because Behave's
``Context`` reserves ``config`` for its own Configuration object — setting
``context.config`` raises ``KeyError`` from Behave's scope-tracking
``__setattr__``.
"""
context.embedding_config = {
"provider_type": "simple_word",
"vocab_size": 100,
}
@@ -224,9 +238,9 @@ def step_have_config(context):
@when("I create a semantic strategy with the configuration")
def step_create_strategy_with_config(context):
"""Create strategy with configuration."""
if context.config["provider_type"] == "simple_word":
if context.embedding_config["provider_type"] == "simple_word":
context.strategy_provider = SimpleWordEmbeddingProvider(
vocab_size=context.config["vocab_size"]
vocab_size=context.embedding_config["vocab_size"]
)