SlideAI / slide_generator.py
PHOENIXREBORNAGAIN's picture
Upload slide_generator.py with huggingface_hub
5de2d90 verified
Raw
History Blame Contribute Delete
3.64 kB
import os
import json
import re
from huggingface_hub import InferenceClient
MODEL_NAME = "Qwen/Qwen2.5-7B-Instruct"
_api_key = os.environ.get("GROQ_API_KEY") or os.environ.get("HF_TOKEN")
client = InferenceClient(api_key=_api_key)
SYSTEM_PROMPT = (
"You are an expert presentation designer and subject-matter expert. "
"Return only valid JSON — no markdown fences, no extra text."
)
def _extract_json(text: str) -> dict:
try:
return json.loads(text.strip())
except json.JSONDecodeError:
pass
cleaned = re.sub(r"^```[a-z]*\n?", "", text.strip(), flags=re.MULTILINE)
cleaned = re.sub(r"\n?```$", "", cleaned.strip(), flags=re.MULTILINE)
try:
return json.loads(cleaned.strip())
except json.JSONDecodeError:
pass
match = re.search(r"\{.*\}", text, re.DOTALL)
if match:
return json.loads(match.group())
raise ValueError("Could not extract JSON from model response.")
def generate_presentation(topic: str, style: str, num_slides: int,
audience: str, key_points: str) -> dict:
key_points_section = (
f"\nKey points to include: {key_points}" if key_points.strip() else ""
)
user_prompt = f"""Create a detailed, informative {style.lower()} presentation about: "{topic}"
Target audience: {audience}
Number of slides: {num_slides} (including title slide){key_points_section}
Return a JSON object with this EXACT structure:
{{
"title": "Main presentation title",
"subtitle": "A compelling subtitle",
"slides": [
{{
"slide_number": 1,
"type": "title",
"title": "Presentation Title",
"subtitle": "Subtitle or tagline",
"image_keyword": "{topic} overview",
"speaker_notes": "Detailed opening notes for the presenter, 3-4 sentences."
}},
{{
"slide_number": 2,
"type": "content",
"title": "Slide Title",
"bullets": [
"First key point with sufficient detail and explanation to be meaningful",
"Second point that elaborates on a core concept with specific data or insight",
"Third point covering an important aspect with supporting context",
"Fourth point with actionable information or a compelling statistic",
"Fifth point summarizing implications or real-world applications"
],
"image_keyword": "{topic} [specific aspect of this slide — 2-4 words total]",
"speaker_notes": "Detailed speaker notes for this slide, 3-4 sentences explaining what to say and emphasize."
}}
]
}}
Rules:
- First slide must be type "title" with subtitle field
- All other slides type "content" with bullets array
- Each slide must have EXACTLY 5 bullet points
- Each bullet point: 15-25 words, informative and specific — include facts, data, or clear explanations. No vague one-liners.
- image_keyword: MUST include the topic "{topic}" plus 1-2 extra words describing the slide's specific angle. Examples for topic "Electric Vehicles": "electric vehicles charging station", "electric vehicles battery technology", "electric vehicles environmental impact". Always make keywords directly about the main topic.
- speaker_notes: 3-4 detailed sentences per slide
- Total slides: exactly {num_slides}
- Return only the JSON object, nothing else
"""
response = client.chat.completions.create(
model=MODEL_NAME,
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_prompt},
],
temperature=0.7,
max_tokens=6000,
)
raw = response.choices[0].message.content
return _extract_json(raw)