Files
project-lyra/tests/test_profile.py
T
serversdown 2a73033eed perf: incremental profile rebuilds — fold new gists instead of re-digesting all
The profile pass map-reduced every session gist (~851) on every consolidation
firing — the biggest redundant-work and MI50-heat source left after the eras fix.
Now: skip when nothing's new, fold only the gists added since last build into the
existing profile, and full-rebuild only when there's no profile, too much has
accumulated to fold safely (>FOLD_LIMIT), on a periodic cadence (anti-drift), or
when forced.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 04:05:24 +00:00

85 lines
3.7 KiB
Python

"""Profile derivation: fold only new gists into the existing profile (incremental).
The old pass re-digested all ~851 gists every consolidation; this checks the cheap
delta path fires in steady state and the full rebuild fires only when it should.
"""
from __future__ import annotations
import importlib
import pytest
from lyra.memory import Summary
@pytest.fixture
def prof(monkeypatch):
import lyra.profile as profile
importlib.reload(profile)
return profile
def _wire(profile, monkeypatch, gists, covered, existing):
"""Stub memory + the LLM passes; record which path ran."""
state = {"stored_content": existing, "stored_covered": covered, "calls": []}
monkeypatch.setattr(profile.memory, "list_summaries",
lambda: [Summary(f"s{i}", g, i, "t") for i, g in enumerate(gists)])
monkeypatch.setattr(profile.memory, "get_profile", lambda: state["stored_content"])
monkeypatch.setattr(profile.memory, "profile_sessions_covered", lambda: state["stored_covered"])
def set_profile(content, sessions_covered, profile_id="self"):
state["stored_content"], state["stored_covered"] = content, sessions_covered
monkeypatch.setattr(profile.memory, "set_profile", set_profile)
monkeypatch.setattr(profile, "_map_reduce",
lambda gists, backend: state["calls"].append(("map_reduce", len(gists))) or "facts")
monkeypatch.setattr(profile, "_call",
lambda prompt, body, backend: state["calls"].append(("fold",)) or "folded profile")
return state
def test_no_profile_yet_does_full_rebuild(prof, monkeypatch):
state = _wire(prof, monkeypatch, gists=["a", "b", "c"], covered=0, existing=None)
out = prof.rebuild_profile(backend="local")
assert state["calls"] == [("map_reduce", 3)] # mapped all three gists
assert out == "facts" and state["stored_covered"] == 3
def test_unchanged_skips_entirely(prof, monkeypatch):
state = _wire(prof, monkeypatch, gists=["a", "b"], covered=2, existing="old profile")
out = prof.rebuild_profile(backend="local")
assert state["calls"] == [] # no LLM work at all
assert out == "old profile"
def test_small_delta_folds_only_new(prof, monkeypatch):
state = _wire(prof, monkeypatch, gists=["a", "b", "c", "d"], covered=2, existing="old profile")
out = prof.rebuild_profile(backend="local")
assert state["calls"] == [("map_reduce", 2), ("fold",)] # mapped just the 2 new, then folded
assert out == "folded profile" and state["stored_covered"] == 4
def test_force_does_full_rebuild(prof, monkeypatch):
state = _wire(prof, monkeypatch, gists=["a", "b", "c"], covered=3, existing="old profile")
out = prof.rebuild_profile(backend="local", force=True)
assert state["calls"] == [("map_reduce", 3)] # ignored the up-to-date profile
assert out == "facts"
def test_big_gap_falls_back_to_full_rebuild(prof, monkeypatch):
gists = [str(i) for i in range(40)] # 30 new > FOLD_LIMIT
state = _wire(prof, monkeypatch, gists=gists, covered=10, existing="old profile")
out = prof.rebuild_profile(backend="local")
assert state["calls"] == [("map_reduce", 40)] # full rebuild, not a giant fold
assert out == "facts"
def test_crossing_cadence_forces_full_rebuild(prof, monkeypatch):
# covered=98, total=102 is a tiny delta, but it crosses the 100-session boundary.
gists = [str(i) for i in range(102)]
state = _wire(prof, monkeypatch, gists=gists, covered=98, existing="old profile")
out = prof.rebuild_profile(backend="local")
assert state["calls"] == [("map_reduce", 102)] # anti-drift full rebuild
assert out == "facts"