|
1
|
"""Prompt templates for LLM-based content analysis.""" |
|
2
|
|
|
3
|
import logging |
|
4
|
from pathlib import Path |
|
5
|
from string import Template |
|
6
|
from typing import Dict, Optional, Union |
|
7
|
|
|
8
|
logger = logging.getLogger(__name__) |
|
9
|
|
|
10
|
|
|
11
|
class PromptTemplate: |
|
12
|
"""Template manager for LLM prompts.""" |
|
13
|
|
|
14
|
def __init__( |
|
15
|
self, |
|
16
|
templates_dir: Optional[Union[str, Path]] = None, |
|
17
|
default_templates: Optional[Dict[str, str]] = None, |
|
18
|
): |
|
19
|
""" |
|
20
|
Initialize prompt template manager. |
|
21
|
|
|
22
|
Parameters |
|
23
|
---------- |
|
24
|
templates_dir : str or Path, optional |
|
25
|
Directory containing template files |
|
26
|
default_templates : dict, optional |
|
27
|
Default templates to use |
|
28
|
""" |
|
29
|
self.templates_dir = Path(templates_dir) if templates_dir else None |
|
30
|
self.templates = {} |
|
31
|
|
|
32
|
# Load default templates |
|
33
|
if default_templates: |
|
34
|
self.templates.update(default_templates) |
|
35
|
|
|
36
|
# Load templates from directory if provided |
|
37
|
if self.templates_dir and self.templates_dir.exists(): |
|
38
|
self._load_templates_from_dir() |
|
39
|
|
|
40
|
def _load_templates_from_dir(self) -> None: |
|
41
|
"""Load templates from template directory.""" |
|
42
|
if not self.templates_dir: |
|
43
|
return |
|
44
|
|
|
45
|
for template_file in self.templates_dir.glob("*.txt"): |
|
46
|
template_name = template_file.stem |
|
47
|
try: |
|
48
|
with open(template_file, "r", encoding="utf-8") as f: |
|
49
|
template_content = f.read() |
|
50
|
self.templates[template_name] = template_content |
|
51
|
logger.debug(f"Loaded template: {template_name}") |
|
52
|
except Exception as e: |
|
53
|
logger.warning(f"Error loading template {template_name}: {str(e)}") |
|
54
|
|
|
55
|
def get_template(self, template_name: str) -> Optional[Template]: |
|
56
|
""" |
|
57
|
Get template by name. |
|
58
|
|
|
59
|
Parameters |
|
60
|
---------- |
|
61
|
template_name : str |
|
62
|
Template name |
|
63
|
|
|
64
|
Returns |
|
65
|
------- |
|
66
|
Template or None |
|
67
|
Template object if found, None otherwise |
|
68
|
""" |
|
69
|
if template_name not in self.templates: |
|
70
|
logger.warning(f"Template not found: {template_name}") |
|
71
|
return None |
|
72
|
|
|
73
|
return Template(self.templates[template_name]) |
|
74
|
|
|
75
|
def format_prompt(self, template_name: str, **kwargs) -> Optional[str]: |
|
76
|
""" |
|
77
|
Format prompt with provided parameters. |
|
78
|
|
|
79
|
Parameters |
|
80
|
---------- |
|
81
|
template_name : str |
|
82
|
Template name |
|
83
|
**kwargs : dict |
|
84
|
Template parameters |
|
85
|
|
|
86
|
Returns |
|
87
|
------- |
|
88
|
str or None |
|
89
|
Formatted prompt if template exists, None otherwise |
|
90
|
""" |
|
91
|
template = self.get_template(template_name) |
|
92
|
if not template: |
|
93
|
return None |
|
94
|
|
|
95
|
try: |
|
96
|
return template.safe_substitute(**kwargs) |
|
97
|
except Exception as e: |
|
98
|
logger.error(f"Error formatting template {template_name}: {str(e)}") |
|
99
|
return None |
|
100
|
|
|
101
|
def add_template(self, template_name: str, template_content: str) -> None: |
|
102
|
""" |
|
103
|
Add or update template. |
|
104
|
|
|
105
|
Parameters |
|
106
|
---------- |
|
107
|
template_name : str |
|
108
|
Template name |
|
109
|
template_content : str |
|
110
|
Template content |
|
111
|
""" |
|
112
|
self.templates[template_name] = template_content |
|
113
|
|
|
114
|
def save_template(self, template_name: str) -> bool: |
|
115
|
""" |
|
116
|
Save template to file. |
|
117
|
|
|
118
|
Parameters |
|
119
|
---------- |
|
120
|
template_name : str |
|
121
|
Template name |
|
122
|
|
|
123
|
Returns |
|
124
|
------- |
|
125
|
bool |
|
126
|
True if successful, False otherwise |
|
127
|
""" |
|
128
|
if not self.templates_dir: |
|
129
|
logger.error("Templates directory not set") |
|
130
|
return False |
|
131
|
|
|
132
|
if template_name not in self.templates: |
|
133
|
logger.warning(f"Template not found: {template_name}") |
|
134
|
return False |
|
135
|
|
|
136
|
try: |
|
137
|
self.templates_dir.mkdir(parents=True, exist_ok=True) |
|
138
|
template_path = self.templates_dir / f"{template_name}.txt" |
|
139
|
|
|
140
|
with open(template_path, "w", encoding="utf-8") as f: |
|
141
|
f.write(self.templates[template_name]) |
|
142
|
|
|
143
|
logger.debug(f"Saved template: {template_name}") |
|
144
|
return True |
|
145
|
except Exception as e: |
|
146
|
logger.error(f"Error saving template {template_name}: {str(e)}") |
|
147
|
return False |
|
148
|
|
|
149
|
|
|
150
|
# Default prompt templates |
|
151
|
DEFAULT_TEMPLATES = { |
|
152
|
"content_analysis": """ |
|
153
|
Analyze the provided video content and extract key information: |
|
154
|
|
|
155
|
TRANSCRIPT: |
|
156
|
$transcript |
|
157
|
|
|
158
|
VISUAL ELEMENTS (if available): |
|
159
|
$visual_elements |
|
160
|
|
|
161
|
Please extract and organize the following: |
|
162
|
- Main topics and themes |
|
163
|
- Key points for each topic |
|
164
|
- Important details or facts |
|
165
|
- Action items or follow-ups |
|
166
|
- Relationships between concepts |
|
167
|
|
|
168
|
Format the output as structured markdown. |
|
169
|
""", |
|
170
|
"diagram_extraction": """ |
|
171
|
Analyze the following image that contains a diagram, whiteboard content, |
|
172
|
or other visual information. |
|
173
|
|
|
174
|
Extract and convert this visual information into a structured representation. |
|
175
|
|
|
176
|
If it's a flowchart, process diagram, or similar structured visual: |
|
177
|
- Identify the components and their relationships |
|
178
|
- Preserve the logical flow and structure |
|
179
|
- Convert it to mermaid diagram syntax |
|
180
|
|
|
181
|
If it's a whiteboard with text, bullet points, or unstructured content: |
|
182
|
- Extract all text elements |
|
183
|
- Preserve hierarchical organization if present |
|
184
|
- Maintain any emphasized or highlighted elements |
|
185
|
|
|
186
|
Image context: $image_context |
|
187
|
|
|
188
|
Return the results as markdown with appropriate structure. |
|
189
|
""", |
|
190
|
"action_item_detection": """ |
|
191
|
Review the following transcript and identify all action items, commitments, or follow-up tasks. |
|
192
|
|
|
193
|
TRANSCRIPT: |
|
194
|
$transcript |
|
195
|
|
|
196
|
For each action item, extract: |
|
197
|
- The specific action to be taken |
|
198
|
- Who is responsible (if mentioned) |
|
199
|
- Any deadlines or timeframes |
|
200
|
- Priority level (if indicated) |
|
201
|
- Context or additional details |
|
202
|
|
|
203
|
Format the results as a structured list of action items. |
|
204
|
""", |
|
205
|
"content_summary": """ |
|
206
|
Provide a concise summary of the following content: |
|
207
|
|
|
208
|
$content |
|
209
|
|
|
210
|
The summary should: |
|
211
|
- Capture the main points and key takeaways |
|
212
|
- Be approximately 3-5 paragraphs |
|
213
|
- Focus on the most important information |
|
214
|
- Maintain a neutral, objective tone |
|
215
|
|
|
216
|
Format the summary as clear, readable text. |
|
217
|
""", |
|
218
|
"summary_generation": """ |
|
219
|
Generate a comprehensive summary of the following transcript content. |
|
220
|
|
|
221
|
CONTENT: |
|
222
|
$content |
|
223
|
|
|
224
|
Provide a well-structured summary that: |
|
225
|
- Captures the main topics discussed |
|
226
|
- Highlights key decisions or conclusions |
|
227
|
- Notes any important context or background |
|
228
|
- Is 3-5 paragraphs long |
|
229
|
|
|
230
|
Write in clear, professional prose. |
|
231
|
""", |
|
232
|
"key_points_extraction": """ |
|
233
|
Extract the key points from the following content. |
|
234
|
|
|
235
|
CONTENT: |
|
236
|
$content |
|
237
|
|
|
238
|
Return a JSON array of key point objects. Each object should have: |
|
239
|
- "point": the key point (1-2 sentences) |
|
240
|
- "topic": category or topic area (optional) |
|
241
|
- "details": supporting details (optional) |
|
242
|
|
|
243
|
Example format: |
|
244
|
[ |
|
245
|
{"point": "The system uses microservices architecture", |
|
246
|
"topic": "Architecture", "details": "Each service handles a specific domain"}, |
|
247
|
] |
|
248
|
|
|
249
|
Return ONLY the JSON array, no additional text. |
|
250
|
""", |
|
251
|
"entity_extraction": """ |
|
252
|
Extract all notable entities (people, concepts, technologies, organizations, |
|
253
|
time references) from the following content. |
|
254
|
CONTENT: |
|
255
|
$content |
|
256
|
|
|
257
|
Return a JSON array of entity objects: |
|
258
|
[ |
|
259
|
{"name": "entity name", |
|
260
|
"type": "person|concept|technology|organization|time", |
|
261
|
"description": "brief description"} |
|
262
|
|
|
263
|
Return ONLY the JSON array, no additional text. |
|
264
|
""", |
|
265
|
"relationship_extraction": """ |
|
266
|
Given the following content and entities, identify relationships between them. |
|
267
|
|
|
268
|
CONTENT: |
|
269
|
$content |
|
270
|
|
|
271
|
KNOWN ENTITIES: |
|
272
|
$entities |
|
273
|
|
|
274
|
Return a JSON array of relationship objects: |
|
275
|
[ |
|
276
|
{"source": "entity A", "target": "entity B", |
|
277
|
"type": "relationship type (e.g., uses, manages, depends_on, created_by, part_of)"} |
|
278
|
|
|
279
|
Return ONLY the JSON array, no additional text. |
|
280
|
""", |
|
281
|
"diagram_analysis": """ |
|
282
|
Analyze the following text extracted from a diagram or visual element. |
|
283
|
|
|
284
|
DIAGRAM TEXT: |
|
285
|
$diagram_text |
|
286
|
|
|
287
|
Identify: |
|
288
|
1. The type of diagram (flowchart, architecture, sequence, etc.) |
|
289
|
2. The main components and their roles |
|
290
|
3. The relationships between components |
|
291
|
4. Any data flows or process steps |
|
292
|
|
|
293
|
Return a JSON object: |
|
294
|
{ |
|
295
|
"diagram_type": "type", |
|
296
|
"components": ["list of components"], |
|
297
|
"relationships": ["component A -> component B: description"], |
|
298
|
"summary": "brief description of what the diagram shows" |
|
299
|
} |
|
300
|
|
|
301
|
Return ONLY the JSON object, no additional text. |
|
302
|
""", |
|
303
|
"mermaid_generation": """ |
|
304
|
Convert the following diagram information into valid Mermaid diagram syntax. |
|
305
|
|
|
306
|
Diagram Type: $diagram_type |
|
307
|
Text Content: $text_content |
|
308
|
Analysis: $semantic_analysis |
|
309
|
|
|
310
|
Generate a Mermaid diagram that accurately represents the visual structure. |
|
311
|
Use the appropriate Mermaid diagram type (graph, sequenceDiagram, classDiagram, etc.). |
|
312
|
|
|
313
|
Return ONLY the Mermaid code, no markdown fences or explanations. |
|
314
|
""", |
|
315
|
} |
|
316
|
|
|
317
|
# Create default prompt template manager |
|
318
|
default_prompt_manager = PromptTemplate(default_templates=DEFAULT_TEMPLATES) |
|
319
|
|