feat: add memory management pipeline
Admission control, entropy-based micro-faulting, phantom tool injection for backing store queries, and xMemory session hierarchy for long conversations (50+ turns). Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
a13719f754
commit
681c1454cb
9 changed files with 3540 additions and 0 deletions
156
tests/test_admission.py
Normal file
156
tests/test_admission.py
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
"""Tests for the admission control module.
|
||||
|
||||
Tests the AdmissionController scoring logic across all four axes:
|
||||
type_score, novelty_score, utility_score, size_score, and the
|
||||
threshold-based admit/reject decision.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mnemosyne.admission import AdmissionController, AdmissionScore, DEFAULT_THRESHOLD
|
||||
|
||||
|
||||
# ── Type score ───────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
def test_admission_score_design_decision():
|
||||
"""design_decision has the highest type weight (0.9)."""
|
||||
ctrl = AdmissionController()
|
||||
score = ctrl.score("x" * 300, "design_decision", has_duplicate=False)
|
||||
assert score.type_score == 0.9
|
||||
|
||||
|
||||
def test_admission_score_conversation_phase():
|
||||
"""conversation_phase has the lowest type weight (0.3)."""
|
||||
ctrl = AdmissionController()
|
||||
score = ctrl.score("x" * 300, "conversation_phase", has_duplicate=False)
|
||||
assert score.type_score == 0.3
|
||||
|
||||
|
||||
def test_admission_unknown_type_default():
|
||||
"""Unknown object types default to 0.3."""
|
||||
ctrl = AdmissionController()
|
||||
score = ctrl.score("x" * 300, "totally_unknown_type", has_duplicate=False)
|
||||
assert score.type_score == 0.3
|
||||
|
||||
|
||||
# ── Novelty score ────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
def test_admission_duplicate_penalized():
|
||||
"""Duplicates get novelty_score=0.2 instead of 1.0."""
|
||||
ctrl = AdmissionController()
|
||||
score_unique = ctrl.score("x" * 300, "file_context", has_duplicate=False)
|
||||
score_dup = ctrl.score("x" * 300, "file_context", has_duplicate=True)
|
||||
assert score_unique.novelty_score == 1.0
|
||||
assert score_dup.novelty_score == 0.2
|
||||
assert score_dup.total < score_unique.total
|
||||
|
||||
|
||||
# ── Utility score ────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
def test_admission_utility_code_blocks():
|
||||
"""Content with code blocks gets utility boost."""
|
||||
ctrl = AdmissionController()
|
||||
content_with_code = "Here is code:\n```python\ndef foo(): pass\n```\n" + "x" * 200
|
||||
content_plain = "Just some plain text without code blocks. " + "x" * 200
|
||||
score_code = ctrl.score(content_with_code, "file_context", has_duplicate=False)
|
||||
score_plain = ctrl.score(content_plain, "file_context", has_duplicate=False)
|
||||
assert score_code.utility_score > score_plain.utility_score
|
||||
|
||||
|
||||
def test_admission_utility_entities():
|
||||
"""Content with many key_entities gets utility boost."""
|
||||
ctrl = AdmissionController()
|
||||
entities = ["foo.py", "bar.py", "baz.py"]
|
||||
score_with = ctrl.score("x" * 300, "file_context", has_duplicate=False, key_entities=entities)
|
||||
score_without = ctrl.score("x" * 300, "file_context", has_duplicate=False, key_entities=[])
|
||||
assert score_with.utility_score > score_without.utility_score
|
||||
|
||||
|
||||
# ── Size score ───────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
def test_admission_size_small_penalized():
|
||||
"""Very small content (< 100 chars) gets penalized size_score."""
|
||||
ctrl = AdmissionController()
|
||||
score = ctrl.score("tiny", "file_context", has_duplicate=False)
|
||||
assert score.size_score < 1.0
|
||||
assert score.size_score == len("tiny") / 100
|
||||
|
||||
|
||||
def test_admission_size_large_penalized():
|
||||
"""Very large content (> 50k chars) gets penalized size_score."""
|
||||
ctrl = AdmissionController()
|
||||
score = ctrl.score("x" * 80000, "file_context", has_duplicate=False)
|
||||
assert score.size_score < 1.0
|
||||
assert score.size_score >= 0.3
|
||||
|
||||
|
||||
def test_admission_size_normal():
|
||||
"""Normal-sized content (100-50k chars) gets size_score=1.0."""
|
||||
ctrl = AdmissionController()
|
||||
score = ctrl.score("x" * 500, "file_context", has_duplicate=False)
|
||||
assert score.size_score == 1.0
|
||||
|
||||
|
||||
# ── Threshold decisions ──────────────────────────────────────────────────
|
||||
|
||||
|
||||
def test_admission_threshold_admit():
|
||||
"""High-value content is admitted."""
|
||||
ctrl = AdmissionController()
|
||||
# design_decision (0.9 type) + unique (1.0 novelty) + code + entities + length
|
||||
content = "```python\ndef important(): pass\n```\n" + "x" * 300
|
||||
admitted, score = ctrl.should_admit(
|
||||
content,
|
||||
"design_decision",
|
||||
has_duplicate=False,
|
||||
key_entities=["foo.py", "bar.py", "baz.py"],
|
||||
)
|
||||
assert admitted is True
|
||||
assert score.total >= DEFAULT_THRESHOLD
|
||||
|
||||
|
||||
def test_admission_threshold_reject():
|
||||
"""Low-value duplicate conversation_phase is rejected."""
|
||||
ctrl = AdmissionController()
|
||||
# conversation_phase (0.3 type) + duplicate (0.2 novelty) + tiny content
|
||||
admitted, score = ctrl.should_admit("hi", "conversation_phase", has_duplicate=True)
|
||||
assert admitted is False
|
||||
assert score.total < DEFAULT_THRESHOLD
|
||||
|
||||
|
||||
# ── Stats tracking ───────────────────────────────────────────────────────
|
||||
|
||||
|
||||
def test_admission_stats_tracking():
|
||||
"""Stats correctly count admitted and rejected objects."""
|
||||
ctrl = AdmissionController()
|
||||
assert ctrl.stats == {"admitted": 0, "rejected": 0}
|
||||
|
||||
# Admit a high-value object
|
||||
ctrl.should_admit(
|
||||
"```python\ndef foo(): pass\n```\n" + "x" * 300,
|
||||
"design_decision",
|
||||
has_duplicate=False,
|
||||
key_entities=["a.py", "b.py", "c.py"],
|
||||
)
|
||||
assert ctrl.stats["admitted"] == 1
|
||||
|
||||
# Reject a low-value object
|
||||
ctrl.should_admit("hi", "conversation_phase", has_duplicate=True)
|
||||
assert ctrl.stats["rejected"] == 1
|
||||
assert ctrl.stats["admitted"] == 1
|
||||
|
||||
|
||||
# ── Edge cases ───────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
def test_admission_empty_content():
|
||||
"""Empty content gets size_score=0 and low utility."""
|
||||
ctrl = AdmissionController()
|
||||
score = ctrl.score("", "file_context", has_duplicate=False)
|
||||
assert score.size_score == 0.0
|
||||
assert score.utility_score == 0.0
|
||||
Loading…
Add table
Add a link
Reference in a new issue