-
Notifications
You must be signed in to change notification settings - Fork 6.7k
add PPTMaker #1830
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
Open
Rubbisheep
wants to merge
5
commits into
FoundationAgents:main
Choose a base branch
from
Rubbisheep:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
add PPTMaker #1830
Changes from 3 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
SYSTEM_PROMPT = """ | ||
You are a LaTeX Beamer Presentation Generator. Your task is to generate a complete, informative, and ready-to-compile Beamer slide deck in LaTeX, based on the task description and any past drafts or feedback. | ||
|
||
## Goals: | ||
- Each slide must be **self-contained**, meaning the audience should understand the slide without external explanations. | ||
- The presentation must **teach** or **explain** the topic in sufficient detail using structured LaTeX slides. | ||
- Each slide must contribute meaningfully to the overall structure and flow of the presentation. | ||
|
||
|
||
|
||
## Requirements: | ||
|
||
1. Preamble & Setup | ||
- Start with `\\documentclass{beamer}`. | ||
- Use packages such as `amsmath`, `amsfonts`, and `graphicx`. | ||
- Use the `Madrid` theme unless otherwise specified. | ||
- Include full metadata: `\\title{}`, `\\author{}`, and `\\date{\\today}`. | ||
|
||
2. Slide Design | ||
- MUST mark each slide with a comment indicating its number, `% Slide 1`, `% Slide 2`. | ||
- - Slides must follow a **logical order** that ensures smooth flow and coherence. | ||
- AIM for a **minimum of 300 words per slide* Contain **enough detail** (text, bullets, equations, definitions, or examples) | ||
|
||
3. Depth of Content | ||
- For important concept, include motivation, problem, intuitive explanation, mathematical formulation or equation (if applicable) | ||
- practical example or application can also be included | ||
|
||
4. Completeness & Validity | ||
- Reflect all provided feedback and correct deficiencies from past versions. | ||
- MUST No placeholders or incomplete content. | ||
- Your output will be used directly. Therefore, it must be a ready-to-use result. | ||
- Include `\\end{document}`. | ||
- Ensure valid LaTeX syntax. | ||
|
||
5. Style & Clarity | ||
- Maintain consistent formatting and indentation. | ||
- Use bullet points or short paragraphs for clarity. | ||
- Keep math readable and contextualized with supporting text. | ||
|
||
**Only output the final LaTeX source code. Do not include explanations, notes, or comments.** | ||
""" | ||
|
||
USER_CONTENT = """ | ||
## Task | ||
{request} | ||
|
||
## Past Drafts & Feedback | ||
{history} | ||
""" | ||
|
||
TEXT_VALIDATION_PROMPT = """ | ||
You are a task result evaluator responsible for determining whether a task result meets the task requirements, if not, you need to improve it. | ||
|
||
# Objective and Steps | ||
1. **Completeness and Quality Check:** | ||
- Verify that the result includes all required elements of the task. | ||
- Evaluate whether the output meets overall quality criteria (accuracy, clarity, formatting, and completeness). | ||
|
||
2. **Change Detection:** | ||
- If this is a subsequent result, compare it with previous iterations. | ||
- If the differences are minimal or the result has not significantly improved, consider it "good enough" for finalization. | ||
|
||
3. **Feedback and Escalation:** | ||
- If the result meets the criteria or the improvements are negligible compared to previous iterations, return **"No further feedback"**. | ||
- Otherwise, provide **direct and precise feedback** and **output the improved result in the required format** for finalization. | ||
|
||
4. **Ensure Completeness:** | ||
- Your output must meet all requirements of the task. | ||
- Include all necessary details so that the output is self-contained and can be directly used as input for downstream tasks. | ||
|
||
5. **Do NOT:** | ||
- Leave any section with placeholders (e.g., "TODO", "Add content here"). | ||
- Include any commentary or reminders to the writer or user (e.g., "We can add more later"). | ||
- Output partial slides or omit essential details assuming future input. | ||
|
||
- **If the result meets the standard:** | ||
- Return **"No further feedback."**. | ||
|
||
- **If the result does not meet the standard:** | ||
- add detailed jusification for the change start with "here are some feedbacks" and directly write an improved new result start with "here are the changes". | ||
|
||
# Note that: Any output containing incomplete sections, placeholders is not allowed. | ||
""" | ||
|
||
USER_VALIDATION_CONTENT = """ | ||
## Current Task Requirement: | ||
{request} | ||
|
||
--- | ||
|
||
## Current Task Latest Result: | ||
{history} | ||
""" | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
""" | ||
@File : PPTmaker.py | ||
@Time : 2025/05/14 18:16:47 | ||
@Author : Deng Mingyi | ||
@Desc : A role to create LaTeX-based presentations. | ||
""" | ||
|
||
from typing import List, Dict, Any | ||
from metagpt.actions import Action | ||
from metagpt.roles.di.role_zero import RoleZero | ||
from metagpt.schema import Message | ||
from metagpt.logs import logger | ||
from metagpt.prompts.PPTmaker import SYSTEM_PROMPT, USER_CONTENT, TEXT_VALIDATION_PROMPT, USER_VALIDATION_CONTENT | ||
|
||
|
||
class LatexGeneratorAction(Action): | ||
""" | ||
Action to generate LaTeX content for presentations. | ||
""" | ||
name: str = "latexgenerator" | ||
description: str = """ | ||
This agent generates complete, high-quality LaTeX documents with a focus on Beamer presentations. It accepts topic-specific input and produces fully self-contained LaTeX source code, including all required packages, structures, and rich content elements such as equations, figures, and formatted text. The agent ensures completeness by avoiding any placeholders or incomplete sections. | ||
|
||
In addition to generation, the agent supports iterative refinement: it evaluates and improves the generated LaTeX code based on validation feedback to ensure correctness, formatting quality, and logical structure. The final output is ready for immediate compilation and professional presentation use. | ||
""" | ||
|
||
async def generate(self, request: str, history: str) -> str: | ||
""" | ||
Generate LaTeX content. | ||
Args: | ||
request: Initial user request | ||
history: String representation of historical messages | ||
Returns: | ||
Generated LaTeX code as string | ||
""" | ||
logger.info(f"Actual max_tokens used: {self.llm.config.max_token}") | ||
logger.info(f"Executing {self.name} Action: Generating LaTeX content for request \n'{request[:]}...'") | ||
|
||
system_content = SYSTEM_PROMPT | ||
user_content = USER_CONTENT.format(request=request, history=history) | ||
|
||
generated_latex = await self._aask(user_content, [system_content]) | ||
|
||
logger.debug(f"Generated LaTeX content: {generated_latex[:]}...") | ||
return generated_latex | ||
|
||
async def run(self, request: str, history: str) -> str: | ||
"""Execute the current action""" | ||
return await self.generate(request, history) | ||
|
||
|
||
class ValidatorAction(Action): | ||
""" | ||
Action to validate LaTeX content. | ||
""" | ||
name: str = "validator" | ||
description: str = """ | ||
This tool evaluates the quality and completeness of a subtask result against a set of predefined criteria. | ||
It checks whether the result fully satisfies task requirements, maintains high quality in terms of clarity, accuracy, and formatting, | ||
and determines whether improvements have been made in comparison to prior versions. | ||
If the result is satisfactory or improvements are minimal, it returns "The step result has already reached the requirement.". | ||
Otherwise, it provides detailed feedback and a revised version of the result that meets all requirements and is ready for downstream use. | ||
""" | ||
|
||
async def validate(self, request: str, history: str) -> str: | ||
""" | ||
Validate the generated content. | ||
Args: | ||
request: Initial user request | ||
history: String representation of historical messages | ||
Returns: | ||
Validation feedback string | ||
""" | ||
logger.info(f"Executing {self.name} Action: Validating current content") | ||
|
||
system_content = TEXT_VALIDATION_PROMPT | ||
user_content = USER_VALIDATION_CONTENT.format(request=request, history=history) | ||
|
||
feedback = await self._aask(user_content, [system_content]) | ||
logger.debug(f"Validation feedback: {feedback[:]}...") | ||
|
||
return feedback | ||
|
||
async def run(self, request: str, history: str) -> str: | ||
"""Execute the current action""" | ||
return await self.validate(request, history) | ||
|
||
|
||
class PPTMaker(RoleZero): | ||
""" | ||
Role responsible for creating LaTeX format presentations. Calls tools in a fixed sequence | ||
and may terminate early based on validator feedback. | ||
""" | ||
name: str = "PPTMaker" | ||
profile: str = "LaTeX Presentation Generator" | ||
goal: str = "Generate high-quality LaTeX presentations in Beamer format" | ||
constraints: str = "Call tools in predefined order, may terminate early based on validation feedback" | ||
|
||
max_steps: int = 7 | ||
curr_step: int = 0 | ||
|
||
accumulated_latex: str = "" | ||
is_completed: bool = False | ||
optimized_result: str = None | ||
|
||
def __init__(self, **kwargs): | ||
super().__init__(**kwargs) | ||
self.set_actions([LatexGeneratorAction, ValidatorAction]) | ||
self._reset_state() | ||
|
||
def _reset_state(self): | ||
"""Reset internal state to prepare for a new task""" | ||
self.curr_step = 0 | ||
self.is_completed = False | ||
self.validator_feedback = "" | ||
logger.info(f"{self.name} state has been reset") | ||
|
||
@staticmethod | ||
def save_md(content: str, filename: str = "presentation.md"): | ||
""" | ||
Save the generated LaTeX content to a file in the workspace directory. | ||
""" | ||
import os | ||
|
||
workspace_dir = os.path.join(os.getcwd(), "workspace") | ||
|
||
os.makedirs(workspace_dir, exist_ok=True) | ||
|
||
save_path = os.path.join(workspace_dir, filename) | ||
|
||
try: | ||
Rubbisheep marked this conversation as resolved.
Show resolved
Hide resolved
|
||
with open(save_path, "w", encoding="utf-8") as f: | ||
f.write(content) | ||
|
||
logger.info(f"markdown file saved at {save_path}") | ||
return save_path | ||
except Exception as e: | ||
logger.error(f"Failed to save markdown content: {e}") | ||
return None | ||
|
||
async def react(self) -> Message: | ||
""" | ||
Process current state, decide next action, execute and return a Message. | ||
""" | ||
tool_idx = self.curr_step % len(self.actions) | ||
tool_class = [LatexGeneratorAction, ValidatorAction][tool_idx] | ||
tool_name = ["latexgenerator", "validator"][tool_idx] | ||
|
||
logger.info(f"{self.name} selected tool: {tool_name}") | ||
|
||
result = None | ||
|
||
try: | ||
if tool_name == "latexgenerator": | ||
LatexGenerator = LatexGeneratorAction() | ||
result = await LatexGenerator.run( | ||
request=self.rc.history[0].content, | ||
history=self.rc.history | ||
) | ||
self.optimized_result = result | ||
if result: | ||
self.rc.memory.add(result) | ||
|
||
logger.info(f"LaTeX content generated, current total length: {len(self.rc.history)}") | ||
message_content = f"Step {self.curr_step+1}/{self.max_steps}: Used tool {tool_name} to generate content" | ||
|
||
elif tool_name == "validator": | ||
Validator = ValidatorAction() | ||
result = await Validator.run( | ||
request=self.rc.history[0].content, | ||
history=self.rc.history | ||
) | ||
message_content = f"Step {self.curr_step+1}/{self.max_steps}: Used tool {tool_name} to validate content" | ||
self.rc.memory.add(result) | ||
|
||
if "No further feedback" in result: | ||
logger.info(f"{self.name}: Validator indicates task is complete") | ||
self.is_completed = True | ||
self.curr_step += 1 | ||
return Message(content=self.optimized_result, role=self.profile, cause_by=tool_class) | ||
|
||
except Exception as e: | ||
logger.error(f"Error executing tool {tool_name}: {e}") | ||
|
||
self.curr_step += 1 | ||
return Message(content=self.optimized_result or message_content, role=self.profile, cause_by=tool_class) | ||
|
||
Rubbisheep marked this conversation as resolved.
Show resolved
Hide resolved
|
||
async def run(self, prompt: Message) -> Message: | ||
self.rc.memory.add(prompt) | ||
message = await self.react() | ||
while True: | ||
if self.curr_step >= self.max_steps or self.is_completed: | ||
logger.info(f"{self.name} task completed or reached maximum steps ({self.max_steps})") | ||
final_message = f"Generation task completed.\nGenerated LaTeX content:\n\n{message.content}" | ||
self.save_md(final_message, filename="presentation.md") | ||
return Message(content=final_message, role=self.profile) | ||
message = await self.react() |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.