mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
fix(toin): publish skip compression recommendations (#1782)
## Description TOIN already learns when a tool-output slice should skip compression, but the published recommendation artifact drops that signal. A high full-retrieval row can therefore still publish an ordinary compressor strategy even though TOIN marked it as skip-worthy. This change carries `skip_compression_recommended` into `recommendations.toml`, keeps Rust parsing backward compatible for older files, and makes skip rows publish a skip-oriented strategy hint instead of misleading compressor guidance. Refs #1775 ## Type of Change - [x] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [ ] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made - Publishes `skip_compression_recommended` in generated recommendation rows. - Uses retrieval-aware strategy output for rows TOIN already marked as skip-worthy. - Extends the Rust recommendation schema with a backward-compatible default for older TOML files. - Adds focused publish and schema coverage for skip and non-skip rows. ## Testing - [x] Unit tests pass (`uv run pytest tests/test_toin_publish.py -q`) - [x] Linting passes (`uv run ruff check headroom/cli/toin_publish.py headroom/telemetry/toin.py tests/test_toin_publish.py`) - [ ] Type checking passes (`uv run mypy headroom`) - [x] New tests added for new functionality - [ ] Manual testing performed - [ ] I have made corresponding changes to the documentation ### Test Output ```text uv run pytest tests/test_toin_publish.py -q: 8 passed uv run ruff check headroom/cli/toin_publish.py headroom/telemetry/toin.py tests/test_toin_publish.py: passed cargo fmt --all -- --check: passed cargo check -p headroom-core: passed cargo test -p headroom-core --lib transforms::recommendations: 6 passed cargo clippy --workspace -- -D warnings: passed ``` ## Real Behavior Proof - Environment: Windows for Python validation through the headless runner; Rust validation via focused local cargo commands where available. - Exact command / steps: `uv run pytest tests/test_toin_publish.py -q`, `uv run ruff check headroom/cli/toin_publish.py headroom/telemetry/toin.py tests/test_toin_publish.py`, `cargo fmt --all -- --check`, `cargo check -p headroom-core`, `cargo test -p headroom-core --lib transforms::recommendations`, and `cargo clippy --workspace -- -D warnings`. - Observed result: Skip-worthy rows carry `skip_compression_recommended = true` and a skip strategy hint; normal rows carry `false` and preserve their ordinary strategy. - Not tested: Live runtime dispatcher skip behavior and full Rust workspace tests. ## Review Readiness - [x] I have performed a self-review - [x] This PR is ready for human review ## Checklist - [x] My code follows the project's style guidelines - [x] I have performed a self-review of my code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] I have updated the CHANGELOG.md if applicable ## Additional Notes This PR fixes the published recommendation artifact. Runtime dispatcher enforcement remains a separate follow-up because it needs a dedicated consumer proof matrix. Documentation and changelog are left unchecked because this changes generated recommendation data and Headroom's changelog is generated from conventional commits.
This commit is contained in:
parent
9cbdba4dc1
commit
be51008c70
3 changed files with 68 additions and 3 deletions
|
|
@ -28,6 +28,7 @@
|
||||||
//! auth_mode = "payg"
|
//! auth_mode = "payg"
|
||||||
//! model_family = "claude-3-5"
|
//! model_family = "claude-3-5"
|
||||||
//! structure_hash = "deadbeef..."
|
//! structure_hash = "deadbeef..."
|
||||||
|
//! skip_compression_recommended = false
|
||||||
//! strategy_hint = "smart_crusher"
|
//! strategy_hint = "smart_crusher"
|
||||||
//! confidence = 0.87
|
//! confidence = 0.87
|
||||||
//! observations = 142
|
//! observations = 142
|
||||||
|
|
@ -71,6 +72,8 @@ pub struct Recommendation {
|
||||||
pub auth_mode: String,
|
pub auth_mode: String,
|
||||||
pub model_family: String,
|
pub model_family: String,
|
||||||
pub structure_hash: String,
|
pub structure_hash: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub skip_compression_recommended: bool,
|
||||||
pub strategy_hint: String,
|
pub strategy_hint: String,
|
||||||
pub confidence: f64,
|
pub confidence: f64,
|
||||||
pub observations: u64,
|
pub observations: u64,
|
||||||
|
|
@ -270,6 +273,7 @@ mod tests {
|
||||||
auth_mode = "payg"
|
auth_mode = "payg"
|
||||||
model_family = "claude-3-5"
|
model_family = "claude-3-5"
|
||||||
structure_hash = "deadbeef"
|
structure_hash = "deadbeef"
|
||||||
|
skip_compression_recommended = true
|
||||||
strategy_hint = "smart_crusher"
|
strategy_hint = "smart_crusher"
|
||||||
confidence = 0.87
|
confidence = 0.87
|
||||||
observations = 142
|
observations = 142
|
||||||
|
|
@ -292,11 +296,21 @@ observations = 60
|
||||||
let r = store
|
let r = store
|
||||||
.lookup(AuthMode::Payg, "claude-3-5", "deadbeef")
|
.lookup(AuthMode::Payg, "claude-3-5", "deadbeef")
|
||||||
.expect("hit");
|
.expect("hit");
|
||||||
|
assert!(r.skip_compression_recommended);
|
||||||
assert_eq!(r.strategy_hint, "smart_crusher");
|
assert_eq!(r.strategy_hint, "smart_crusher");
|
||||||
assert!((r.confidence - 0.87).abs() < 1e-9);
|
assert!((r.confidence - 0.87).abs() < 1e-9);
|
||||||
assert_eq!(r.observations, 142);
|
assert_eq!(r.observations, 142);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_toml_str_defaults_missing_skip_field_to_false() {
|
||||||
|
let store = RecommendationStore::from_toml_str(sample_toml()).expect("parses");
|
||||||
|
let r = store
|
||||||
|
.lookup(AuthMode::OAuth, "gpt-4o", "cafebabe")
|
||||||
|
.expect("hit");
|
||||||
|
assert!(!r.skip_compression_recommended);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn lookup_returns_none_for_missing_slice() {
|
fn lookup_returns_none_for_missing_slice() {
|
||||||
let store = RecommendationStore::from_toml_str(sample_toml()).expect("parses");
|
let store = RecommendationStore::from_toml_str(sample_toml()).expect("parses");
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ result as TOML the Rust proxy loads at startup
|
||||||
auth_mode = "payg"
|
auth_mode = "payg"
|
||||||
model_family = "claude-3-5"
|
model_family = "claude-3-5"
|
||||||
structure_hash = "deadbeef..."
|
structure_hash = "deadbeef..."
|
||||||
|
skip_compression_recommended = false
|
||||||
strategy_hint = "smart_crusher"
|
strategy_hint = "smart_crusher"
|
||||||
confidence = 0.87
|
confidence = 0.87
|
||||||
observations = 142
|
observations = 142
|
||||||
|
|
@ -30,7 +31,9 @@ alongside the Rust binary, and the proxy reads it once at startup.
|
||||||
# Output stability
|
# Output stability
|
||||||
|
|
||||||
Rows are sorted by ``(auth_mode, model_family, structure_hash)`` so the
|
Rows are sorted by ``(auth_mode, model_family, structure_hash)`` so the
|
||||||
file diffs cleanly across publishes. Strategies ship as the
|
file diffs cleanly across publishes. Rows with
|
||||||
|
``skip_compression_recommended = true`` publish
|
||||||
|
``strategy_hint = "skip_compression"``. Other rows ship the
|
||||||
ToolPattern's learned ``optimal_strategy`` (or the dominant entry of
|
ToolPattern's learned ``optimal_strategy`` (or the dominant entry of
|
||||||
``strategy_success_rates``). Confidence is the pattern's existing
|
``strategy_success_rates``). Confidence is the pattern's existing
|
||||||
confidence score — bounded ``[0.0, 0.95]`` by the confidence calculator.
|
confidence score — bounded ``[0.0, 0.95]`` by the confidence calculator.
|
||||||
|
|
@ -98,16 +101,19 @@ def _format_row(
|
||||||
auth_mode: str,
|
auth_mode: str,
|
||||||
model_family: str,
|
model_family: str,
|
||||||
structure_hash: str,
|
structure_hash: str,
|
||||||
|
skip_compression_recommended: bool,
|
||||||
strategy_hint: str,
|
strategy_hint: str,
|
||||||
confidence: float,
|
confidence: float,
|
||||||
observations: int,
|
observations: int,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Render one ``[[recommendation]]`` block."""
|
"""Render one ``[[recommendation]]`` block."""
|
||||||
|
skip_flag = "true" if skip_compression_recommended else "false"
|
||||||
return (
|
return (
|
||||||
"[[recommendation]]\n"
|
"[[recommendation]]\n"
|
||||||
f'auth_mode = "{_toml_escape(auth_mode)}"\n'
|
f'auth_mode = "{_toml_escape(auth_mode)}"\n'
|
||||||
f'model_family = "{_toml_escape(model_family)}"\n'
|
f'model_family = "{_toml_escape(model_family)}"\n'
|
||||||
f'structure_hash = "{_toml_escape(structure_hash)}"\n'
|
f'structure_hash = "{_toml_escape(structure_hash)}"\n'
|
||||||
|
f"skip_compression_recommended = {skip_flag}\n"
|
||||||
f'strategy_hint = "{_toml_escape(strategy_hint)}"\n'
|
f'strategy_hint = "{_toml_escape(strategy_hint)}"\n'
|
||||||
f"confidence = {confidence:.4f}\n"
|
f"confidence = {confidence:.4f}\n"
|
||||||
f"observations = {observations}\n"
|
f"observations = {observations}\n"
|
||||||
|
|
@ -132,12 +138,18 @@ def _eligible_rows(
|
||||||
if observations < min_observations:
|
if observations < min_observations:
|
||||||
continue
|
continue
|
||||||
auth_mode, model_family, sig_hash = key
|
auth_mode, model_family, sig_hash = key
|
||||||
|
strategy_hint = (
|
||||||
|
"skip_compression"
|
||||||
|
if pattern.skip_compression_recommended
|
||||||
|
else _select_strategy(pattern)
|
||||||
|
)
|
||||||
rows.append(
|
rows.append(
|
||||||
{
|
{
|
||||||
"auth_mode": auth_mode,
|
"auth_mode": auth_mode,
|
||||||
"model_family": model_family,
|
"model_family": model_family,
|
||||||
"structure_hash": sig_hash,
|
"structure_hash": sig_hash,
|
||||||
"strategy_hint": _select_strategy(pattern),
|
"skip_compression_recommended": pattern.skip_compression_recommended,
|
||||||
|
"strategy_hint": strategy_hint,
|
||||||
"confidence": float(pattern.confidence),
|
"confidence": float(pattern.confidence),
|
||||||
"observations": observations,
|
"observations": observations,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ Pins:
|
||||||
1. ``publish()`` writes a TOML file the stdlib ``tomllib`` can parse.
|
1. ``publish()`` writes a TOML file the stdlib ``tomllib`` can parse.
|
||||||
2. Slices below ``--min-observations`` are filtered out.
|
2. Slices below ``--min-observations`` are filtered out.
|
||||||
3. Rows include ``auth_mode``, ``model_family``, ``structure_hash``,
|
3. Rows include ``auth_mode``, ``model_family``, ``structure_hash``,
|
||||||
``strategy_hint``, ``confidence``, ``observations`` — the schema
|
``skip_compression_recommended``, ``strategy_hint``, ``confidence``,
|
||||||
|
``observations`` — the schema
|
||||||
``crates/headroom-core/src/transforms/recommendations.rs`` consumes.
|
``crates/headroom-core/src/transforms/recommendations.rs`` consumes.
|
||||||
4. The CLI entry point honors ``--output`` / ``--min-observations``.
|
4. The CLI entry point honors ``--output`` / ``--min-observations``.
|
||||||
"""
|
"""
|
||||||
|
|
@ -99,6 +100,7 @@ def test_publish_command_writes_toml(fresh_toin: ToolIntelligenceNetwork, tmp_pa
|
||||||
"auth_mode",
|
"auth_mode",
|
||||||
"model_family",
|
"model_family",
|
||||||
"structure_hash",
|
"structure_hash",
|
||||||
|
"skip_compression_recommended",
|
||||||
"strategy_hint",
|
"strategy_hint",
|
||||||
"confidence",
|
"confidence",
|
||||||
"observations",
|
"observations",
|
||||||
|
|
@ -106,12 +108,49 @@ def test_publish_command_writes_toml(fresh_toin: ToolIntelligenceNetwork, tmp_pa
|
||||||
assert row["auth_mode"] == "payg"
|
assert row["auth_mode"] == "payg"
|
||||||
assert row["model_family"] == "claude-3-5"
|
assert row["model_family"] == "claude-3-5"
|
||||||
assert row["structure_hash"] == sig.structure_hash
|
assert row["structure_hash"] == sig.structure_hash
|
||||||
|
assert row["skip_compression_recommended"] is False
|
||||||
assert row["strategy_hint"] == "smart_crusher"
|
assert row["strategy_hint"] == "smart_crusher"
|
||||||
assert isinstance(row["confidence"], float)
|
assert isinstance(row["confidence"], float)
|
||||||
assert 0.0 <= row["confidence"] <= 1.0
|
assert 0.0 <= row["confidence"] <= 1.0
|
||||||
assert row["observations"] == 60
|
assert row["observations"] == 60
|
||||||
|
|
||||||
|
|
||||||
|
def test_publish_preserves_skip_recommendation(
|
||||||
|
fresh_toin: ToolIntelligenceNetwork,
|
||||||
|
tmp_path: Path,
|
||||||
|
) -> None:
|
||||||
|
"""Skip-eligible rows publish the skip flag and skip strategy hint."""
|
||||||
|
items = [{"id": i, "status": "ok"} for i in range(20)]
|
||||||
|
sig = _record(
|
||||||
|
fresh_toin,
|
||||||
|
items=items,
|
||||||
|
n=60,
|
||||||
|
auth_mode="payg",
|
||||||
|
model_family="claude-3-5",
|
||||||
|
)
|
||||||
|
for _ in range(49):
|
||||||
|
fresh_toin.record_retrieval(
|
||||||
|
tool_signature_hash=sig.structure_hash,
|
||||||
|
retrieval_type="full",
|
||||||
|
strategy="smart_crusher",
|
||||||
|
auth_mode="payg",
|
||||||
|
model_family="claude-3-5",
|
||||||
|
)
|
||||||
|
|
||||||
|
output = tmp_path / "recommendations.toml"
|
||||||
|
rows_written = publish(
|
||||||
|
output_path=output,
|
||||||
|
min_observations=50,
|
||||||
|
toin=fresh_toin,
|
||||||
|
)
|
||||||
|
assert rows_written == 1
|
||||||
|
|
||||||
|
parsed = tomllib.loads(output.read_text(encoding="utf-8"))
|
||||||
|
row = parsed["recommendation"][0]
|
||||||
|
assert row["skip_compression_recommended"] is True
|
||||||
|
assert row["strategy_hint"] == "skip_compression"
|
||||||
|
|
||||||
|
|
||||||
def test_publish_filters_below_min_observations(
|
def test_publish_filters_below_min_observations(
|
||||||
fresh_toin: ToolIntelligenceNetwork,
|
fresh_toin: ToolIntelligenceNetwork,
|
||||||
tmp_path: Path,
|
tmp_path: Path,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue