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

106 lines
4.3 KiB
Python

# SPDX-FileCopyrightText: 2026 Art Sea LLC
#
# SPDX-License-Identifier: AGPL-3.0-only
from __future__ import annotations
import json
from dataclasses import dataclass
from band_aider.ai_client.json_completion import load_json_completion
from band_aider.ai_client.openai_compatible_client import OpenAICompatibleClient
from band_aider.context.class_meta import ClassMeta
from band_aider.judgement.vibe_check import VibeCheck
from band_aider.judgement.prompt_formatter import PromptFormatterBuilder, format_prompt
@dataclass
class CurrentCotCompletedCheck(VibeCheck):
"""Decide whether one permanently bound COT task is satisfied by stabilized root evidence."""
client: OpenAICompatibleClient
prompt_formatter_builder: PromptFormatterBuilder
reason: str = ""
def __call__(self, task: str, files: list[ClassMeta]) -> bool:
"""Return True only when stabilized evidence completes the bound COT task."""
data = load_json_completion(
self.client,
self._prompt(task, files),
prompt_formatter_builder=self.prompt_formatter_builder,
check_name=type(self).__name__,
files=tuple(map(lambda file: file.location, files)),
references=[{'completed': True, 'reason': ''}],
)
completed = bool(data.get("completed"))
self.reason = str(data.get("reason") or "")
self.changes.append((self, completed))
return completed
def _file_picture(self, candidate: ClassMeta) -> dict[str, object]:
"""Return CDC-backed evidence for the production root bound to one COT."""
return {
"location": candidate.location,
"summary": candidate.summary,
"relevance": candidate.relevance,
"relevant_symbols": candidate.relevant_symbols,
"cdc": [
{
"changed_at": changed_at.isoformat(),
"actor": actor,
"description": description,
}
for changed_at, actor, description in candidate.cdc
],
}
def _prompt(self, task: str, files: list[ClassMeta]) -> str:
"""Build the completion prompt for one COT and its permanently bound root."""
expected = {
"completed": True,
"reason": "one sentence explaining the yes or no decision",
}
body = (
"Decide whether the current stabilization goal is satisfied by the current COT task.\n"
"The original stabilization goal is the immutable contract; the current task and file metadata are subordinate evidence.\n"
"Use only the current COT task and the stabilized file metadata below. "
"The CDC history is the primary evidence of work already completed.\n\n"
"The stabilized file evidence below belongs to the production root permanently bound to this COT task.\n"
"Return completed true only when the stabilized evidence shows that this bound COT task is satisfied.\n"
"Return completed false when the stabilized evidence does not demonstrate completion of this bound COT task.\n\n"
"Return strict JSON only with this shape:\n"
f"{json.dumps(expected, indent=2)}\n\n"
"ORIGINAL COT: IMMUTABLE STABILIZATION TARGET\n"
f"{format_prompt(self.prompt_formatter_builder, 'ORIGINAL STABILIZATION GOAL', self.prompt, depth=2)}\n\n"
f"Current COT task:\n{task}\n\n"
"Stabilized file evidence:\n"
f"{json.dumps([self._file_picture(file) for file in files], indent=2)}"
)
return format_prompt(
self.prompt_formatter_builder,
"CURRENT COT COMPLETION",
body,
escape=False,
)
@dataclass
class CurrentCotCompletedCheckFactory:
"""Create completion checks for permanently bound COT task/root records."""
client: OpenAICompatibleClient
prompt_formatter_builder: PromptFormatterBuilder
def create(self, original_prompt: str) -> CurrentCotCompletedCheck:
"""Create a completion judgement for one bound COT task after stabilization."""
return CurrentCotCompletedCheck(
changes=[],
prompt=original_prompt,
client=self.client,
prompt_formatter_builder=self.prompt_formatter_builder,
)