from __future__ import annotations import time from ..state import AgentState from ..models import LLMClient, FORMATTER_PROMPT_TEMPLATE from ..tools import get_logger, log_state_summary logger = get_logger() def formatter_node(state: AgentState) -> AgentState: start = time.time() topic = state.get("topic", "") mode = state.get("mode", "blog") revised = state.get("revised_draft") or state.get("draft") or "" if not revised.strip(): raise ValueError("No draft or revised draft available for formatter_node.") client = LLMClient() system_prompt = "You are an expert formatter who adapts content to the requested mode." user_prompt = FORMATTER_PROMPT_TEMPLATE.format( mode=mode, topic=topic, draft=revised ) logger.info("Formatter: producing final output in mode '%s'...", mode) final_output = client.generate(system_prompt=system_prompt, user_prompt=user_prompt) # Naive outline extraction: use headings lines outline = [] for line in final_output.splitlines(): stripped = line.strip() if stripped.startswith("#") or stripped.endswith(":"): outline.append(stripped.lstrip("#").strip()) meta = state.get("meta", {}) or {} meta["formatter_time_sec"] = round(time.time() - start, 3) new_state: AgentState = { **state, "final_output": final_output, "outline": outline or state.get("outline", []) or [], "meta": meta, } log_state_summary(new_state, prefix="Formatter") return new_state