generated from coulomb/repo-seed
feat(memory): complete CYA-WP-0006 Profile 1 production hardening
Add guided reflection capture with preview, cya memory reflections CLI, near-duplicate compaction, budget-capped surfacing, and expanded tests. Profile 1 is now documented as production-ready in README and MemoryVision.
This commit is contained in:
86
tests/test_orchestrator.py
Normal file
86
tests/test_orchestrator.py
Normal file
@@ -0,0 +1,86 @@
|
||||
"""Orchestrator tests — Profile 1 surfacing and explain-context roundtrip."""
|
||||
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from rich.console import Console
|
||||
|
||||
from cya.memory import KIND_REFLECTION, remember_reflection
|
||||
from cya.memory.reflections import format_reflection_surfacing
|
||||
from cya.orchestrator import handle_request
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def isolated_memory(monkeypatch, tmp_path):
|
||||
mem_dir = tmp_path / "memory"
|
||||
mem_dir.mkdir()
|
||||
|
||||
def _fake_mem_path(scope: str = "cwd") -> Path:
|
||||
return mem_dir / f"{scope}.json"
|
||||
|
||||
monkeypatch.setattr("cya.memory._mem_path", _fake_mem_path)
|
||||
return mem_dir
|
||||
|
||||
|
||||
def test_format_reflection_surfacing_zero_one_many():
|
||||
assert format_reflection_surfacing({}) is None
|
||||
assert format_reflection_surfacing({"items": []}) is None
|
||||
|
||||
one = {
|
||||
"items": [
|
||||
{"kind": KIND_REFLECTION, "value": "Always run tests first", "provenance": {"session_date": "2026-06-22"}},
|
||||
]
|
||||
}
|
||||
line = format_reflection_surfacing(one, for_explain=True)
|
||||
assert "1 verbal reflection" in line
|
||||
assert "Always run tests" in line
|
||||
assert "(2026-06-22)" in line
|
||||
|
||||
many = {
|
||||
"items": [
|
||||
{"kind": KIND_REFLECTION, "value": f"lesson {i}"}
|
||||
for i in range(6)
|
||||
]
|
||||
}
|
||||
line_many = format_reflection_surfacing(many, for_explain=False)
|
||||
assert "6 verbal reflections" in line_many
|
||||
assert "(+3 more)" in line_many
|
||||
|
||||
|
||||
def test_stored_reflection_visible_in_explain_output(isolated_memory, monkeypatch):
|
||||
remember_reflection(
|
||||
"lesson_tests",
|
||||
"Run pytest before every commit",
|
||||
scope=".",
|
||||
provenance={"session_date": "2026-06-22", "scope": ".", "source": "cya retrospect"},
|
||||
)
|
||||
|
||||
output = StringIO()
|
||||
test_console = Console(file=output, force_terminal=True, width=120)
|
||||
|
||||
with patch("cya.orchestrator.console", test_console):
|
||||
with patch("cya.orchestrator.collect") as mock_collect:
|
||||
mock_collect.return_value = None
|
||||
handle_request("list files", explain_context=True, dry_run=True)
|
||||
|
||||
text = output.getvalue()
|
||||
assert "Reflections:" in text or "verbal reflection" in text.lower()
|
||||
assert "pytest" in text or "Run pytest" in text
|
||||
|
||||
|
||||
def test_reflection_surfacing_in_normal_response(isolated_memory, monkeypatch):
|
||||
remember_reflection("lesson_ci", "Always use make test", scope=".")
|
||||
|
||||
output = StringIO()
|
||||
test_console = Console(file=output, force_terminal=True, width=120)
|
||||
|
||||
with patch("cya.orchestrator.console", test_console):
|
||||
with patch("cya.orchestrator.collect") as mock_collect:
|
||||
with patch("cya.orchestrator.get_user_confirmation", return_value=True):
|
||||
mock_collect.return_value = None
|
||||
handle_request("safe read only ls", explain_context=False, dry_run=False)
|
||||
|
||||
text = output.getvalue()
|
||||
assert "verbal reflection" in text.lower() or "influenced this" in text
|
||||
Reference in New Issue
Block a user