mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
fix: clear CI mypy + rust test failures introduced in eaf5980
compression_units.py:
- Replace dict-unpacking pattern with dataclasses.replace() so mypy can
type-check fields. The `**base` form forced mypy to infer
`dict[str, object]`, which doesn't satisfy the per-field types of
UnitCompressionResult (46 arg-type errors).
- Use `isinstance(candidates, Iterable)` for the transform-iteration
guard. The previous `iter()` call had a `# type: ignore[arg-type]`
that was misclassified — mypy actually emits `call-overload` here.
live_zone_thresholds.rs:
- Update the JsonArray threshold assertion from 1024 to 512 to match
the new constant. eaf5980 lowered THRESHOLD_JSON_ARRAY from 1024 → 512
in live_zone.rs but missed this integration test.
This commit is contained in:
parent
c7af8307d1
commit
17ffae0cd8
2 changed files with 35 additions and 37 deletions
|
|
@ -51,14 +51,14 @@ fn first_tool_result_action(out: &LiveZoneOutcome) -> BlockAction {
|
|||
|
||||
#[test]
|
||||
fn below_threshold_no_compression_attempted() {
|
||||
// 200 bytes of homogeneous JSON dicts — well below the 1 KiB
|
||||
// 200 bytes of homogeneous JSON dicts — well below the 512 B
|
||||
// JsonArray threshold. The dispatcher must record
|
||||
// `BelowByteThreshold` and emit `NoChange`; no compressor runs.
|
||||
let small_array: Vec<Value> = (0..3).map(|i| json!({"id": i, "v": "x"})).collect();
|
||||
let payload = serde_json::to_string(&small_array).unwrap();
|
||||
assert!(
|
||||
payload.len() < 1024,
|
||||
"fixture must stay below the 1 KiB JsonArray threshold; got {}",
|
||||
payload.len() < 512,
|
||||
"fixture must stay below the 512 B JsonArray threshold; got {}",
|
||||
payload.len()
|
||||
);
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ fn below_threshold_no_compression_attempted() {
|
|||
} => {
|
||||
assert_eq!(content_type, "json_array");
|
||||
assert_eq!(byte_count, payload.len());
|
||||
assert_eq!(threshold_bytes, 1024);
|
||||
assert_eq!(threshold_bytes, 512);
|
||||
}
|
||||
other => panic!("expected BelowByteThreshold for sub-threshold JSON, got {other:?}"),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ replacements back into their native request shape.
|
|||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Iterable
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass, field, replace
|
||||
from typing import Protocol
|
||||
|
||||
from .content_router import CompressionStrategy, ContentRouter, RouterCompressionResult
|
||||
|
|
@ -63,11 +63,9 @@ def find_content_router(transforms: object) -> ContentRouter | None:
|
|||
"""Return the first ContentRouter in a pipeline or iterable."""
|
||||
|
||||
candidates = getattr(transforms, "transforms", transforms)
|
||||
try:
|
||||
iterator = iter(candidates) # type: ignore[arg-type]
|
||||
except TypeError:
|
||||
if not isinstance(candidates, Iterable):
|
||||
return None
|
||||
for transform in iterator:
|
||||
for transform in candidates:
|
||||
if isinstance(transform, ContentRouter):
|
||||
return transform
|
||||
return None
|
||||
|
|
@ -86,32 +84,32 @@ def compress_unit_with_router(
|
|||
"""
|
||||
|
||||
tokens_before = tokenizer.count_text(unit.text)
|
||||
base = {
|
||||
"original": unit.text,
|
||||
"compressed": unit.text,
|
||||
"modified": False,
|
||||
"tokens_before": tokens_before,
|
||||
"tokens_after": tokens_before,
|
||||
"tokens_saved": 0,
|
||||
"transforms_applied": [],
|
||||
"strategy": CompressionStrategy.PASSTHROUGH.value,
|
||||
"router_result": None,
|
||||
}
|
||||
base = UnitCompressionResult(
|
||||
original=unit.text,
|
||||
compressed=unit.text,
|
||||
modified=False,
|
||||
tokens_before=tokens_before,
|
||||
tokens_after=tokens_before,
|
||||
tokens_saved=0,
|
||||
transforms_applied=[],
|
||||
strategy=CompressionStrategy.PASSTHROUGH.value,
|
||||
router_result=None,
|
||||
)
|
||||
|
||||
if not unit.mutable:
|
||||
return UnitCompressionResult(**base, reason="immutable")
|
||||
return replace(base, reason="immutable")
|
||||
if unit.role == "user":
|
||||
return UnitCompressionResult(**base, reason="protected_user_message")
|
||||
return replace(base, reason="protected_user_message")
|
||||
if unit.role in {"system", "developer"}:
|
||||
return UnitCompressionResult(**base, reason="protected_system_message")
|
||||
return replace(base, reason="protected_system_message")
|
||||
if unit.role == "assistant" and unit.metadata.get("compress_assistant") != "true":
|
||||
return UnitCompressionResult(**base, reason="protected_assistant_message")
|
||||
return replace(base, reason="protected_assistant_message")
|
||||
if unit.cache_zone != "live":
|
||||
return UnitCompressionResult(**base, reason=f"cache_zone_{unit.cache_zone}")
|
||||
return replace(base, reason=f"cache_zone_{unit.cache_zone}")
|
||||
if len(unit.text) < unit.min_bytes:
|
||||
return UnitCompressionResult(**base, reason="below_unit_floor")
|
||||
return replace(base, reason="below_unit_floor")
|
||||
if "Retrieve more: hash=" in unit.text or "Retrieve original: hash=" in unit.text:
|
||||
return UnitCompressionResult(**base, reason="already_compressed")
|
||||
return replace(base, reason="already_compressed")
|
||||
|
||||
router_result = router.compress(
|
||||
unit.text,
|
||||
|
|
@ -122,21 +120,21 @@ def compress_unit_with_router(
|
|||
replacement = router_result.compressed
|
||||
strategy = router_result.strategy_used.value
|
||||
if replacement == unit.text:
|
||||
return UnitCompressionResult(
|
||||
**{**base, "strategy": strategy, "router_result": router_result},
|
||||
return replace(
|
||||
base,
|
||||
strategy=strategy,
|
||||
router_result=router_result,
|
||||
reason="router_no_change",
|
||||
)
|
||||
|
||||
tokens_after = tokenizer.count_text(replacement)
|
||||
if tokens_after >= tokens_before:
|
||||
return UnitCompressionResult(
|
||||
**{
|
||||
**base,
|
||||
"compressed": replacement,
|
||||
"tokens_after": tokens_after,
|
||||
"strategy": strategy,
|
||||
"router_result": router_result,
|
||||
},
|
||||
return replace(
|
||||
base,
|
||||
compressed=replacement,
|
||||
tokens_after=tokens_after,
|
||||
strategy=strategy,
|
||||
router_result=router_result,
|
||||
reason="rejected_not_smaller",
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue