File size: 6,323 Bytes
fcaa164 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
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)
|