f66fb5a19a
CI / lint (push) Failing after 35s
CI / quality (push) Successful in 40s
CI / typecheck (push) Failing after 48s
CI / security (push) Failing after 49s
CI / coverage (push) Has been skipped
CI / build (push) Successful in 20s
CI / helm (push) Successful in 34s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Failing after 2m12s
CI / docker (push) Has been skipped
CI / e2e_tests (push) Failing after 15m52s
CI / integration_tests (push) Failing after 22m11s
CI / status-check (push) Failing after 1s
CI / benchmark-publish (push) Has been cancelled
Align Unicode box-drawing blocks and related tables in specification.md, ADR-044/045/046, and reference pages for consistent MkDocs rendering. ISSUES CLOSED: #1171
174 lines
7.2 KiB
Markdown
174 lines
7.2 KiB
Markdown
# ACMS Strategy Coordinator & Fusion Engine
|
|
|
|
## Overview
|
|
|
|
The **StrategyCoordinator** and **FusionEngine** are named facades that
|
|
provide clean public APIs over the existing ACMS pipeline Phase 1 and
|
|
Phase 2 components respectively.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────────┐
|
|
│ StrategyCoordinator │
|
|
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────┐ │
|
|
│ │ Confidence │ │ Proportional │ │ Parallel │ │
|
|
│ │ Weighted │ │ Budget │ │ Strategy │ │
|
|
│ │ Selector │ │ Allocator │ │ Executor │ │
|
|
│ └────────┬─────────┘ └────────┬─────────┘ └────┬─────┘ │
|
|
│ │ select │ allocate │execute │
|
|
│ └────────────────────┴────────────────┘ │
|
|
│ coordinate() │
|
|
└─────────────────────────┬────────────────────────────────┘
|
|
│ fragments
|
|
▼
|
|
┌────────────────────────────────────────────────────────┐
|
|
│ FusionEngine │
|
|
│ ┌──────────┐ ┌───────────┐ ┌─────────┐ ┌───────────┐ │
|
|
│ │ Content │ │ Max Depth │ │Weighted │ │ Greedy │ │
|
|
│ │ Hash │ │ Resolver │ │Composite│ │ Knapsack │ │
|
|
│ │ Dedup │ │ │ │ Scorer │ │ Packer │ │
|
|
│ └────┬─────┘ └─────┬─────┘ └────┬────┘ └─────┬─────┘ │
|
|
│ │ dedup │ resolve │ score │ pack │
|
|
│ └─────────────┴────────────┴────────────┘ │
|
|
│ fuse() │
|
|
│ ┌──────────────────────────────────────────────────┐ │
|
|
│ │ Budget Overage Guard │ │
|
|
│ │ Drop lowest-relevance fragments if over budget │ ││ └──────────────────────────────────────────────────┘ │
|
|
└────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## StrategyCoordinator
|
|
|
|
### Public API
|
|
|
|
```python
|
|
coordinator = StrategyCoordinator(config=CoordinatorConfig(
|
|
per_strategy_max_cap=500,
|
|
min_useful_budget=64,
|
|
))
|
|
|
|
result = coordinator.coordinate(
|
|
request={"preferred_strategies": ["relevance"]},
|
|
strategies=[strategy_a, strategy_b],
|
|
budget=ContextBudget(max_tokens=4096),
|
|
fragments=input_fragments,
|
|
backends={"vector": True},
|
|
plan_context={"plan_id": "..."},
|
|
)
|
|
|
|
# Result: CoordinationResult
|
|
# .fragments: list[ContextFragment]
|
|
# .strategies_used: list[str]
|
|
# .allocations: list[tuple[str, float, int]]
|
|
# .circuit_broken: list[str]
|
|
```
|
|
|
|
### Budget Allocation
|
|
|
|
Budget tokens are allocated **proportionally by strategy confidence**:
|
|
|
|
- Strategy with confidence 0.8 in a pool of (0.8 + 0.2) = 1.0
|
|
receives 80% of the budget.
|
|
- The largest-remainder method ensures no tokens are lost to rounding.
|
|
- Strategies whose proportional share falls below `min_useful_budget`
|
|
are excluded and their tokens are redistributed.
|
|
|
|
### Per-Strategy Max Caps
|
|
|
|
When `per_strategy_max_cap` is set:
|
|
|
|
1. Any allocation exceeding the cap is clamped.
|
|
2. Excess tokens are redistributed proportionally among uncapped
|
|
strategies.
|
|
3. Redistributed tokens are also capped to prevent cascading overflows.
|
|
|
|
### Error Handling
|
|
|
|
- **Circuit breaker**: After `circuit_breaker_threshold` consecutive
|
|
failures, a strategy is temporarily disabled. Disabled strategies
|
|
appear in `result.circuit_broken`.
|
|
- **Timeouts**: Per-strategy execution timeout of `executor_timeout`
|
|
seconds. Timed-out strategies are treated as failures.
|
|
- **Graceful degradation**: Failed strategies are excluded from results
|
|
without failing the entire coordination round.
|
|
|
|
## FusionEngine
|
|
|
|
### Public API
|
|
|
|
```python
|
|
engine = FusionEngine(config=FusionConfig(
|
|
overage_guard_enabled=True,
|
|
min_fragment_tokens=10,
|
|
))
|
|
|
|
result = engine.fuse(
|
|
fragments=coordinator_output.fragments,
|
|
budget=ContextBudget(max_tokens=4096),
|
|
)
|
|
|
|
# Result: FusionResult
|
|
# .fragments: list[ContextFragment]
|
|
# .dedup_count: int
|
|
# .depth_resolved_count: int
|
|
# .dropped_by_overage_guard: int
|
|
# .total_tokens: int
|
|
# .budget_utilization: float
|
|
```
|
|
|
|
### Fragment Dedup
|
|
|
|
Fragments are grouped by **(UKO URI, SHA-256 hash of content)**.
|
|
Within each group, the fragment with the highest `relevance_score`
|
|
is retained.
|
|
|
|
### Detail Conflict Resolution
|
|
|
|
When the same UKO node appears at multiple detail depths:
|
|
- The highest-depth rendering is retained.
|
|
- Equal depths: prefer higher `relevance_score`.
|
|
|
|
### Greedy Knapsack Packing
|
|
|
|
Fragments are sorted with **deterministic tie-breakers**:
|
|
|
|
1. `relevance_score` descending
|
|
2. `detail_depth` descending
|
|
3. `token_count` ascending
|
|
|
|
The greedy algorithm fills the budget top-down. When a high-value
|
|
fragment doesn't fit, **depth fallback** attempts lower-depth
|
|
renderings of the same UKO node.
|
|
|
|
### Budget Overage Guard
|
|
|
|
A post-packing safety net that:
|
|
|
|
1. Checks if total tokens exceed the available budget.
|
|
2. Drops fragments in ascending order of `relevance_score`.
|
|
3. Emits structured `WARNING` log messages for each dropped fragment.
|
|
4. Continues until total tokens fit within budget.
|
|
|
|
## Configuration Reference
|
|
|
|
### CoordinatorConfig
|
|
|
|
| Field | Type | Default | Description |
|
|
|---|---|---|---|
|
|
| `min_useful_budget` | `int` | 64 | Min tokens per strategy |
|
|
| `executor_timeout` | `float` | 30.0 | Per-strategy timeout (seconds) |
|
|
| `executor_max_workers` | `int` | 4 | Max concurrent threads |
|
|
| `circuit_breaker_threshold` | `int` | 3 | Failures before circuit opens |
|
|
| `preference_boost` | `float` | 1.5 | Confidence multiplier for preferred |
|
|
| `per_strategy_max_cap` | `int \| None` | None | Max tokens per strategy |
|
|
|
|
### FusionConfig
|
|
|
|
| Field | Type | Default | Description |
|
|
|---|---|---|---|
|
|
| `scorer_weights` | `ScorerWeights \| None` | None | Composite scoring weights |
|
|
| `depth_fallback_steps` | `tuple[int, ...]` | (9,4,2,0) | Depth fallback sequence |
|
|
| `min_fragment_tokens` | `int` | 10 | Min tokens for packing |
|
|
| `overage_guard_enabled` | `bool` | True | Enable budget overage guard |
|