1521c4ae8c
Implement the ACMS context strategy registry per spec §25162-25233, §28682-28708, §42628-42653, and §43167-43199. - Define ContextStrategy protocol, StrategyCapabilities, BackendSet, PlanContext, StrategyConfig, ContextStrategyResult models - Add 6 built-in stub strategies (simple-keyword, semantic-embedding, breadth-depth-navigator, arce, temporal-archaeology, plan-decision-context) with spec quality scores and feature flags - Add StrategyRegistry with register, register_from_module (plugin discovery), enable/disable, per-strategy config, and validation - Add ContextStrategyResult with deterministic fragment ordering (-relevance_score, uko_node) - Add configuration-driven enabled list with per-project overrides - Add per-strategy timeout, max-fragment, circuit-breaker config - Add registry validation for resource types and backend capabilities - Fix update_config to sync _enabled_order when toggling enabled flag - Fix register_from_module to honour the name parameter as registry key - Fix update_config to re-run Pydantic validators via model_validate - Add docs/reference/context_strategies.md - Add 55 BDD scenarios (Behave), 4 Robot integration tests, ASV benchmarks ISSUES CLOSED: #191
4.9 KiB
4.9 KiB
Context Strategy Registry
The Context Strategy Registry manages pluggable retrieval strategies for the
ACMS Context Assembly Pipeline. Strategies implement the ContextStrategy
protocol and are registered via TOML configuration or programmatic API.
Architecture
ContextRequest
┌─── StrategySelector ───┐
│ can_handle() polling │
└──────────┬──────────────┘
v
┌─── BudgetAllocator ────┐
│ proportional alloc │
└──────────┬──────────────┘
v
┌─── StrategyExecutor ───┐
│ parallel w/ timeout │
│ circuit breaker │
└──────────┬──────────────┘
v
ContextFragment[]
ContextStrategy Protocol
Every strategy implements:
| Member | Type | Description |
|---|---|---|
name |
property -> str |
Unique strategy name |
capabilities |
property -> StrategyCapabilities |
Backend requirements and quality score |
can_handle(request, backends) |
-> float |
0.0-1.0 confidence for this request |
assemble(request, backends, budget, plan_context) |
-> list[ContextFragment] |
Execute and return fragments; must respect budget |
explain() |
-> str |
Human-readable description |
StrategyCapabilities
| Field | Type | Default | Description |
|---|---|---|---|
uses_text |
bool |
False |
Requires TextBackend |
uses_vector |
bool |
False |
Requires VectorBackend |
uses_graph |
bool |
False |
Requires GraphBackend |
uses_temporal |
bool |
False |
Requires temporal/cold-tier data |
resource_types |
tuple[str, ...] |
() |
Supported resource types (empty = all) |
quality_score |
float |
0.5 |
Intrinsic quality score (0.0-1.0) |
supports_depth_breadth |
bool |
False |
Supports depth/breadth projection |
supports_plan_hierarchy |
bool |
False |
Supports plan hierarchy traversal |
supports_temporal |
bool |
False |
Supports temporal archaeology queries |
Built-in Strategies
| Strategy | Quality | Backends | Description |
|---|---|---|---|
simple-keyword |
0.3 | Text | Basic keyword/regex text search. Universal fallback. |
semantic-embedding |
0.6 | Vector | Vector similarity search. |
breadth-depth-navigator |
0.85 | Graph | Graph-aware UKO traversal. Primary code-aware strategy. |
arce |
0.95 | All | Multi-modal ARCE pipeline. Highest quality. |
temporal-archaeology |
0.5 | Graph + Cold | Historical pattern discovery. |
plan-decision-context |
0.7 | Warm/Cold | Parent/ancestor plan context retrieval. |
Default enabled (spec context.strategies.enabled):
["simple-keyword", "semantic-embedding", "breadth-depth-navigator"]
Configuration
Global (config.toml)
[context.strategies]
enabled = ["simple-keyword", "semantic-embedding", "breadth-depth-navigator"]
[context.strategies.custom]
"my-strategy" = "my_package.strategies:MyStrategy"
Per-strategy settings
| Key | Type | Default | Description |
|---|---|---|---|
timeout_seconds |
int | 30 | Per-strategy assembly timeout |
max_fragments |
int | 100 | Maximum fragments per call |
max_workers |
int | 4 | Parallel workers for executor |
circuit_breaker_threshold |
int | 3 | Failures before circuit opens |
enabled |
bool | true |
Whether the strategy is active |
Per-project overrides
Projects can override the global enabled list using:
agents project context set --strategy simple-keyword --strategy semantic-embedding
This replaces the global context.strategies.enabled list for that project.
ContextStrategyResult
Output of a single strategy execution:
| Field | Type | Description |
|---|---|---|
strategy_name |
str |
Name of the producing strategy |
fragments |
tuple[ContextFragment, ...] |
Deterministically ordered fragments |
total_fragments |
int |
Total fragments before limits |
tokens_used |
int |
Total tokens across fragments |
execution_time_ms |
float |
Execution wall-clock time (ms) |
errors |
tuple[str, ...] |
Error messages |
stats |
dict[str, Any] |
Strategy-specific statistics |
Fragment ordering: (relevance_score DESC, uko_node ASC).
Registry Validation
The registry validates that:
- Every enabled strategy is actually registered.
- Every strategy declares at least one backend capability.
- Every strategy declares supported resource types.
Fallback Degradation Path
When backends are unavailable, the system degrades gracefully:
arce(requires all) → 2.breadth-depth-navigator(graph) →semantic-embedding(vector) → 4.simple-keyword(text only)
This ensures context is always produced.