| | """ |
| | Slides/Presentation Generation Tool - Create PowerPoint presentations |
| | """ |
| |
|
| | import logging |
| | import os |
| | import tempfile |
| | import base64 |
| | from typing import Any, Dict |
| | from datetime import datetime |
| | from pptx import Presentation |
| | from pptx.util import Inches, Pt |
| | from pptx.enum.text import PP_ALIGN |
| | from pptx.dml.color import RGBColor |
| |
|
| | logger = logging.getLogger(__name__) |
| |
|
| | SLIDES_TOOL_SPEC = { |
| | "name": "create_slides", |
| | "description": ( |
| | "Create a PowerPoint presentation with multiple slides. " |
| | "Use this to generate professional presentations with titles, content, and formatting. " |
| | "Supports title slides, content slides with bullet points, and section dividers." |
| | ), |
| | "parameters": { |
| | "type": "object", |
| | "properties": { |
| | "title": { |
| | "type": "string", |
| | "description": "The main title of the presentation", |
| | }, |
| | "slides": { |
| | "type": "array", |
| | "description": "Array of slide objects, each with 'type' (title, content, section), 'title', and 'content' (array of bullet points)", |
| | "items": { |
| | "type": "object", |
| | "properties": { |
| | "type": {"type": "string", "enum": ["title", "content", "section"]}, |
| | "title": {"type": "string"}, |
| | "content": {"type": "array", "items": {"type": "string"}}, |
| | }, |
| | "required": ["type", "title"], |
| | }, |
| | }, |
| | "filename": { |
| | "type": "string", |
| | "description": "Output filename for the presentation (e.g., 'presentation.pptx')", |
| | }, |
| | }, |
| | "required": ["title", "slides", "filename"], |
| | }, |
| | } |
| |
|
| |
|
| | async def create_slides_handler(arguments: Dict[str, Any]) -> tuple[str, bool]: |
| | """Handler for creating PowerPoint presentations.""" |
| | try: |
| | title = arguments.get("title", "Presentation") |
| | slides_data = arguments.get("slides", []) |
| | filename = arguments.get("filename", "presentation.pptx") |
| | |
| | if not slides_data: |
| | return "Error: No slides provided", False |
| | |
| | |
| | if not filename.endswith(".pptx"): |
| | filename += ".pptx" |
| | |
| | |
| | prs = Presentation() |
| | prs.slide_width = Inches(13.333) |
| | prs.slide_height = Inches(7.5) |
| | |
| | |
| | title_color = RGBColor(31, 78, 121) |
| | text_color = RGBColor(51, 51, 51) |
| | |
| | for slide_data in slides_data: |
| | slide_type = slide_data.get("type", "content") |
| | slide_title = slide_data.get("title", "") |
| | slide_content = slide_data.get("content", []) |
| | |
| | if slide_type == "title": |
| | |
| | slide_layout = prs.slide_layouts[6] |
| | slide = prs.slides.add_slide(slide_layout) |
| | |
| | |
| | title_box = slide.shapes.add_textbox(Inches(0.5), Inches(2.5), Inches(12.333), Inches(1.5)) |
| | title_frame = title_box.text_frame |
| | title_frame.text = slide_title |
| | title_para = title_frame.paragraphs[0] |
| | title_para.font.size = Pt(44) |
| | title_para.font.bold = True |
| | title_para.font.color.rgb = title_color |
| | title_para.alignment = PP_ALIGN.CENTER |
| | |
| | |
| | subtitle_box = slide.shapes.add_textbox(Inches(0.5), Inches(4.2), Inches(12.333), Inches(1)) |
| | subtitle_frame = subtitle_box.text_frame |
| | subtitle_frame.text = title |
| | subtitle_para = subtitle_frame.paragraphs[0] |
| | subtitle_para.font.size = Pt(24) |
| | subtitle_para.font.color.rgb = text_color |
| | subtitle_para.alignment = PP_ALIGN.CENTER |
| | |
| | elif slide_type == "section": |
| | |
| | slide_layout = prs.slide_layouts[6] |
| | slide = prs.slides.add_slide(slide_layout) |
| | |
| | |
| | title_box = slide.shapes.add_textbox(Inches(0.5), Inches(3), Inches(12.333), Inches(1.5)) |
| | title_frame = title_box.text_frame |
| | title_frame.text = slide_title |
| | title_para = title_frame.paragraphs[0] |
| | title_para.font.size = Pt(40) |
| | title_para.font.bold = True |
| | title_para.font.color.rgb = title_color |
| | title_para.alignment = PP_ALIGN.CENTER |
| | |
| | else: |
| | slide_layout = prs.slide_layouts[6] |
| | slide = prs.slides.add_slide(slide_layout) |
| | |
| | |
| | title_box = slide.shapes.add_textbox(Inches(0.5), Inches(0.3), Inches(12.333), Inches(1)) |
| | title_frame = title_box.text_frame |
| | title_frame.text = slide_title |
| | title_para = title_frame.paragraphs[0] |
| | title_para.font.size = Pt(32) |
| | title_para.font.bold = True |
| | title_para.font.color.rgb = title_color |
| | |
| | |
| | if slide_content: |
| | content_box = slide.shapes.add_textbox(Inches(0.7), Inches(1.5), Inches(12), Inches(5.5)) |
| | content_frame = content_box.text_frame |
| | content_frame.word_wrap = True |
| | |
| | for i, bullet in enumerate(slide_content): |
| | if i == 0: |
| | p = content_frame.paragraphs[0] |
| | else: |
| | p = content_frame.add_paragraph() |
| | p.text = f"β’ {bullet}" |
| | p.font.size = Pt(18) |
| | p.font.color.rgb = text_color |
| | p.space_after = Pt(12) |
| | |
| | |
| | output_dir = os.path.join(tempfile.gettempdir(), "kimi_agent_outputs") |
| | os.makedirs(output_dir, exist_ok=True) |
| | output_path = os.path.join(output_dir, filename) |
| | prs.save(output_path) |
| | |
| | |
| | prs.save(filename) |
| | |
| | file_size = os.path.getsize(output_path) |
| |
|
| | |
| | with open(output_path, "rb") as f: |
| | file_content = f.read() |
| | file_content_b64 = base64.b64encode(file_content).decode() |
| |
|
| | |
| | file_data = { |
| | "id": f"file_{datetime.now().strftime('%Y%m%d%H%M%S')}_{filename}", |
| | "name": filename, |
| | "type": "document", |
| | "content": file_content_b64, |
| | "language": None, |
| | "originalContent": None, |
| | "modifiedContent": file_content_b64, |
| | "size": file_size, |
| | "created_at": datetime.now().isoformat(), |
| | } |
| |
|
| | return ( |
| | f"β
Presentation created successfully!\n" |
| | f"π Filename: {filename}\n" |
| | f"π Total slides: {len(slides_data)}\n" |
| | f"πΎ File size: {file_size / 1024:.2f} KB\n" |
| | f"π Saved to: {output_path}", |
| | True, |
| | file_data |
| | ) |
| | |
| | except Exception as e: |
| | logger.error(f"Slides creation error: {e}") |
| | return f"β Error creating presentation: {str(e)}", False |
| |
|