YouTubeScriptMaster / nodes /node5_api.py
fcyber-labs
first commit
0cf3992
Raw
History Blame Contribute Delete
4.51 kB
from core.state import AgenticState
import json
from loguru import logger
@logger.catch
async def node_5_beautiful_presentation_api(state: AgenticState) -> AgenticState:
"""
Node 5 Prepare nice presentation with API
"""
logger.info("🚀 Node 5: Beautiful Presentation started...")
llm = state.llm
if not llm:
state.errors.append("LLM not available in state")
logger.error("LLM not available in state")
return state
structured = getattr(state, "structured_script", {})
metadata = getattr(state, "video_metadata", {})
if not structured:
state.errors.append({"type": "missing_structure", "message": "No structured script"})
logger.error("No structured script")
return state
video_id = (
getattr(state, "video_id", None)
or video_metadata.get("video_id")
or "UNKNOWN"
)
title = (
getattr(state, "title", None)
or video_metadata.get("title")
or (sections[0].get("title") if sections else None)
or "YouTube Video Summary"
)
channel = (
getattr(state, "channel", None)
or video_metadata.get("channel")
or "Unknown Channel"
)
duration_human = (
getattr(state, "duration_human", None)
or video_metadata.get("duration_human")
or None
)
# Upload date
upload_date = (
getattr(state, "upload_date", None)
or video_metadata.get("upload_date")
or None
)
# Build summary prompt
content_sample = "\n".join(
sec.get("summary", "") for sec in structured.get("sections", [])
)[:3000]
prompt = f"""
You are a professional content summarizer.
Generate:
1. Executive summary (3-5 sentences)
2. TLDR (one powerful sentence)
Return JSON:
{{
"executive_summary": "...",
"tldr": "..."
}}
CONTENT:
{content_sample}
"""
try:
response = llm.invoke(prompt)
json_str = response.content if hasattr(response, "content") else str(response)
if "```json" in json_str:
json_str = json_str.split("```json")[1].split("```")[0].strip()
elif "```" in json_str:
json_str = json_str.split("```")[1].split("```")[0].strip()
summaries = json.loads(json_str)
exec_summary = summaries.get("executive_summary", "")
tldr = summaries.get("tldr", "")
except Exception as e:
state.errors.append({"type": "summary_failed", "message": str(e)})
exec_summary = "Summary unavailable."
tldr = "TLDR unavailable."
logger.error("Summary unavailable")
# Table of contents
toc = "## Table of Contents\n"
for i, sec in enumerate(structured.get("sections", []), 1):
toc += f"{i}. {sec.get('title','Section')}\n"
# Sections
sections_md = []
for i, sec in enumerate(structured.get("sections", []), 1):
title_sec = sec.get("title", f"Section {i}")
summary = sec.get("summary", "")
content = sec.get("content", "")
key_points = sec.get("key_points", [])
start_time = sec.get("start_time")
timestamp = f"⏱ {start_time}\n\n" if start_time else ""
section_md = f"""
### {i}. {title_sec}
{timestamp}
**Summary**
{summary}
**Explanation**
{content}
**Key Insights**
{chr(10).join(f"- {p}" for p in key_points[:5])}
"""
sections_md.append(section_md)
# Topics
topics_md = ""
if state.main_topics:
topics_md = "## Main Topics\n" + "\n".join(f"- {t}" for t in state.main_topics)
# Quotes
quotes_md = ""
if state.key_quotes:
quotes_md = "## Key Quotes\n\n"
for q in state.key_quotes:
quotes_md += f'> "{q}"\n\n'
# Entities
entities_md = ""
if state.mentioned_entities:
entities_md = "## Key Mentions\n\n"
for e in state.mentioned_entities:
entities_md += f"- {e}\n"
final_md = f"""
# {title}
*Channel: {channel}*
*Video ID: {video_id}*
*Duration: {duration_human}*
*Updated: {upload_date}*
---
## Executive Summary
{exec_summary}
## TL;DR
{tldr}
---
{topics_md}
---
{toc}
---
{chr(10).join(sections_md)}
---
{quotes_md}
---
{entities_md}
---
*Generated with Groq API + YouTubeScriptMaster 2026*
"""
state.final_formatted_markdown = final_md
state.presentation_complete = True
logger.info(" ✅ Node 5 complete | Markdown size: {len_final_md}", len_final_md=len(final_md))
return state