Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(integration): ai ppt generator agent #497

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions integrations/hackathons/AI-ppt-generator-agent/agents/agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@

import json
import requests
from io import BytesIO
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
from pptx.enum.shapes import MSO_SHAPE
import random
import tkinter as tk
from tkinter import simpledialog, messagebox
from open_ai_assistant import OpenAIProcessor
from uagents import Agent, Context

# Initialize OpenAI processor
openai_processor = OpenAIProcessor(api_key="your_api_key_opneai")

# Create the agent
ppt_agent = Agent(name="ppt_agent", seed="ppt_agent_seed")

@ppt_agent.on_event("startup")
async def startup_message(ctx: Context):
ctx.logger.info(f"Agent {ppt_agent.name} has started with address {ppt_agent.address}.")
input_data = get_user_input_via_gui()
ctx.logger.info("got the input data")
create_ppt_from_input(input_data["topic"], input_data["description"], input_data["slides_number"])
ctx.logger.info("Presentation saved as 'output_presentation.pptx'")

# @ppt_agent.on_interval(period=5.0)
# async def log_agent_activity(ctx: Context):
# ctx.logger.info("Agent is active and waiting for user inputs.")

def download_random_image():

random_width = random.randint(1920, 2560)
random_height = random.randint(1080, 1440)
image_url = f"https://picsum.photos/{random_width}/{random_height}"
response = requests.get(image_url)
return BytesIO(response.content)

def add_background_image(slide, image_stream):
slide.shapes.add_picture(image_stream, 0, 0, width=prs.slide_width, height=prs.slide_height)

def create_text_box_with_blended_background(slide, left, top, width, height, text, font_size):
background_shape = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE, left, top, width, height
)
fill = background_shape.fill
fill.solid()
fill.fore_color.rgb = RGBColor(255, 255, 255)
fill.fore_color.brightness = 0.5

background_shape.line.color.rgb = RGBColor(255, 255, 255)

text_box = slide.shapes.add_textbox(left, top, width, height)
text_frame = text_box.text_frame
text_frame.text = text
text_frame.word_wrap = True
for paragraph in text_frame.paragraphs:
paragraph.font.size = Pt(font_size)
paragraph.alignment = PP_ALIGN.LEFT

def create_ppt_from_input(topic, description, slides_number):
slides_content = openai_processor.get_assistant_response(topic, description, slides_number)
slides_content = json.loads(slides_content)

global prs
prs = Presentation()

for slide_num, slide_data in slides_content.items():
slide = prs.slides.add_slide(prs.slide_layouts[5])

image_stream = download_random_image()
add_background_image(slide, image_stream)

main_topic = slide_data.get("main_topic", "Main Topic").strip()
create_text_box_with_blended_background(slide, Inches(0.5), Inches(0.5), Inches(9), Inches(1.5), main_topic, font_size=28)

top = Inches(2)
left_margin = Inches(0.75)
right_margin = prs.slide_width - Inches(1.5)

subtopics = slide_data.get("subtopics", [])
for subtopic in subtopics:
subtopic_title = subtopic.get("title", "Subtopic").strip()
content = subtopic.get("content", "Content goes here.").strip()

create_text_box_with_blended_background(slide, left_margin, top, right_margin - left_margin, Inches(0.5), subtopic_title, font_size=24)
top += Inches(0.6)

create_text_box_with_blended_background(slide, left_margin + Inches(0.25), top, right_margin - left_margin - Inches(0.5), Inches(1), content, font_size=20)
top += Inches(1.2)

prs.save('output_presentation.pptx')


def get_user_input_via_gui():
root = tk.Tk()
root.withdraw() # Hide the root window

topic = simpledialog.askstring("Input", "Enter the topic of the presentation:", parent=root)
description = simpledialog.askstring("Input", "Enter a brief description of the presentation:", parent=root)
slides_number = simpledialog.askinteger("Input", "Enter the number of slides you want to create:", parent=root)

if not topic or not description or slides_number is None:
messagebox.showerror("Error", "All inputs must be provided!")
root.quit()
return None

return {"topic": topic, "description": description, "slides_number": slides_number}

if __name__ == "__main__":


ppt_agent.run()
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import time
from openai import OpenAI


