import json import random from copy import deepcopy from src.apis import API_TYPES, CodeExecutor from src.llms import Role from src.pptgen import PPTCrew from src.presentation import GroupShape, ShapeElement, SlidePage, TextFrame from src.utils import get_slide_content, pexists, pjoin, tenacity class PPTCrew_wo_Structure(PPTCrew): def _hire_staffs(self, record_cost: bool, **kwargs) -> dict[str, Role]: new_planner = "planner_wo_structure" self.roles.append(new_planner) super()._hire_staffs(record_cost, **kwargs) self.staffs["planner"] = self.staffs.pop(new_planner) @tenacity def _generate_outline(self, num_slides: int): outline_file = pjoin(self.config.RUN_DIR, "presentation_outline.json") if pexists(outline_file): outline = json.load(open(outline_file, "r")) else: outline = self.staffs["planner"]( num_slides=num_slides, layouts="\n".join( set(self.slide_induction.keys()).difference(self.functional_keys) ), json_content=self.doc_json, image_information=self.image_information, ) outline = self._valid_outline(outline) json.dump( outline, open(outline_file, "w"), ensure_ascii=False, indent=4, ) return outline class PPTCrew_wo_LayoutInduction(PPTCrew): def _generate_slide(self, slide_data, code_executor: CodeExecutor) -> SlidePage: slide_idx, (slide_title, slide) = slide_data images_info = "No Images" if any( [ i in slide["layout"] for i in ["picture", "chart", "table", "diagram", "freeform"] ] ): images_info = self.image_information slide_content = f"Slide-{slide_idx+1} " + get_slide_content( self.doc_json, slide_title, slide ) try: return self.synergize( deepcopy(self.slide_induction[random.choice(self.layout_names)]), slide_content, code_executor, images_info, ) except Exception as e: print(f"generate slide {slide_idx} failed: {e}") return None class PPTCrew_wo_Decoupling(PPTCrew): roles: list[str] = ["agent"] def synergize( self, template: dict, slide_content: str, code_executor: CodeExecutor, image_info: str, ) -> SlidePage: schema = template["content_schema"] edit_actions = self.staffs["agent"]( schema=schema, api_docs=code_executor.get_apis_docs(API_TYPES.Agent.value), edit_target=self.presentation.slides[template["template_id"] - 1].to_html(), outline=self.simple_outline, metadata=self.metadata, text=slide_content, images_info=image_info, ) for error_idx in range(self.retry_times): edited_slide: SlidePage = deepcopy( self.presentation.slides[template["template_id"] - 1] ) feedback = code_executor.execute_actions(edit_actions, edited_slide) if feedback is None: return edited_slide if error_idx == self.retry_times - 1: raise Exception( f"Failed to generate slide, tried too many times at editing\ntraceback: {feedback[1]}" ) edit_actions = self.staffs["agent"].retry(*feedback, error_idx + 1) self.empty_prs.build_slide(edited_slide) return edited_slide class PPTCrew_wo_SchemaInduction(PPTCrew): def _hire_staffs(self, record_cost: bool, **kwargs) -> dict[str, Role]: new_editor = "editor_wo_schema" self.roles.append(new_editor) super()._hire_staffs(record_cost, **kwargs) self.staffs["editor"] = self.staffs.pop(new_editor) def synergize( self, template: dict, slide_content: str, code_executor: CodeExecutor, images_info: str, ) -> SlidePage: content_schema = template["content_schema"] new_schema = {} for k, v in enumerate(content_schema.values()): v.pop("description") new_schema[str(k)] = v old_data = self._prepare_schema(new_schema) editor_output = self.staffs["editor"]( schema=new_schema, outline=self.simple_outline, metadata=self.metadata, text=slide_content, images_info=images_info, ) command_list = self._generate_commands(editor_output, new_schema, old_data) edit_actions = self.staffs["coder"]( api_docs=code_executor.get_apis_docs(API_TYPES.Agent.value), edit_target=self.presentation.slides[template["template_id"] - 1].to_html(), command_list="\n".join([str(i) for i in command_list]), ) for error_idx in range(self.retry_times): edited_slide: SlidePage = deepcopy( self.presentation.slides[template["template_id"] - 1] ) feedback = code_executor.execute_actions(edit_actions, edited_slide) if feedback is None: break if error_idx == self.retry_times - 1: raise Exception( f"Failed to generate slide, tried too many times at editing\ntraceback: {feedback[1]}" ) edit_actions = self.staffs["coder"].retry(*feedback, error_idx + 1) self.empty_prs.build_slide(edited_slide) return edited_slide def monkeypatch_render(): for cls in [ ShapeElement, GroupShape, SlidePage, TextFrame, ]: cls.to_html = lambda s: s.to_pptc() class PPTCrew_wo_HTML(PPTCrew): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) monkeypatch_render() def _hire_staffs(self, record_cost: bool, **kwargs) -> dict[str, Role]: new_coder = "coder_wo_html" self.roles.append(new_coder) super()._hire_staffs(record_cost, **kwargs) self.staffs["coder"] = self.staffs.pop(new_coder)