rewrite phase 1

This commit is contained in:
2026-07-22 23:10:23 +02:00
parent 7527831af6
commit 98ac4abca1
89 changed files with 9179 additions and 2795 deletions
+109
View File
@@ -0,0 +1,109 @@
from pathlib import Path
from string import Template
import pytest
from pydantic import BaseModel
import agentci.prompts
from agentci.opencode import load_schema
from agentci.prompts import PromptLibrary
from agentci.workflows.model import (
AgentResult,
DiscussionReply,
PlanArtifact,
ReviewFinding,
ReviewReport,
)
PROMPTS = {
"plan_initial": {"context", "request"},
"plan_review": {"context", "artifact"},
"plan_revision": {"artifact", "review"},
"discuss": {"artifact", "message"},
"plan_iterate": {"context", "artifact", "review", "message"},
"implement_initial": {
"context",
"artifact",
"request",
"development_environment",
},
"implementation_review": {"issue_context", "artifact", "pull_context"},
"implementation_revision": {"review", "development_environment"},
"implementation_iterate": {
"context",
"review",
"message",
"development_environment",
},
"fix": {"context", "message", "development_environment"},
}
SCHEMAS: dict[str, tuple[type[BaseModel], set[str]]] = {
"plan.json": (PlanArtifact, {"plan_markdown"}),
"discussion.json": (DiscussionReply, {"markdown"}),
"agent_result.json": (AgentResult, {"summary_markdown", "tests"}),
"review.json": (ReviewReport, {"summary", "findings"}),
}
def prompt_directory() -> Path:
module_file = agentci.prompts.__file__
assert module_file is not None
return Path(module_file).parent
@pytest.mark.parametrize(("name", "identifiers"), PROMPTS.items())
def test_referenced_prompt_loads_and_renders(name: str, identifiers: set[str]) -> None:
directory = prompt_directory()
source = (directory / f"{name}.md").read_text()
values = {identifier: f"<{identifier}-value>" for identifier in identifiers}
assert set(Template(source).get_identifiers()) == identifiers
rendered = PromptLibrary(directory).render(name, **values)
for value in values.values():
assert value in rendered
def test_prompt_resource_set_matches_workflow_references() -> None:
names = {path.stem for path in prompt_directory().glob("*.md")}
assert names == set(PROMPTS)
def test_prompt_render_rejects_missing_template_value() -> None:
with pytest.raises(KeyError, match="request"):
PromptLibrary(prompt_directory()).render("plan_initial", context="context")
@pytest.mark.parametrize(("name", "contract"), SCHEMAS.items())
def test_referenced_schema_matches_result_model(
name: str, contract: tuple[type[BaseModel], set[str]]
) -> None:
model, required = contract
schema = load_schema(prompt_directory() / "schemas", name)
assert schema["type"] == "object"
assert schema["additionalProperties"] is False
assert set(schema["properties"]) == set(model.model_fields)
assert set(schema["required"]) == required
def test_review_finding_schema_matches_model_and_severity_values() -> None:
schema = load_schema(prompt_directory() / "schemas", "review.json")
finding = schema["properties"]["findings"]["items"]
assert set(finding["properties"]) == set(ReviewFinding.model_fields)
assert set(finding["required"]) == set(ReviewFinding.model_fields)
assert finding["properties"]["severity"]["enum"] == [
"blocking",
"major",
"minor",
]
assert finding["additionalProperties"] is False
def test_schema_resource_set_matches_workflow_references() -> None:
schema_directory = prompt_directory() / "schemas"
names = {path.name for path in schema_directory.glob("*.json")}
assert names == set(SCHEMAS)