band-aider-pub/tests/judgement/test_file_manager_memory_summaries.py
2026-10-17 11:57:37 -07:00

160 lines
5.6 KiB
Python

# SPDX-FileCopyrightText: 2026 Art Sea LLC
#
# SPDX-License-Identifier: AGPL-3.0-only
"""Memory-backed semantic summary contracts for ``FileManager``."""
from __future__ import annotations
import json
from pathlib import Path
from band_aider.context.class_meta import ClassMeta, ContentType
from band_aider.judgement.file_manager import FileManager
from band_aider.judgement.file_parser import FileParser
from band_aider.judgement.prompt_formatter import MarkdownPromptFormatterBuilder
from tests.support.completion_clients import (
ScriptedOpenAICompatibleClient,
StaticOpenAICompatibleClient,
)
from tests.support.memory_repo_exec import MemoryRepoExec
def _manager(client: ScriptedOpenAICompatibleClient) -> FileManager:
"""Build one real manager over source and test exhibits held only in memory."""
root = Path("/testbed/file-manager-summary")
repo_exec = MemoryRepoExec(root)
repo_exec.write_text(root / "src" / "service.py", "def service() -> str:\n return 'before'\n")
repo_exec.write_text(
root / "tests" / "test_service.py",
"from service import service\n\ndef test_service() -> None:\n assert service() == 'before'\n",
)
formatter = MarkdownPromptFormatterBuilder()
parser_client = StaticOpenAICompatibleClient(
json.dumps(
{
"location": "",
"summary": "memory fixture",
"relevance": ["fixture relevance"],
"irrelevance": [],
"relevant_symbols": {"service": "fixture symbol"},
}
)
)
return FileManager(
parser=FileParser(parser_client, formatter, repo_exec),
client=client,
repo_root=root,
src_root=root / "src",
test_root=root / "tests",
actor="test",
prompt_formatter_builder=formatter,
repo_exec=repo_exec,
prompt="FILE_MANAGER_TASK_SENTINEL",
)
def _source(manager: FileManager) -> ClassMeta:
"""Return the sole source exhibit after proving the fixture populated it."""
source = manager.current_src("src/service.py")
assert source is not None
return source
def _test(manager: FileManager) -> ClassMeta:
"""Return the sole test exhibit after proving the fixture populated it."""
test = manager.current_test("tests/test_service.py")
assert test is not None
return test
def test_file_manager_summarizes_dirty_memory_metadata_with_a_stationary_response() -> None:
"""Dirty metadata produces the LLM-backed completion summary without repository IO."""
client = ScriptedOpenAICompatibleClient(
(
json.dumps({"cdc": "SOURCE_CDC_SENTINEL"}),
json.dumps({"summary": "WORK_SUMMARY_SENTINEL"}),
)
)
manager = _manager(client)
source = _source(manager)
updated_source = ClassMeta(
location=source.location,
summary="updated source summary",
relevance=["updated relevance"],
relevant_symbols={"service": "updated symbol"},
content_type=ContentType.Source,
)
manager.upsert_src(updated_source, "SOURCE_UPDATE_PROMPT_SENTINEL")
summary = manager.summarize("SUMMARY_HINT_SENTINEL")
refreshed = _source(manager)
assert summary == "WORK_SUMMARY_SENTINEL"
assert refreshed.summary == "updated source summary"
assert refreshed.cdc[-1][2] == "SOURCE_CDC_SENTINEL"
assert manager.src_net_effects() == {"src/service.py": "changed"}
assert manager.test_net_effects() == {"tests/test_service.py": "unchanged"}
assert "WORK SUMMARY" in client.prompts[-1]
assert "SOURCE_UPDATE_PROMPT_SENTINEL" not in client.prompts[-1]
def test_file_manager_squashes_dirty_memory_metadata_to_its_upstream_owner() -> None:
"""A scoped manager transfers only explicitly dirty metadata to its upstream owner."""
client = ScriptedOpenAICompatibleClient(
(
json.dumps({"cdc": "SCOPED_SOURCE_CDC_SENTINEL"}),
json.dumps(
{
"summary": "SCOPED_SHARED_SUMMARY_SENTINEL",
"files": {
"src/service.py": "SCOPED_SOURCE_SUMMARY_SENTINEL",
"tests/test_service.py": "SCOPED_TEST_SUMMARY_SENTINEL",
},
}
),
)
)
upstream = _manager(client)
scoped = FileManager.from_manager(upstream)
source = _source(scoped)
test = _test(scoped)
scoped.upsert_src(
ClassMeta(
location=source.location,
summary="scoped source summary",
relevance=["scoped source relevance"],
relevant_symbols={"service": "scoped symbol"},
content_type=ContentType.Source,
),
"SCOPED_SOURCE_UPDATE_SENTINEL",
)
scoped.upsert_test(
ClassMeta(
location=test.location,
summary="scoped test summary",
relevance=["ignored test relevance"],
relevant_symbols={"test_service": "ignored test symbol"},
content_type=ContentType.Test,
),
"SCOPED_TEST_UPDATE_SENTINEL",
)
scoped.squash_to_upstream("SCOPED_HINT_SENTINEL")
upstream_source = _source(upstream)
upstream_test = _test(upstream)
assert upstream_source.summary == "scoped source summary"
assert upstream_test.summary == "scoped test summary"
assert upstream_source.cdc[-1][2] == "SCOPED_SOURCE_SUMMARY_SENTINEL"
assert upstream_test.cdc[-1][2] == "SCOPED_TEST_SUMMARY_SENTINEL"
assert upstream.src_dirty == {"src/service.py": True}
assert upstream.test_dirty == {"tests/test_service.py": True}
assert "SCOPED CDC SUMMARY" in client.prompts[-1]
assert "SCOPED_HINT_SENTINEL" in client.prompts[-1]