CascadingDev/agents/visualizer.py

89 lines
2.6 KiB
Python

#!/usr/bin/env python3
"""
AI_Visual agent.
Generates placeholder PlantUML diagrams on demand when @AI_visual is
mentioned in a discussion. Provides scaffolding for future AI-powered
diagram generation.
"""
from __future__ import annotations
import argparse
from pathlib import Path
MENTION_TOKEN = "@AI_visual"
BLOCK_START = "<!-- AUTO:VISUAL START -->"
BLOCK_END = "<!-- AUTO:VISUAL END -->"
def find_next_diagram(diagram_dir: Path) -> Path:
diagram_dir.mkdir(parents=True, exist_ok=True)
existing = sorted(diagram_dir.glob("diagram_*.puml"))
next_index = len(existing) + 1
return diagram_dir / f"diagram_{next_index:03d}.puml"
def write_placeholder_plantuml(path: Path, prompt: str) -> None:
content = "\n".join(
[
"@startuml",
"' Auto-generated scaffold",
"' Requested via @AI_visual",
f"note as N1",
prompt.strip() or "Diagram requested with no additional context.",
"end note",
"@enduml",
"",
]
)
path.write_text(content, encoding="utf-8")
def append_comment(discussion_path: Path, diagram_rel: Path) -> None:
comment = (
f"{BLOCK_START}\n"
"Name: AI_Visual\n"
f"Generated diagram: `{diagram_rel.as_posix()}`\n"
"\n"
"Let me know if you need an updated view.\n"
f"{BLOCK_END}\n"
)
text = discussion_path.read_text(encoding="utf-8")
if text and not text.endswith("\n"):
text += "\n"
discussion_path.write_text(text + comment, encoding="utf-8")
def main() -> int:
parser = argparse.ArgumentParser(description="AI Visual agent")
parser.add_argument("--repo-root", required=True, help="Repository root path")
parser.add_argument("--path", required=True, help="Relative path to discussion file")
args = parser.parse_args()
repo_root = Path(args.repo_root).resolve()
discussion_rel = Path(args.path)
discussion_path = (repo_root / discussion_rel).resolve()
if not discussion_path.exists():
return 0
text = discussion_path.read_text(encoding="utf-8")
if MENTION_TOKEN not in text:
return 0
# Simple check to avoid re-processing if our comment is already there
if f"Name: AI_Visual" in text and BLOCK_START in text:
return 0
diagram_dir = discussion_path.parent.parent / "diagrams"
diagram_path = find_next_diagram(diagram_dir)
prompt = text.split(MENTION_TOKEN, 1)[1]
write_placeholder_plantuml(diagram_path, prompt)
append_comment(discussion_path, diagram_path.relative_to(repo_root))
return 0
if __name__ == "__main__":
raise SystemExit(main())