"""The vault and memory as a loop offers them (L10, L6.4), apart from any agent: tools only for what exists, labelled results, failures as results, notes only about the item's own project, provenance recorded.""" import io from pathlib import Path from nisse_core.knowledge.handlers import Knowledge from nisse_core.knowledge.memory import Memory from nisse_core.knowledge.vault import Vault, split_frontmatter from nisse_core.loop.tools import names from nisse_core.oplog import OpLog FOLDER = "memory/agent" def knowledge(tmp_path: Path, *, memory: bool = True) -> Knowledge: (tmp_path / "notes").mkdir() (tmp_path / "notes" / "Style.md").write_text("Use split.\n") vault = Vault(tmp_path, {FOLDER: "rw", "notes": "ro"}, agent="agent") return Knowledge( vault, Memory(vault, FOLDER) if memory else None, OpLog("t", io.StringIO()) ) def test_tools_and_prompt_follow_what_exists(tmp_path: Path) -> None: both = knowledge(tmp_path) assert names(both.tools()) == { "read_note", "list_notes", "search_notes", "remember", "forget", } assert "knowledge vault" in both.prompt() and "Your memory" in both.prompt() none = Knowledge(None, None, OpLog("t", io.StringIO())) assert none.tools() == [] and none.prompt() == "" and none.index("x", None) is None assert none.handlers("x", project=None, provenance={}, say=print) == {} def test_notes_are_read_labelled_and_failures_are_results(tmp_path: Path) -> None: handlers = knowledge(tmp_path, memory=False).handlers( "x", project=None, provenance={}, say=print ) assert "remember" not in handlers assert handlers["read_note"]({"path": "notes/Style.md"}) == ( "[vault: notes/Style.md]\nUse split.\n", True, ) assert handlers["read_note"]({"path": "notes/No.md"})[1] is False def test_memory_is_about_the_items_own_project_only(tmp_path: Path) -> None: k = knowledge(tmp_path) said: list[str] = [] handlers = k.handlers( "x", project="demo", provenance={"source": "work item x"}, say=said.append ) fact = {"name": "short-prs", "description": "Small PRs", "fact": "Don likes them"} assert handlers["remember"]({**fact, "scope": "project"}) == ( "remembered short-prs", True, ) note = (tmp_path / FOLDER / "projects" / "demo" / "short-prs.md").read_text() assert split_frontmatter(note)[0]["provenance"]["project"] == "demo" assert said == ["Remembered: Small PRs"] assert "short-prs" in (k.index("x", "demo") or "") general = k.handlers("y", project=None, provenance={}, say=said.append) assert general["remember"]({**fact, "scope": "project"})[1] is False