PosterGen / src /agents /section_title_designer.py
Hadlay's picture
First commit
46a8a46
"""
Section title Designer
- Fixed style for current version
"""
import json
from pathlib import Path
from typing import Dict, Any, List
from src.state.poster_state import PosterState
from utils.src.logging_utils import log_agent_info, log_agent_success, log_agent_error
class SectionTitleDesigner:
def __init__(self):
self.name = "section_title_designer"
def __call__(self, state: PosterState) -> PosterState:
log_agent_info(self.name, "generating section title styling (code-based, Style 2 only)")
try:
story_board = state.get("story_board")
color_scheme = state.get("color_scheme")
if not story_board:
log_agent_error(self.name, "missing story_board")
raise ValueError("missing story_board from curator")
if not color_scheme:
log_agent_error(self.name, "missing color_scheme")
raise ValueError("missing color_scheme from color agent")
title_design = self._generate_colorblock_design(story_board, color_scheme)
state["section_title_design"] = title_design
state["current_agent"] = self.name
self._save_title_design(state)
log_agent_success(self.name, "generated section title styling")
log_agent_info(self.name, f"theme color: {color_scheme.get('theme', 'unknown')}")
except Exception as e:
log_agent_error(self.name, f"failed: {e}")
state["errors"].append(f"{self.name}: {e}")
return state
def _generate_colorblock_design(self, story_board: Dict, color_scheme: Dict) -> Dict:
"""Generate colorblock design"""
sections = story_board.get("spatial_content_plan", {}).get("sections", [])
# color mapping from color_scheme for rectangle_left template
colors = self._map_rectangle_colors(color_scheme)
# applications for all sections
applications = self._generate_rectangle_applications(sections, colors)
return {
"section_title_design": {
"selected_template": "rectangle_left",
"design_rationale": "Code-generated rectangle_left template for modern, design-forward appearance with color accent",
"color_palette": colors,
"spacing_specifications": {
"title_left_padding": "4_spaces",
"rectangle_to_content_gap": 0.15
},
"section_applications": applications
}
}
def _map_rectangle_colors(self, color_scheme: Dict) -> Dict:
"""Map color scheme to rectangle_left template colors"""
theme_color = color_scheme.get("theme", "#1E3A8A")
mono_light = color_scheme.get("mono_light", "#335f91")
mono_dark = color_scheme.get("mono_dark", "#002c5e")
return {
"theme_color": theme_color,
"mono_light": mono_light,
"mono_dark": mono_dark,
"title_text_color": "#000000", # black for readability on colored background
"accent_rectangle_color": theme_color,
"background_color": "#FFFFFF"
}
def _generate_rectangle_applications(self, sections: List[Dict], colors: Dict) -> List[Dict]:
applications = []
for section in sections:
application = {
"section_id": section["section_id"],
"section_title": section.get("section_title", ""),
"title_styling": {
"font_family": "Helvetica Neue",
"font_size": 48, # this will be overridden by styling_interfaces font_sizes
"font_weight": "bold",
"color": colors["title_text_color"],
"alignment": "left"
},
"accent_styling": {
"type": "rectangle",
"color": colors["accent_rectangle_color"],
"dimensions": {"width": "golden_ratio_based_on_height", "height": "title_height"},
"position": "same_row"
}
}
applications.append(application)
return applications
def _save_title_design(self, state: PosterState):
"""Save title design to json file"""
output_dir = Path(state["output_dir"]) / "content"
output_dir.mkdir(parents=True, exist_ok=True)
with open(output_dir / "section_title_design.json", "w", encoding='utf-8') as f:
json.dump(state.get("section_title_design", {}), f, indent=2)
def section_title_designer_node(state: PosterState) -> Dict[str, Any]:
result = SectionTitleDesigner()(state)
return {
**state,
"section_title_design": result["section_title_design"],
"current_agent": result["current_agent"],
"errors": result["errors"]
}