Files
cleveragents-core/robot/helper_context_strategy_registry.py
freemo af9db5ea28
CI / lint (pull_request) Successful in 32s
CI / quality (pull_request) Successful in 32s
CI / typecheck (pull_request) Successful in 46s
CI / build (pull_request) Successful in 31s
CI / helm (pull_request) Successful in 35s
CI / security (pull_request) Successful in 1m19s
CI / unit_tests (pull_request) Failing after 6m45s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 15m36s
CI / coverage (pull_request) Successful in 10m43s
CI / integration_tests (pull_request) Failing after 23m29s
CI / status-check (pull_request) Failing after 3s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m58s
fix(acms): implement real retrieval logic in all 6 spec-required context strategies
2026-04-05 20:56:32 +00:00

286 lines
9.3 KiB
Python

#!/usr/bin/env python3
"""Robot Framework helper for context strategy registry smoke tests."""
from __future__ import annotations
import sys
from collections.abc import Callable
from pathlib import Path
# Ensure src is on sys.path
_SRC = Path(__file__).resolve().parents[1] / "src"
if str(_SRC) not in sys.path:
sys.path.insert(0, str(_SRC))
from cleveragents.application.services.strategy_registry import ( # noqa: E402
StrategyRegistry,
)
from cleveragents.domain.models.acms.crp import ContextRequest # noqa: E402
from cleveragents.domain.models.acms.strategy import ( # noqa: E402
BackendSet,
ContextStrategy,
StrategyConfig,
)
from cleveragents.domain.models.acms.strategy_stubs import ( # noqa: E402
BUILTIN_STRATEGY_CLASSES,
DEFAULT_ENABLED_STRATEGIES,
)
from cleveragents.domain.models.acms.stubs import ( # noqa: E402
InMemoryGraphBackend,
InMemoryTextBackend,
InMemoryVectorBackend,
)
# ---------------------------------------------------------------------------
# Commands
# ---------------------------------------------------------------------------
def _cmd_register_builtins() -> int:
"""Register all built-in strategies and verify count."""
registry = StrategyRegistry()
for cls in BUILTIN_STRATEGY_CLASSES:
inst = cls()
enabled = inst.name in DEFAULT_ENABLED_STRATEGIES
registry.register(inst, config=StrategyConfig(enabled=enabled), is_builtin=True)
registry.set_enabled(list(DEFAULT_ENABLED_STRATEGIES))
if len(registry) != 6:
print(f"strategy-fail: expected 6 strategies, got {len(registry)}")
return 1
print(f"strategy-ok: registered {len(registry)} strategies")
enabled = registry.list_enabled()
if len(enabled) != 3:
print(f"strategy-fail: expected 3 enabled, got {len(enabled)}")
return 1
print(f"strategy-enabled: {enabled}")
return 0
def _cmd_protocol_check() -> int:
"""Verify all built-in strategies satisfy ContextStrategy protocol."""
for cls in BUILTIN_STRATEGY_CLASSES:
inst = cls()
if not isinstance(inst, ContextStrategy):
print(f"strategy-fail: {cls.__name__} doesn't satisfy protocol")
return 1
if not inst.name:
print(f"strategy-fail: {cls.__name__} has empty name")
return 1
if inst.capabilities.quality_score <= 0:
print(f"strategy-fail: {cls.__name__} has invalid quality score")
return 1
print(f"strategy-ok: {inst.name} (quality={inst.capabilities.quality_score})")
return 0
def _cmd_can_handle() -> int:
"""Test can_handle with various backend configurations."""
from cleveragents.domain.models.acms.strategy_stubs import (
ARCEStrategy,
SimpleKeywordStrategy,
)
request = ContextRequest(query="test")
# simple-keyword with text backend
sk = SimpleKeywordStrategy()
bs_text = BackendSet(text=InMemoryTextBackend())
score = sk.can_handle(request, bs_text)
if abs(score - 0.3) > 1e-6:
print(f"strategy-fail: simple-keyword expected 0.3, got {score}")
return 1
print(f"strategy-ok: simple-keyword can_handle with text = {score}")
# simple-keyword without backend
bs_none = BackendSet()
score = sk.can_handle(request, bs_none)
if score != 0.0:
print(
f"strategy-fail: simple-keyword expected 0.0 without backend, got {score}"
)
return 1
print(f"strategy-ok: simple-keyword can_handle without backend = {score}")
# arce with all backends
arce = ARCEStrategy()
bs_all = BackendSet(
text=InMemoryTextBackend(),
vector=InMemoryVectorBackend(),
graph=InMemoryGraphBackend(),
)
score = arce.can_handle(request, bs_all)
if abs(score - 0.95) > 1e-6:
print(f"strategy-fail: arce expected 0.95, got {score}")
return 1
print(f"strategy-ok: arce can_handle with all = {score}")
return 0
def _cmd_validate() -> int:
"""Validate registry with all built-in strategies."""
registry = StrategyRegistry()
for cls in BUILTIN_STRATEGY_CLASSES:
registry.register(cls(), is_builtin=True)
warnings = registry.validate_registry()
if warnings:
print(f"strategy-fail: unexpected warnings: {warnings}")
return 1
print("strategy-ok: registry validation passed with no warnings")
return 0
def _cmd_pipeline_integration() -> int:
"""Integration test: verify all 6 spec strategies are registered in ACMSPipeline.
Verifies that the 6 spec-required strategies are registered with ACMSPipeline
and that the pipeline can be used with the spec strategy names.
"""
from cleveragents.application.services.acms_service import ACMSPipeline
pipeline = ACMSPipeline()
# Verify all 6 spec-required strategies are registered
expected_strategies = {
"simple-keyword",
"semantic-embedding",
"breadth-depth-navigator",
"arce",
"temporal-archaeology",
"plan-decision-context",
}
registered = set(pipeline._strategies.keys())
missing = expected_strategies - registered
if missing:
print(f"strategy-fail: missing strategies: {missing}")
return 1
print("strategy-ok: all 6 spec strategies registered in ACMSPipeline")
print(f"strategy-ok: total strategies: {len(registered)}")
return 0
def _cmd_real_retrieval() -> int:
"""Test that each strategy returns non-empty fragments with populated backends."""
from datetime import UTC, datetime, timedelta
from cleveragents.domain.models.acms.backends import (
GraphResult,
TextResult,
VectorResult,
)
from cleveragents.domain.models.acms.crp import ContextRequest
from cleveragents.domain.models.acms.strategy import BackendSet, PlanContext
from cleveragents.domain.models.acms.strategy_stubs import BUILTIN_STRATEGY_CLASSES
from cleveragents.domain.models.acms.temporal import TemporalMetadata, TemporalNode
from cleveragents.domain.models.acms.temporal_stubs import InMemoryTemporalBackend
class _TextBackend:
def search(self, query, *, scope, max_results=20):
return [
TextResult(
uko_uri="uko:class/Auth",
content=f"Auth for {query}",
score=0.9,
)
]
class _VectorBackend:
def similarity_search(self, embedding, *, scope, top_k=20):
return [
VectorResult(
uko_uri="uko:class/Auth",
content="Auth semantic",
score=0.85,
)
]
class _GraphBackend:
def sparql_query(self, query, *, scope):
return GraphResult(triples=[("uko:class/Auth", "rdf:type", "uko:Class")])
def get_triples(self, subject):
return GraphResult(triples=[(subject, "rdf:type", "uko:Class")])
def traverse(self, start, *, depth=2):
return GraphResult(
triples=[
(start, "rdf:type", "uko:Class"),
(start, "uko:hasMethod", "uko:method/auth"),
]
)
# Create temporal backend with data
temporal_backend = InMemoryTemporalBackend()
now = datetime.now(tz=UTC)
node = TemporalNode(
node_uri="uko:plan/test_v1",
source_resource="res://test",
source_path="src/test.py",
temporal=TemporalMetadata(
valid_from=now - timedelta(hours=1),
is_current=True,
),
)
temporal_backend.store_node(node)
request = ContextRequest(query="authentication", focus=["uko:class/Auth"])
plan_context = PlanContext()
backend_map = {
"simple-keyword": BackendSet(text=_TextBackend()),
"semantic-embedding": BackendSet(vector=_VectorBackend()),
"breadth-depth-navigator": BackendSet(graph=_GraphBackend()),
"arce": BackendSet(
text=_TextBackend(),
vector=_VectorBackend(),
graph=_GraphBackend(),
),
"temporal-archaeology": BackendSet(
graph=_GraphBackend(),
temporal=temporal_backend,
),
"plan-decision-context": BackendSet(temporal=temporal_backend),
}
all_ok = True
for cls in BUILTIN_STRATEGY_CLASSES:
strategy = cls()
backends = backend_map[strategy.name]
result = strategy.assemble(request, backends, 10000, plan_context)
if len(result) < 1:
print(
f"strategy-fail: {strategy.name} returned 0 fragments "
"with populated backends"
)
all_ok = False
else:
print(f"strategy-ok: {strategy.name} returned {len(result)} fragment(s)")
return 0 if all_ok else 1
_COMMANDS: dict[str, Callable[[], int]] = {
"register-builtins": _cmd_register_builtins,
"protocol-check": _cmd_protocol_check,
"can-handle": _cmd_can_handle,
"validate": _cmd_validate,
"pipeline-integration": _cmd_pipeline_integration,
"real-retrieval": _cmd_real_retrieval,
}
def main() -> int:
"""Run the specified command."""
if len(sys.argv) < 2 or sys.argv[1] not in _COMMANDS:
print(f"Usage: {sys.argv[0]} <{'|'.join(_COMMANDS)}>")
return 2
return _COMMANDS[sys.argv[1]]()
if __name__ == "__main__":
sys.exit(main())