1f64a274e3
- docs/reference/context_strategies.md: update Built-in Strategies table to document real retrieval logic for all 6 strategies (SimpleKeyword, SemanticEmbedding, BreadthDepthNavigator, ARCE, TemporalArchaeology, PlanDecisionContext); add note about v1 character-frequency embedding approximation; note SpecStrategyAdapter registration (#3500) - docs/reference/checkpointing.md: add Automatic Checkpoint Triggers section documenting the 4 triggers (on_tool_write, on_tool_write_complete, on_subplan_spawn, on_error), configuration via core.checkpoints.auto_create_on, and wiring into ToolRunner/SubplanExecutionService/PlanExecutor (#3439)
140 lines
5.8 KiB
Markdown
140 lines
5.8 KiB
Markdown
# 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
|
|
|
|
All six built-in strategies now implement real backend-driven retrieval logic
|
|
(v3.8.0+, issue #3500). Previously they were no-op stubs that returned empty
|
|
fragment lists. The `SpecStrategyAdapter` bridges each strategy into the
|
|
`ACMSPipeline` at construction time.
|
|
|
|
| Strategy | Quality | Backends | Retrieval Logic |
|
|
|----------|---------|----------|-----------------|
|
|
| `simple-keyword` | 0.3 | Text | `TextBackend.search()` using keywords extracted from the `ContextRequest`; results packed greedily into token budget |
|
|
| `semantic-embedding` | 0.6 | Vector | `VectorBackend.similarity_search()` using a character-frequency embedding as a v1 approximation; budget-aware packing |
|
|
| `breadth-depth-navigator` | 0.85 | Graph | `GraphBackend` traversal from focus nodes declared in the `ContextRequest`, expanding outward by `request.breadth` hops |
|
|
| `arce` | 0.95 | All | Multi-modal pipeline: text search (40% budget) + vector similarity (40%) + graph traversal (20%); results merged and deduplicated |
|
|
| `temporal-archaeology` | 0.5 | Graph + Cold | Two-phase: `TemporalBackend.query_by_tier()` for cold-tier historical nodes, then `GraphBackend` traversal from those nodes |
|
|
| `plan-decision-context` | 0.7 | Warm/Cold | `TemporalBackend`-driven lookup walking parent and ancestor plan hierarchy, retrieving decision records from warm/cold tiers |
|
|
|
|
Default enabled (spec `context.strategies.enabled`):
|
|
`["simple-keyword", "semantic-embedding", "breadth-depth-navigator"]`
|
|
|
|
> **Note:** The `SemanticEmbeddingStrategy` uses a character-frequency
|
|
> embedding as a v1 approximation of semantic similarity. A real embedding
|
|
> model integration is planned for a future milestone.
|
|
|
|
## Configuration
|
|
|
|
### Global (config.toml)
|
|
|
|
```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:
|
|
|
|
1. Every enabled strategy is actually registered.
|
|
2. Every strategy declares at least one backend capability.
|
|
3. Every strategy declares supported resource types.
|
|
|
|
## Fallback Degradation Path
|
|
|
|
When backends are unavailable, the system degrades gracefully:
|
|
|
|
1. `arce` (requires all) → 2. `breadth-depth-navigator` (graph) →
|
|
3. `semantic-embedding` (vector) → 4. `simple-keyword` (text only)
|
|
|
|
This ensures context is always produced.
|