# How ContentRouter Selects the Appropriate Compressor in Headroom

> Discover how Headroom's ContentRouter selects the best compressor using a three-stage pipeline including quick-path checks and content-type mapping.

- Repository: [Tejas Chopra/headroom](https://github.com/chopratejas/headroom)
- Tags: how-to-guide
- Published: 2026-06-14

---

**The ContentRouter uses a three-stage pipeline—quick-path checks, mixed-content detection, and content-type mapping—to select the optimal compressor based on the input text's characteristics.**

In the `chopratejas/headroom` repository, the **ContentRouter** transform automatically routes every piece of text through a sophisticated decision tree to determine which compression algorithm should handle the data. This selection process balances speed, accuracy, and configurability to ensure that source code, JSON arrays, search results, and prose each receive the most effective compression treatment.

## The Three-Stage Selection Pipeline

The router's decision logic in [`headroom/transforms/content_router.py`](https://github.com/chopratejas/headroom/blob/main/headroom/transforms/content_router.py) processes input through a cascading pipeline that narrows down the optimal strategy before invoking any concrete compressor.

### Stage 1: Quick-Path Passthrough Checks

Before any analysis begins, the router performs immediate sanity checks on the input. If the content is empty or contains only whitespace, the router returns the text unchanged via the **passthrough** strategy. This avoids unnecessary computational overhead for trivial inputs.

### Stage 2: Mixed-Content Detection

When the input contains non-trivial text, the router calls `is_mixed_content()` (lines 202-219 in [`content_router.py`](https://github.com/chopratejas/headroom/blob/main/content_router.py)) to detect documents that combine multiple content types. This function searches for four distinct indicators:

- **Fenced-code blocks** matching `_CODE_FENCE_PATTERN`
- **JSON-like blocks** identified by `_JSON_BLOCK_START`
- **Prose sections** matching `_PROSE_PATTERN`
- **Search-result lines** matching `_SEARCH_RESULT_PATTERN`

If two or more indicators are present, the router selects the **`MIXED`** strategy and splits the text into sections for per-section routing, ensuring that code blocks and explanatory text receive different compression treatments.

### Stage 3: Content-Type Detection and Strategy Mapping

For homogeneous content, the router invokes `_detect_content()` (lines 112-124) to classify the input. This method first calls the Rust-based detector `headroom._core.detect_content_type` for high-performance analysis. If the Rust detector returns **plain-text**, the router falls back to `_regex_detect_content_type`, a pure-Python regex implementation.

The resulting `DetectionResult` contains a `ContentType` enum value (e.g., `SOURCE_CODE`, `JSON_ARRAY`, `SEARCH_RESULTS`). The router then translates this into a `CompressionStrategy` via `_strategy_from_detection()` (lines 125-144).

## How Content-Type Maps to Compression Strategy

The mapping between detected content types and compression strategies follows a deterministic table implemented in `_strategy_from_detection()`:

| ContentType | CompressionStrategy |
|-------------|---------------------|
| `SOURCE_CODE` | `CODE_AWARE` |
| `JSON_ARRAY` | `SMART_CRUSHER` |
| `SEARCH_RESULTS` | `SEARCH` |
| `BUILD_OUTPUT` | `LOG` |
| `GIT_DIFF` | `DIFF` |
| `HTML` | `HTML` |
| `PLAIN_TEXT` | `TEXT` |

The router checks `ContentRouterConfig` settings before finalizing the selection. If `enable_code_aware=False` disables the code-aware compressor, or if `prefer_code_aware_for_code` is set to `false`, the strategy overrides to **`KOMPRESS`** regardless of the initial mapping.

## Configuration Overrides and Fallback Chains

After strategy selection, the router lazily loads the concrete compressor through methods like `_get_code_compressor()` and `_get_smart_crusher()`. If the chosen compressor is unavailable, Headroom implements an automatic fallback chain:

1. `SMART_CRUSHER` falls back to `KOMPRESS`
2. `KOMPRESS` falls back to `LOG`

The final strategy and routing decisions are recorded in the `RouterCompressionResult`, providing full observability into why a specific compressor was selected.

## Code Examples

The following examples demonstrate how `ContentRouter` selects compressors for different input types:

```python
from headroom.transforms import ContentRouter

router = ContentRouter()

# Compress a Python file – uses CodeAwareCompressor (or falls back to Kompress)

with open("example.py") as f:
    result = router.compress(f.read())
print("Chosen strategy:", result.strategy_used)   # → CODE_AWARE or KOMPRESS

print("Saved tokens:", result.tokens_saved)

```

```python

# Compress a JSON array – SmartCrusher is selected

json_array = '[{"id":1,"name":"A"},{"id":2,"name":"B"}]'
result = router.compress(json_array)
print("Chosen strategy:", result.strategy_used)   # → SMART_CRUSHER

```

```python

# Mixed content (README with code fences) – router splits and routes each part

mixed = """

# My Library

```python
def hello():
    print("hi")

```

## Usage

Run `python -m mylib` to start.
"""
result = router.compress(mixed)
print("Chosen strategy:", result.strategy_used)   # → MIXED

print("Section routing log:")
for d in result.routing_log:
    print(f"  • {d.content_type.value}: {d.strategy.value}")

```

## Summary

- **ContentRouter** implements a three-stage pipeline in [`headroom/transforms/content_router.py`](https://github.com/chopratejas/headroom/blob/main/headroom/transforms/content_router.py) to intelligently route text to the appropriate compressor.
- **Mixed-content detection** via `is_mixed_content()` triggers the `MIXED` strategy, splitting documents into sections for specialized handling.
- **Content-type detection** uses a Rust-based detector with a Python regex fallback, mapping results to specific `CompressionStrategy` values through `_strategy_from_detection()`.
- **Configuration options** like `enable_code_aware` and `prefer_code_aware_for_code` allow runtime overrides of the default strategy mappings.
- **Automatic fallback chains** ensure compression succeeds even when preferred compressors are unavailable, with full logging in `RouterCompressionResult`.

## Frequently Asked Questions

### What happens when ContentRouter encounters mixed content?

When the router detects mixed content through `is_mixed_content()` in [`headroom/transforms/content_router.py`](https://github.com/chopratejas/headroom/blob/main/headroom/transforms/content_router.py), it selects the `MIXED` strategy and splits the text into sections using `split_into_sections()`. Each section is then routed independently based on its specific content type, ensuring that code blocks receive `CODE_AWARE` compression while adjacent prose receives `TEXT` compression.

### Can I force ContentRouter to use a specific compressor?

Yes, you can influence the selection through `ContentRouterConfig` settings. Setting `enable_code_aware=False` disables the code-aware compressor entirely, while setting `prefer_code_aware_for_code=False` forces the router to use `KOMPRESS` instead of `CODE_AWARE` for source code. These configuration options are evaluated in `_strategy_from_detection()` before the final strategy is locked.

### How does the content detection fallback work?

The `_detect_content()` method first attempts to use the Rust-based `headroom._core.detect_content_type` for performance. If this detector returns `PLAIN_TEXT` or fails, the router falls back to `_regex_detect_content_type`, a pure-Python implementation that uses regex patterns to identify content types. This ensures robust detection even when the Rust extension is unavailable.

### What is the fallback order if a compressor is unavailable?

If the selected compressor is unavailable, Headroom follows a defined fallback chain: `SMART_CRUSHER` falls back to `KOMPRESS`, which in turn falls back to `LOG`. This chain is executed during `_apply_strategy_to_content()`, ensuring that compression always succeeds even when optional dependencies are missing.