Spaces:
Sleeping
Sleeping
| import os | |
| from pathlib import Path | |
| """ | |
| Generate clean, standalone SVG illustrations for each slide concept using a GPT text model | |
| by prompting it to produce SVG markup. This avoids image model restrictions and uses your | |
| existing OpenAI API token. Optionally converts to PNG if cairosvg is installed. | |
| Outputs: | |
| - docs/slide_ai_svgs/slide-1.svg ... slide-5.svg | |
| - docs/slide_ai_svgs/slide-1.png ... (if cairosvg available) | |
| """ | |
| SLIDE_CONCEPTS = [ | |
| ( | |
| 1, | |
| "Consistent Output Control", | |
| "Minimalist flat vector diagram: speech bubble -> robot head -> JSON braces with a checkmark badge. No text. Blue/teal palette.", | |
| ), | |
| ( | |
| 2, | |
| "Input Control via Missing Fields", | |
| "Product-style vector: a form card with several fields; some marked as required with subtle red dots; an assistant bubble pointing to missing fields. No text labels. Blue/orange accents.", | |
| ), | |
| ( | |
| 3, | |
| "Dynamic Input Schemas (KB & Internet)", | |
| "Agent icon with two branching arrows to a database cylinder (KB) and a globe (internet), recombining to a merged node. No text. Minimal lines, gradient accents.", | |
| ), | |
| ( | |
| 4, | |
| "Multistep Execution & Delegation", | |
| "Central orchestrator node with sequential delegation to two sub-agents (1 -> 2). Use small numbered badges or dots; no words. Monochrome with a single accent color.", | |
| ), | |
| ( | |
| 5, | |
| "API Calls (NCBI/Web Search)", | |
| "Magnifying glass over a DNA helix next to a web globe; arrows indicating request/response. No text. Cool scientific tones.", | |
| ), | |
| ] | |
| SVG_SYSTEM_PROMPT = ( | |
| "You are an expert vector illustrator. Output ONLY valid, standalone SVG markup. " | |
| "Do not include backticks or explanations. The SVG should: " | |
| "- Be 1024x1024 viewBox with responsive vector shapes. " | |
| "- Use clean, flat, minimal iconography. " | |
| "- Avoid text labels; rely on shapes and badges. " | |
| "- Ensure high contrast and accessibility-friendly colors. " | |
| ) | |
| SVG_USER_TEMPLATE = ( | |
| "Create a 1024x1024 minimalist vector illustration for the concept: '{title}'. " | |
| "Style hints: {hints} " | |
| "Use a light background, subtle drop-shadows via filters, and consistent stroke widths (2px). " | |
| "Return only a single <svg> root with shapes (paths, circles, rects, lines)." | |
| ) | |
| def maybe_png(svg_path: Path): | |
| try: | |
| import cairosvg # type: ignore | |
| png_path = svg_path.with_suffix('.png') | |
| cairosvg.svg2png(url=str(svg_path), write_to=str(png_path), output_width=1024, output_height=1024) | |
| return png_path | |
| except Exception: | |
| return None | |
| def call_gpt_for_svg(system_prompt: str, user_prompt: str) -> str: | |
| from openai import OpenAI # type: ignore | |
| import os | |
| if not os.getenv("OPENAI_API_KEY"): | |
| raise RuntimeError("OPENAI_API_KEY not set") | |
| client = OpenAI() | |
| # Use a capable text model for structured generation | |
| resp = client.chat.completions.create( | |
| model=os.getenv("SVG_MODEL", "gpt-4o-mini"), | |
| messages=[ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": user_prompt}, | |
| ], | |
| temperature=0.7, | |
| max_tokens=2000, | |
| ) | |
| content = resp.choices[0].message.content or "" | |
| # Strip possible code fences just in case | |
| if content.startswith("```"): | |
| content = content.strip().strip("`") | |
| # try to extract <svg>...</svg> | |
| start = content.find('<svg') | |
| end = content.rfind('</svg>') | |
| if start != -1 and end != -1: | |
| content = content[start:end+6] | |
| return content | |
| def main(): | |
| project_root = Path(__file__).resolve().parents[1] | |
| out_dir = project_root / "docs" / "slide_ai_svgs" | |
| out_dir.mkdir(parents=True, exist_ok=True) | |
| for idx, title, hints in SLIDE_CONCEPTS: | |
| print(f"Generating SVG for slide {idx}: {title}") | |
| user_prompt = SVG_USER_TEMPLATE.format(title=title, hints=hints) | |
| svg = call_gpt_for_svg(SVG_SYSTEM_PROMPT, user_prompt) | |
| if '<svg' not in svg: | |
| print(f" Warning: No <svg> root returned for slide {idx}; skipping save.") | |
| continue | |
| svg_path = out_dir / f"slide-{idx}.svg" | |
| svg_path.write_text(svg, encoding="utf-8") | |
| print(f" Saved {svg_path}") | |
| png_path = maybe_png(svg_path) | |
| if png_path: | |
| print(f" Saved {png_path}") | |
| print(f"Done. SVGs written to {out_dir}") | |
| if __name__ == "__main__": | |
| main() | |