Spaces:
Running
Running
Fix problems with prior commits
Browse files- app.py +24 -12
- global_config.py +4 -4
- helpers/pptx_helper.py +176 -46
- helpers/text_helper.py +36 -3
- langchain_templates/chat_prompts/initial_template_v2_steps.txt +59 -0
- langchain_templates/chat_prompts/refinement_template_v2_steps.txt +70 -0
- requirements.txt +10 -2
app.py
CHANGED
@@ -277,20 +277,32 @@ def generate_slide_deck(json_str: str):
|
|
277 |
slides_template=pptx_template,
|
278 |
output_file_path=path
|
279 |
)
|
280 |
-
|
281 |
_display_download_button(path)
|
282 |
-
except ValueError
|
283 |
-
st.error(
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
291 |
)
|
292 |
-
|
293 |
-
logger.error('Additional error info: %s', str(ve))
|
294 |
except Exception as ex:
|
295 |
st.error(APP_TEXT['content_generation_error'])
|
296 |
logger.error('Caught a generic exception: %s', str(ex))
|
|
|
277 |
slides_template=pptx_template,
|
278 |
output_file_path=path
|
279 |
)
|
|
|
280 |
_display_download_button(path)
|
281 |
+
except ValueError:
|
282 |
+
# st.error(
|
283 |
+
# f"{APP_TEXT['json_parsing_error']}"
|
284 |
+
# f"\n\nAdditional error info: {ve}"
|
285 |
+
# f"\n\nHere are some sample instructions that you could try to possibly fix this error;"
|
286 |
+
# f" if these don't work, try rephrasing or refreshing:"
|
287 |
+
# f"\n\n"
|
288 |
+
# "- Regenerate content and fix the JSON error."
|
289 |
+
# "\n- Regenerate content and fix the JSON error. Quotes inside quotes should be escaped."
|
290 |
+
# )
|
291 |
+
# logger.error('%s', APP_TEXT['json_parsing_error'])
|
292 |
+
# logger.error('Additional error info: %s', str(ve))
|
293 |
+
st.info(
|
294 |
+
'Encountered error while parsing JSON...will fix it and retry'
|
295 |
+
)
|
296 |
+
logger.debug(
|
297 |
+
'Caught ValueError: trying again after repairing JSON...'
|
298 |
+
)
|
299 |
+
|
300 |
+
pptx_helper.generate_powerpoint_presentation(
|
301 |
+
text_helper.fix_malformed_json(json_str),
|
302 |
+
slides_template=pptx_template,
|
303 |
+
output_file_path=path
|
304 |
)
|
305 |
+
_display_download_button(path)
|
|
|
306 |
except Exception as ex:
|
307 |
st.error(APP_TEXT['content_generation_error'])
|
308 |
logger.error('Caught a generic exception: %s', str(ex))
|
global_config.py
CHANGED
@@ -24,12 +24,12 @@ class GlobalConfig:
|
|
24 |
APP_STRINGS_FILE = 'strings.json'
|
25 |
PRELOAD_DATA_FILE = 'examples/example_02.json'
|
26 |
SLIDES_TEMPLATE_FILE = 'langchain_templates/template_combined.txt'
|
27 |
-
JSON_TEMPLATE_FILE = 'langchain_templates/text_to_json_template_02.txt'
|
28 |
-
INITIAL_PROMPT_TEMPLATE = 'langchain_templates/chat_prompts/
|
29 |
-
REFINEMENT_PROMPT_TEMPLATE = 'langchain_templates/chat_prompts/
|
30 |
|
31 |
PPTX_TEMPLATE_FILES = {
|
32 |
-
'
|
33 |
'file': 'pptx_templates/Blank.pptx',
|
34 |
'caption': 'A good start'
|
35 |
},
|
|
|
24 |
APP_STRINGS_FILE = 'strings.json'
|
25 |
PRELOAD_DATA_FILE = 'examples/example_02.json'
|
26 |
SLIDES_TEMPLATE_FILE = 'langchain_templates/template_combined.txt'
|
27 |
+
# JSON_TEMPLATE_FILE = 'langchain_templates/text_to_json_template_02.txt'
|
28 |
+
INITIAL_PROMPT_TEMPLATE = 'langchain_templates/chat_prompts/initial_template_v2_steps.txt'
|
29 |
+
REFINEMENT_PROMPT_TEMPLATE = 'langchain_templates/chat_prompts/refinement_template_v2_steps.txt'
|
30 |
|
31 |
PPTX_TEMPLATE_FILES = {
|
32 |
+
'Basic': {
|
33 |
'file': 'pptx_templates/Blank.pptx',
|
34 |
'caption': 'A good start'
|
35 |
},
|
helpers/pptx_helper.py
CHANGED
@@ -7,10 +7,21 @@ from typing import List, Tuple
|
|
7 |
|
8 |
import json5
|
9 |
import pptx
|
|
|
10 |
|
11 |
from global_config import GlobalConfig
|
12 |
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
PATTERN = re.compile(r"^slide[ ]+\d+:", re.IGNORECASE)
|
15 |
SAMPLE_JSON_FOR_PPTX = '''
|
16 |
{
|
@@ -69,6 +80,10 @@ def generate_powerpoint_presentation(
|
|
69 |
)
|
70 |
presentation = pptx.Presentation(GlobalConfig.PPTX_TEMPLATE_FILES[slides_template]['file'])
|
71 |
|
|
|
|
|
|
|
|
|
72 |
# The title slide
|
73 |
title_slide_layout = presentation.slide_layouts[0]
|
74 |
slide = presentation.slides.add_slide(title_slide_layout)
|
@@ -91,24 +106,21 @@ def generate_powerpoint_presentation(
|
|
91 |
for a_slide in parsed_data['slides']:
|
92 |
bullet_slide_layout = presentation.slide_layouts[1]
|
93 |
slide = presentation.slides.add_slide(bullet_slide_layout)
|
94 |
-
shapes = slide.shapes
|
95 |
-
|
96 |
-
title_shape = shapes.title
|
97 |
-
body_shape = shapes.placeholders[1]
|
98 |
-
title_shape.text = remove_slide_number_from_heading(a_slide['heading'])
|
99 |
-
all_headers.append(title_shape.text)
|
100 |
-
text_frame = body_shape.text_frame
|
101 |
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
|
|
|
|
|
|
|
|
112 |
|
113 |
# The thank-you slide
|
114 |
last_slide_layout = presentation.slide_layouts[0]
|
@@ -142,28 +154,128 @@ def get_flat_list_of_contents(items: list, level: int) -> List[Tuple]:
|
|
142 |
return flat_list
|
143 |
|
144 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
if __name__ == '__main__':
|
146 |
-
|
147 |
-
# 'Description',
|
148 |
-
# 'Types',
|
149 |
-
# [
|
150 |
-
# 'Type A',
|
151 |
-
# 'Type B'
|
152 |
-
# ],
|
153 |
-
# 'Grand parent',
|
154 |
-
# [
|
155 |
-
# 'Parent',
|
156 |
-
# [
|
157 |
-
# 'Grand child'
|
158 |
-
# ]
|
159 |
-
# ]
|
160 |
-
# ]
|
161 |
-
|
162 |
-
# output = get_flat_list_of_contents(bullets, level=0)
|
163 |
-
# for x in output:
|
164 |
-
# print(x)
|
165 |
-
|
166 |
-
json_data = '''
|
167 |
{
|
168 |
"title": "Understanding AI",
|
169 |
"slides": [
|
@@ -174,7 +286,8 @@ if __name__ == '__main__':
|
|
174 |
[
|
175 |
"Importance of understanding AI"
|
176 |
]
|
177 |
-
]
|
|
|
178 |
},
|
179 |
{
|
180 |
"heading": "What is AI?",
|
@@ -188,7 +301,8 @@ if __name__ == '__main__':
|
|
188 |
]
|
189 |
],
|
190 |
"Differences between AI and machine learning"
|
191 |
-
]
|
|
|
192 |
},
|
193 |
{
|
194 |
"heading": "How AI Works",
|
@@ -203,7 +317,19 @@ if __name__ == '__main__':
|
|
203 |
]
|
204 |
],
|
205 |
"How AI processes data"
|
206 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
},
|
208 |
{
|
209 |
"heading": "Pros of AI",
|
@@ -212,7 +338,8 @@ if __name__ == '__main__':
|
|
212 |
"Improved accuracy and precision",
|
213 |
"Enhanced decision-making capabilities",
|
214 |
"Personalized experiences"
|
215 |
-
]
|
|
|
216 |
},
|
217 |
{
|
218 |
"heading": "Cons of AI",
|
@@ -221,14 +348,16 @@ if __name__ == '__main__':
|
|
221 |
"Bias and discrimination",
|
222 |
"Privacy and security concerns",
|
223 |
"Dependence on technology"
|
224 |
-
]
|
|
|
225 |
},
|
226 |
{
|
227 |
"heading": "Future Prospects of AI",
|
228 |
"bullet_points": [
|
229 |
"Advancements in fields such as healthcare and finance",
|
230 |
"Increased use"
|
231 |
-
]
|
|
|
232 |
}
|
233 |
]
|
234 |
}'''
|
@@ -237,9 +366,10 @@ if __name__ == '__main__':
|
|
237 |
path = pathlib.Path(temp.name)
|
238 |
|
239 |
generate_powerpoint_presentation(
|
240 |
-
json5.loads(
|
241 |
output_file_path=path,
|
242 |
-
slides_template='
|
243 |
)
|
|
|
244 |
|
245 |
temp.close()
|
|
|
7 |
|
8 |
import json5
|
9 |
import pptx
|
10 |
+
from pptx.enum.shapes import MSO_AUTO_SHAPE_TYPE
|
11 |
|
12 |
from global_config import GlobalConfig
|
13 |
|
14 |
|
15 |
+
# English Metric Unit (used by PowerPoint) to inches
|
16 |
+
EMU_TO_INCH_SCALING_FACTOR = 1.0 / 914400
|
17 |
+
INCHES_1_5 = pptx.util.Inches(1.5)
|
18 |
+
INCHES_1 = pptx.util.Inches(1)
|
19 |
+
INCHES_0_5 = pptx.util.Inches(0.5)
|
20 |
+
INCHES_0_4 = pptx.util.Inches(0.4)
|
21 |
+
INCHES_0_3 = pptx.util.Inches(0.3)
|
22 |
+
|
23 |
+
STEP_BY_STEP_PROCESS_MARKER = '>> '
|
24 |
+
|
25 |
PATTERN = re.compile(r"^slide[ ]+\d+:", re.IGNORECASE)
|
26 |
SAMPLE_JSON_FOR_PPTX = '''
|
27 |
{
|
|
|
80 |
)
|
81 |
presentation = pptx.Presentation(GlobalConfig.PPTX_TEMPLATE_FILES[slides_template]['file'])
|
82 |
|
83 |
+
slide_width_inch = EMU_TO_INCH_SCALING_FACTOR * presentation.slide_width
|
84 |
+
slide_height_inch = EMU_TO_INCH_SCALING_FACTOR * presentation.slide_height
|
85 |
+
logger.debug('Slide width: %f, height: %f', slide_width_inch, slide_height_inch)
|
86 |
+
|
87 |
# The title slide
|
88 |
title_slide_layout = presentation.slide_layouts[0]
|
89 |
slide = presentation.slides.add_slide(title_slide_layout)
|
|
|
106 |
for a_slide in parsed_data['slides']:
|
107 |
bullet_slide_layout = presentation.slide_layouts[1]
|
108 |
slide = presentation.slides.add_slide(bullet_slide_layout)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
|
110 |
+
if not _handle_step_by_step_process(
|
111 |
+
slide=slide,
|
112 |
+
slide_json=a_slide,
|
113 |
+
slide_width_inch=slide_width_inch,
|
114 |
+
slide_height_inch=slide_height_inch,
|
115 |
+
):
|
116 |
+
_handle_default_display(slide, a_slide)
|
117 |
+
|
118 |
+
_handle_key_message(
|
119 |
+
slide=slide,
|
120 |
+
slide_json=a_slide,
|
121 |
+
slide_width_inch=slide_width_inch,
|
122 |
+
slide_height_inch=slide_height_inch,
|
123 |
+
)
|
124 |
|
125 |
# The thank-you slide
|
126 |
last_slide_layout = presentation.slide_layouts[0]
|
|
|
154 |
return flat_list
|
155 |
|
156 |
|
157 |
+
def _handle_default_display(
|
158 |
+
slide: pptx.slide.Slide,
|
159 |
+
slide_json: dict,
|
160 |
+
):
|
161 |
+
"""
|
162 |
+
Display a list of text in a slide.
|
163 |
+
|
164 |
+
:param slide: The slide to be processed.
|
165 |
+
:param slide_json: The content of the slide as JSON data.
|
166 |
+
"""
|
167 |
+
|
168 |
+
shapes = slide.shapes
|
169 |
+
title_shape = shapes.title
|
170 |
+
body_shape = shapes.placeholders[1]
|
171 |
+
title_shape.text = remove_slide_number_from_heading(slide_json['heading'])
|
172 |
+
text_frame = body_shape.text_frame
|
173 |
+
|
174 |
+
# The bullet_points may contain a nested hierarchy of JSON arrays
|
175 |
+
# In some scenarios, it may contain objects (dictionaries) because the LLM generated so
|
176 |
+
# ^ The second scenario is not covered
|
177 |
+
|
178 |
+
flat_items_list = get_flat_list_of_contents(slide_json['bullet_points'], level=0)
|
179 |
+
|
180 |
+
for an_item in flat_items_list:
|
181 |
+
paragraph = text_frame.add_paragraph()
|
182 |
+
paragraph.text = an_item[0].removeprefix(STEP_BY_STEP_PROCESS_MARKER)
|
183 |
+
paragraph.level = an_item[1]
|
184 |
+
|
185 |
+
|
186 |
+
def _handle_step_by_step_process(
|
187 |
+
slide: pptx.slide.Slide,
|
188 |
+
slide_json: dict,
|
189 |
+
slide_width_inch: float,
|
190 |
+
slide_height_inch: float
|
191 |
+
) -> bool:
|
192 |
+
"""
|
193 |
+
Add shapes to display a step-by-step process in the slide, if available.
|
194 |
+
|
195 |
+
:param slide: The slide to be processed.
|
196 |
+
:param slide_json: The content of the slide as JSON data.
|
197 |
+
:param slide_width_inch: The width of the slide in inches.
|
198 |
+
:param slide_height_inch: The height of the slide in inches.
|
199 |
+
:return True is this slide has a step-by-step process depiction; False otherwise.
|
200 |
+
"""
|
201 |
+
|
202 |
+
if 'bullet_points' in slide_json and slide_json['bullet_points']:
|
203 |
+
steps = slide_json['bullet_points']
|
204 |
+
|
205 |
+
# Ensure that it is a single list of strings without any sub-list
|
206 |
+
for step in steps:
|
207 |
+
if not isinstance(step, str):
|
208 |
+
return False
|
209 |
+
|
210 |
+
if not step.startswith(STEP_BY_STEP_PROCESS_MARKER):
|
211 |
+
return False
|
212 |
+
|
213 |
+
shapes = slide.shapes
|
214 |
+
shapes.title.text = remove_slide_number_from_heading(slide_json['heading'])
|
215 |
+
n_steps = len(steps)
|
216 |
+
|
217 |
+
if 3 <= n_steps <= 4:
|
218 |
+
# Horizontal display
|
219 |
+
height = INCHES_1_5
|
220 |
+
width = pptx.util.Inches(slide_width_inch / n_steps - 0.01)
|
221 |
+
top = pptx.util.Inches(slide_height_inch / 2)
|
222 |
+
left = pptx.util.Inches((slide_width_inch - width.inches * n_steps) / 2 + 0.05)
|
223 |
+
|
224 |
+
for step in steps:
|
225 |
+
shape = shapes.add_shape(MSO_AUTO_SHAPE_TYPE.CHEVRON, left, top, width, height)
|
226 |
+
shape.text = step.removeprefix(STEP_BY_STEP_PROCESS_MARKER)
|
227 |
+
left += width - INCHES_0_4
|
228 |
+
elif n_steps > 4:
|
229 |
+
# Vertical display
|
230 |
+
height = pptx.util.Inches(0.65)
|
231 |
+
width = pptx.util.Inches(slide_width_inch * 2/ 3)
|
232 |
+
top = pptx.util.Inches(slide_height_inch / 4)
|
233 |
+
left = INCHES_1 # slide_width_inch - width.inches)
|
234 |
+
|
235 |
+
for step in steps:
|
236 |
+
shape = shapes.add_shape(MSO_AUTO_SHAPE_TYPE.PENTAGON, left, top, width, height)
|
237 |
+
shape.text = step.removeprefix(STEP_BY_STEP_PROCESS_MARKER)
|
238 |
+
top += height + INCHES_0_3
|
239 |
+
left += INCHES_0_5
|
240 |
+
else:
|
241 |
+
# Two steps -- probably not a process
|
242 |
+
return False
|
243 |
+
|
244 |
+
return True
|
245 |
+
|
246 |
+
|
247 |
+
def _handle_key_message(
|
248 |
+
slide: pptx.slide.Slide,
|
249 |
+
slide_json: dict,
|
250 |
+
slide_width_inch: float,
|
251 |
+
slide_height_inch: float
|
252 |
+
):
|
253 |
+
"""
|
254 |
+
Add a shape to display the key message in the slide, if available.
|
255 |
+
|
256 |
+
:param slide: The slide to be processed.
|
257 |
+
:param slide_json: The content of the slide as JSON data.
|
258 |
+
:param slide_width_inch: The width of the slide in inches.
|
259 |
+
:param slide_height_inch: The height of the slide in inches.
|
260 |
+
"""
|
261 |
+
|
262 |
+
if 'key_message' in slide_json and slide_json['key_message']:
|
263 |
+
height = pptx.util.Inches(1.6)
|
264 |
+
width = pptx.util.Inches(slide_width_inch / 2.3)
|
265 |
+
top = pptx.util.Inches(slide_height_inch - height.inches - 0.1)
|
266 |
+
left = pptx.util.Inches((slide_width_inch - width.inches) / 2)
|
267 |
+
shape = slide.shapes.add_shape(
|
268 |
+
MSO_AUTO_SHAPE_TYPE.ROUNDED_RECTANGLE,
|
269 |
+
left=left,
|
270 |
+
top=top,
|
271 |
+
width=width,
|
272 |
+
height=height
|
273 |
+
)
|
274 |
+
shape.text = slide_json['key_message']
|
275 |
+
|
276 |
+
|
277 |
if __name__ == '__main__':
|
278 |
+
_JSON_DATA = '''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
{
|
280 |
"title": "Understanding AI",
|
281 |
"slides": [
|
|
|
286 |
[
|
287 |
"Importance of understanding AI"
|
288 |
]
|
289 |
+
],
|
290 |
+
"key_message": ""
|
291 |
},
|
292 |
{
|
293 |
"heading": "What is AI?",
|
|
|
301 |
]
|
302 |
],
|
303 |
"Differences between AI and machine learning"
|
304 |
+
],
|
305 |
+
"key_message": ""
|
306 |
},
|
307 |
{
|
308 |
"heading": "How AI Works",
|
|
|
317 |
]
|
318 |
],
|
319 |
"How AI processes data"
|
320 |
+
],
|
321 |
+
"key_message": ""
|
322 |
+
},
|
323 |
+
{
|
324 |
+
"heading": "Building AI Models",
|
325 |
+
"bullet_points": [
|
326 |
+
">> Collect data",
|
327 |
+
">> Select model or architecture to use",
|
328 |
+
">> Set appropriate parameters",
|
329 |
+
">> Train model with data",
|
330 |
+
">> Run inference",
|
331 |
+
],
|
332 |
+
"key_message": ""
|
333 |
},
|
334 |
{
|
335 |
"heading": "Pros of AI",
|
|
|
338 |
"Improved accuracy and precision",
|
339 |
"Enhanced decision-making capabilities",
|
340 |
"Personalized experiences"
|
341 |
+
],
|
342 |
+
"key_message": "AI can be used for many different purposes"
|
343 |
},
|
344 |
{
|
345 |
"heading": "Cons of AI",
|
|
|
348 |
"Bias and discrimination",
|
349 |
"Privacy and security concerns",
|
350 |
"Dependence on technology"
|
351 |
+
],
|
352 |
+
"key_message": ""
|
353 |
},
|
354 |
{
|
355 |
"heading": "Future Prospects of AI",
|
356 |
"bullet_points": [
|
357 |
"Advancements in fields such as healthcare and finance",
|
358 |
"Increased use"
|
359 |
+
],
|
360 |
+
"key_message": ""
|
361 |
}
|
362 |
]
|
363 |
}'''
|
|
|
366 |
path = pathlib.Path(temp.name)
|
367 |
|
368 |
generate_powerpoint_presentation(
|
369 |
+
json5.loads(_JSON_DATA),
|
370 |
output_file_path=path,
|
371 |
+
slides_template='Basic'
|
372 |
)
|
373 |
+
print(f'File path: {path}')
|
374 |
|
375 |
temp.close()
|
helpers/text_helper.py
CHANGED
@@ -1,3 +1,6 @@
|
|
|
|
|
|
|
|
1 |
def is_valid_prompt(prompt: str) -> bool:
|
2 |
"""
|
3 |
Verify whether user input satisfies the concerned constraints.
|
@@ -46,11 +49,41 @@ def get_clean_json(json_str: str) -> str:
|
|
46 |
# a new line or a closing bracket }
|
47 |
prev_char = json_str[idx - 1]
|
48 |
|
49 |
-
if prev_char == '}':
|
50 |
-
response_cleaned = json_str[:idx]
|
51 |
-
elif prev_char == '\n' and json_str[idx - 2] == '}':
|
52 |
response_cleaned = json_str[:idx]
|
53 |
|
54 |
json_str = json_str[:idx]
|
55 |
|
56 |
return response_cleaned
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json_repair as jr
|
2 |
+
|
3 |
+
|
4 |
def is_valid_prompt(prompt: str) -> bool:
|
5 |
"""
|
6 |
Verify whether user input satisfies the concerned constraints.
|
|
|
49 |
# a new line or a closing bracket }
|
50 |
prev_char = json_str[idx - 1]
|
51 |
|
52 |
+
if (prev_char == '}') or (prev_char == '\n' and json_str[idx - 2] == '}'):
|
|
|
|
|
53 |
response_cleaned = json_str[:idx]
|
54 |
|
55 |
json_str = json_str[:idx]
|
56 |
|
57 |
return response_cleaned
|
58 |
+
|
59 |
+
|
60 |
+
def fix_malformed_json(json_str: str) -> str:
|
61 |
+
"""
|
62 |
+
Try and fix the syntax error(s) in a JSON string.
|
63 |
+
|
64 |
+
:param json_str: The input JSON string.
|
65 |
+
:return: The fixed JSOn string.
|
66 |
+
"""
|
67 |
+
|
68 |
+
return jr.repair_json(json_str, skip_json_loads=True)
|
69 |
+
|
70 |
+
|
71 |
+
if __name__ == '__main__':
|
72 |
+
json1 = '''{
|
73 |
+
"key": "value"
|
74 |
+
}
|
75 |
+
'''
|
76 |
+
json2 = '''["Reason": "Regular updates help protect against known vulnerabilities."]'''
|
77 |
+
json3 = '''["Reason" Regular updates help protect against known vulnerabilities."]'''
|
78 |
+
json4 = '''
|
79 |
+
{"bullet_points": [
|
80 |
+
">> Write without stopping or editing",
|
81 |
+
>> Set daily writing goals and stick to them,
|
82 |
+
">> Allow yourself to make mistakes"
|
83 |
+
],}
|
84 |
+
'''
|
85 |
+
|
86 |
+
print(fix_malformed_json(json1))
|
87 |
+
print(fix_malformed_json(json2))
|
88 |
+
print(fix_malformed_json(json3))
|
89 |
+
print(fix_malformed_json(json4))
|
langchain_templates/chat_prompts/initial_template_v2_steps.txt
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
You are a helpful, intelligent chatbot. Create the slides for a presentation on the given topic.
|
2 |
+
Include main headings for each slide, detailed bullet points for each slide.
|
3 |
+
Add relevant content to each slide.
|
4 |
+
The content of each slide should be verbose, descriptive, and very detailed.
|
5 |
+
If relevant, add one or two examples to illustrate the concept.
|
6 |
+
Unless explicitly specified with the topic, create about 10 slides.
|
7 |
+
|
8 |
+
|
9 |
+
### Topic:
|
10 |
+
{question}
|
11 |
+
|
12 |
+
|
13 |
+
The output must be only a valid and syntactically correct JSON adhering to the following schema:
|
14 |
+
{{
|
15 |
+
"title": "Presentation Title",
|
16 |
+
"slides": [
|
17 |
+
{{
|
18 |
+
"heading": "Heading for the First Slide",
|
19 |
+
"bullet_points": [
|
20 |
+
"First bullet point",
|
21 |
+
[
|
22 |
+
"Sub-bullet point 1",
|
23 |
+
"Sub-bullet point 2"
|
24 |
+
],
|
25 |
+
"Second bullet point"
|
26 |
+
],
|
27 |
+
"key_message": ""
|
28 |
+
}},
|
29 |
+
{{
|
30 |
+
"heading": "Heading for the Second Slide",
|
31 |
+
"bullet_points": [
|
32 |
+
"First bullet point",
|
33 |
+
"Second bullet item",
|
34 |
+
"Third bullet point"
|
35 |
+
],
|
36 |
+
"key_message": "The key message conveyed in this slide"
|
37 |
+
}},
|
38 |
+
{{
|
39 |
+
"heading": "A slide that describes a step-by-step/sequential process",
|
40 |
+
"bullet_points": [
|
41 |
+
">> The first step of the process (begins with special marker >>)",
|
42 |
+
">> A second step (begins with >>)",
|
43 |
+
">> Third step",
|
44 |
+
],
|
45 |
+
"key_message": ""
|
46 |
+
}}
|
47 |
+
]
|
48 |
+
}}
|
49 |
+
|
50 |
+
|
51 |
+
### Some more hints on the slide content and JSON output format:
|
52 |
+
- For two or three important slides, generate the key message that those slides convey and assign
|
53 |
+
them to the `key_message` elements of JSON output.
|
54 |
+
- Identify if a slide describes a step-by-step/sequential process, then begin the bullet points
|
55 |
+
with a special marker >>. Limit this to max two or three slides.
|
56 |
+
|
57 |
+
|
58 |
+
### Output:
|
59 |
+
```json
|
langchain_templates/chat_prompts/refinement_template_v2_steps.txt
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
You are a helpful, intelligent chatbot. You follow instructions to refine an existing slide deck.
|
2 |
+
A list of user instructions is provided below in sequential order -- from the oldest to the latest.
|
3 |
+
The previously generated content of the slide deck in JSON format is also provided.
|
4 |
+
Follow the instructions to revise the content of the previously generated slides of the presentation on the given topic.
|
5 |
+
Include main headings for each slide, detailed bullet points for each slide.
|
6 |
+
Add relevant content to each slide.
|
7 |
+
The content of the slides should be descriptive, verbose, and detailed.
|
8 |
+
If relevant, add one or two examples to illustrate the concept.
|
9 |
+
Unless explicitly specified with the topic, create about 10 slides.
|
10 |
+
You also fix any syntax error that may be present in the JSON-formatted content.
|
11 |
+
|
12 |
+
A slide that describes a step-by-step/sequential process begins the bullet points
|
13 |
+
with a special marker >>
|
14 |
+
|
15 |
+
|
16 |
+
### List of instructions:
|
17 |
+
{instructions}
|
18 |
+
|
19 |
+
|
20 |
+
### Previously generated slide deck content as JSON:
|
21 |
+
{previous_content}
|
22 |
+
|
23 |
+
|
24 |
+
The output must be only a valid and syntactically correct JSON adhering to the following schema:
|
25 |
+
{{
|
26 |
+
"title": "Presentation Title",
|
27 |
+
"slides": [
|
28 |
+
{{
|
29 |
+
"heading": "Heading for the First Slide",
|
30 |
+
"bullet_points": [
|
31 |
+
"First bullet point",
|
32 |
+
[
|
33 |
+
"Sub-bullet point 1",
|
34 |
+
"Sub-bullet point 2"
|
35 |
+
],
|
36 |
+
"Second bullet point"
|
37 |
+
],
|
38 |
+
"key_message": ""
|
39 |
+
}},
|
40 |
+
{{
|
41 |
+
"heading": "Heading for the Second Slide",
|
42 |
+
"bullet_points": [
|
43 |
+
"First bullet point",
|
44 |
+
"Second bullet item",
|
45 |
+
"Third bullet point"
|
46 |
+
],
|
47 |
+
"key_message": "The key message conveyed in this slide"
|
48 |
+
}},
|
49 |
+
{{
|
50 |
+
"heading": "A slide that describes a step-by-step/sequential process",
|
51 |
+
"bullet_points": [
|
52 |
+
">> The first step of the process (begins with special marker >>)",
|
53 |
+
">> A second step (begins with >>)",
|
54 |
+
">> Third step",
|
55 |
+
],
|
56 |
+
"key_message": ""
|
57 |
+
}}
|
58 |
+
]
|
59 |
+
}}
|
60 |
+
|
61 |
+
|
62 |
+
### Some more hints on the slide content and JSON output format:
|
63 |
+
- For two or three important slides, generate the key message that those slides convey and assign
|
64 |
+
them to the `key_message` elements of JSON output.
|
65 |
+
- Identify if a slide describes a step-by-step/sequential process, then begin the bullet points
|
66 |
+
with a special marker >>. Limit this to max two or three slides.
|
67 |
+
|
68 |
+
|
69 |
+
### Output:
|
70 |
+
```json
|
requirements.txt
CHANGED
@@ -1,6 +1,14 @@
|
|
|
|
1 |
python-dotenv[cli]~=1.0.0
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
streamlit~=1.32.2
|
5 |
|
6 |
python-pptx
|
|
|
1 |
+
aiohttp==3.9.5
|
2 |
python-dotenv[cli]~=1.0.0
|
3 |
+
gitpython==3.1.43
|
4 |
+
json_repair==0.15.3
|
5 |
+
idna==3.7
|
6 |
+
jinja2==3.1.3
|
7 |
+
Pillow==10.3.0
|
8 |
+
pyarrow~=16.0.0
|
9 |
+
pydantic==2.4.0
|
10 |
+
langchain~=0.1.16
|
11 |
+
langchain-core~=0.1.46
|
12 |
streamlit~=1.32.2
|
13 |
|
14 |
python-pptx
|