"""Helper functions for advanced context strategies Robot Framework tests.""" from __future__ import annotations import sys from pathlib import Path from typing import Any # Robot Framework adds the library file's directory (robot/) to sys.path, but # features.mocks lives at the project root. Insert the project root so the # import below resolves correctly regardless of invocation context. _PROJECT_ROOT = str(Path(__file__).resolve().parents[1]) if _PROJECT_ROOT not in sys.path: sys.path.insert(0, _PROJECT_ROOT) from features.mocks.advanced_context_strategies_mocks import ( # noqa: E402 AdaptiveContextSelector, ContextFusionStrategy, RelevanceScoringStrategy, ) from cleveragents.application.services.context_strategies import ( # noqa: E402 BreadthDepthNavigatorStrategy, SemanticEmbeddingStrategy, ) from cleveragents.domain.models.core.context_fragment import ( # noqa: E402 ContextBudget, ContextFragment, FragmentProvenance, ) # Default provenance used for test fragments (no real resource needed). _TEST_PROVENANCE = FragmentProvenance(resource_uri="test://fixture") def create_semantic_search_strategy_impl() -> SemanticEmbeddingStrategy: """Create a semantic search strategy with FakeEmbeddings.""" return SemanticEmbeddingStrategy(min_similarity=0.05) def create_relevance_scoring_strategy_impl() -> RelevanceScoringStrategy: """Create a relevance scoring strategy.""" return RelevanceScoringStrategy() def create_adaptive_selector_impl() -> AdaptiveContextSelector: """Create an adaptive context strategy selector.""" return AdaptiveContextSelector() def create_context_fusion_strategy_impl( strategies: list[str], ) -> ContextFusionStrategy: """Create a context fusion strategy.""" return ContextFusionStrategy(strategies) def create_test_fragments_impl(args: list[str]) -> list[ContextFragment]: """Create test context fragments from arguments.""" fragments: list[ContextFragment] = [] i = 0 while i < len(args): if i + 4 < len(args): uko_node = args[i] content = args[i + 1] score = float(args[i + 2]) tokens = int(args[i + 3]) depth = int(args[i + 4]) frag = ContextFragment( uko_node=uko_node, content=content, relevance_score=score, token_count=tokens, detail_depth=depth, provenance=_TEST_PROVENANCE, ) fragments.append(frag) i += 5 else: break return fragments def create_context_budget_impl(max_tokens: int, reserved_tokens: int) -> ContextBudget: """Create a context budget.""" return ContextBudget( max_tokens=int(max_tokens), reserved_tokens=int(reserved_tokens), ) def search_with_query_impl( strategy: SemanticEmbeddingStrategy, query: str, fragments: list[ContextFragment], budget: ContextBudget, ) -> list[ContextFragment]: """Search with a query.""" strategy.set_query(query) return strategy.assemble(fragments, budget) def assemble_with_strategy_impl( strategy: Any, fragments: list[ContextFragment], budget: ContextBudget, ) -> list[ContextFragment]: """Assemble with a strategy.""" return strategy.assemble(fragments, budget) def select_strategy_for_query_impl( selector: AdaptiveContextSelector, query: str ) -> str: """Select strategy for a query.""" request = {"query": query} strategy_name, _ = selector.select_strategy(request) return strategy_name def select_strategy_without_query_impl(selector: AdaptiveContextSelector) -> str: """Select strategy without query.""" request = {} strategy_name, _ = selector.select_strategy(request) return strategy_name def select_strategy_with_invalid_request_impl( selector: AdaptiveContextSelector, ) -> str: """Select strategy with invalid request.""" request = {"invalid": "data"} strategy_name, _ = selector.select_strategy(request) return strategy_name def fuse_with_query_impl( fusion: ContextFusionStrategy, query: str, fragments: list[ContextFragment], budget: ContextBudget, ) -> list[ContextFragment]: """Fuse strategies with a query.""" return fusion.assemble(fragments, budget, query) def load_strategy_from_yaml_impl(config: dict[str, Any]) -> Any: """Load strategy from YAML configuration.""" strategy_type = config.get("strategy") if strategy_type == "semantic-embedding": min_sim = config.get("min_similarity", 0.05) return SemanticEmbeddingStrategy(min_similarity=min_sim) elif strategy_type == "relevance-scoring": return RelevanceScoringStrategy() elif strategy_type == "adaptive-selector": return AdaptiveContextSelector() elif strategy_type == "context-fusion": strategies = config.get("strategies", []) return ContextFusionStrategy(strategies) else: raise ValueError(f"Unknown strategy type: {strategy_type!r}") def create_context_assembler_with_advanced_strategies_impl() -> dict[str, Any]: """Create a ContextAssembler with advanced strategies.""" return { "strategies": [ SemanticEmbeddingStrategy(), RelevanceScoringStrategy(), BreadthDepthNavigatorStrategy(), ] } def create_context_assembler_with_multiple_strategies_impl() -> dict[str, Any]: """Create a ContextAssembler with multiple strategies.""" return { "strategies": [ SemanticEmbeddingStrategy(), RelevanceScoringStrategy(), ] } def assemble_context_with_query_impl( assembler: dict[str, Any], query: str, fragments: list[ContextFragment], budget: ContextBudget, ) -> list[ContextFragment]: """Assemble context with a query.""" request = {"query": query} best_strategy = None best_confidence = 0.0 for strategy in assembler["strategies"]: confidence = strategy.can_handle(request) if confidence > best_confidence: best_confidence = confidence best_strategy = strategy if best_strategy is None: best_strategy = assembler["strategies"][0] if hasattr(best_strategy, "set_query"): best_strategy.set_query(query) return best_strategy.assemble(fragments, budget) def get_uko_nodes_impl(fragments: list[ContextFragment]) -> list[str]: """Extract uko_node values from fragments.""" return [f.uko_node for f in fragments]