assistant_id="asst_qG3nAPr1A1o4pIIXO5x8v27o"

class OpenAIProcessor:
def __init__(self, api_key):
self.client = OpenAI(api_key=api_key, default_headers={"OpenAI-Beta": "assistants=v2"})


def get_assistant_response(self, topic, description, slides_number):
thread = self.client.beta.threads.create()
thread_id = thread.id

self.client.beta.threads.messages.create(
thread_id=thread_id,
role="user",
content=f'topic: {topic}\ndescription: {description}\nslides_number: {slides_number}'
)

run = self.client.beta.threads.runs.create(
thread_id=thread_id,
assistant_id=assistant_id,
model='gpt-4o',
tools=[],
)

def check_status(run_id, thread_id):
run = self.client.beta.threads.runs.retrieve(
thread_id=thread_id,
run_id=run_id
)
return run.status

status = check_status(run.id, thread_id)
while status != "completed":
time.sleep(1)
status = check_status(run.id, thread_id)

messages = self.client.beta.threads.messages.list(
thread_id=thread_id
)

response_content = ""
for msg in messages.data:
response_content = msg.content[0].text.value
return response_content.strip()


Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
106 changes: 106 additions & 0 deletions integrations/hackathons/AI-ppt-generator-agent/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@



# PPT Generator Agent

Tired of lengthy boring ppts? taking too much to make one just for a single period ? no problem here is the solution

This project generates a PowerPoint presentation based on user input for the title, description, and the number of slides. The project uses a Python script with a GUI for user input and integrates an OpenAI assistant to generate the content for the slides.

# How it Works
1: follow the process and run the agent
2: Enter Topic , description and slide number
3: vallah!!! your ppt is generated by our agent

## Prerequisites

1. **Python 3.10**: Make sure you have Python installed on your machine.
2. **OpenAI API Key**: You'll need an API key from OpenAI to use the assistant for generating slide content.
3. **Assistant ID** : create assistant in open ai platform and use its id

## Installation

1. Clone this repository to your local machine:
```bash
git clone https://github.com/your-repo/ppt-generator-bot.git
cd ppt-generator-bot
```


2. Install the required Python packages:
```bash
pip install -r requirements.txt
```

## OpenAI Assistant Setup

Before running the script, you need to create an OpenAI assistant. Use the following prompt for your assistant:

![1723218039919](image/readme/1723218039919.png)

**Assistant Prompt:**

```
You are a PPT generator bot. You will receive a title, its description, and the number of slides to generate a PPT. Your job is to generate main topics, subtopics for each main topic, and content for each subtopic.

- The number of slides can be between 8 to 12.
- Each slide should include everything related to the topic and description.
- Each slide should have a minimum of 2 and a maximum of 3 subtopics.
- The content for each subtopic should be between 80 and 150 words.

Return a JSON file in the following format:

{
"slide1": {
"main_topic": " ",
"subtopics": [
{"title": " ", "content": " "},
{"title": " ", "content": "."},
]
},
...
}
```

## Usage

1. **Run the Script**:
To start the application, run the following command in your terminal:

```bash
python agent.py
```
2. **GUI Input**:

- A GUI window will appear, prompting you to enter the title, description, and the number of slides you want to generate.
- Fill in the details and click "OK".
3. **Output**:

- The script will generate a PowerPoint presentation based on the inputs and save it as `output_presentation.pptx` in the current directory.

![1723218190852](image/readme/1723218190852.png)

## Example

Here’s an example of how the generated JSON might look:

```json
{
"slide1": {
"main_topic": "Introduction to AI",
"subtopics": [
{"title": "What is AI?", "content": "Artificial Intelligence (AI) refers to the simulation of human intelligence in machines..."},
{"title": "History of AI", "content": "The concept of AI dates back to the mid-20th century, with early milestones including..."}
]
},
"slide2": {
"main_topic": "Applications of AI",
"subtopics": [
{"title": "Healthcare", "content": "AI is revolutionizing healthcare by enabling precision medicine..."},
{"title": "Finance", "content": "In finance, AI is used for algorithmic trading, fraud detection..."},
{"title": "Manufacturing", "content": "AI-driven automation is enhancing manufacturing processes..."}
]
}
// more slides...
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
uagents
python-pptx
requests
Loading