Update core/prompt_engineering.py
Browse files- core/prompt_engineering.py +163 -88
core/prompt_engineering.py
CHANGED
@@ -1,114 +1,189 @@
|
|
1 |
# core/prompt_engineering.py
|
2 |
import json
|
3 |
|
4 |
-
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
return f"""
|
7 |
-
You are an
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
"""
|
21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
characters_involved_in_scene = scene_data.get('characters_involved', [])
|
29 |
-
character_prompt_segments = []
|
30 |
-
if characters_involved_in_scene:
|
31 |
-
for char_name_from_scene in characters_involved_in_scene:
|
32 |
-
char_name_clean = char_name_from_scene.strip(); char_lookup_key = char_name_clean.lower()
|
33 |
if character_definitions and char_lookup_key in character_definitions:
|
34 |
-
|
35 |
else: character_prompt_segments.append(char_name_clean)
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
54 |
"""
|
55 |
-
Generates a
|
56 |
-
|
57 |
"""
|
|
|
58 |
scenes_summary = []
|
59 |
for i, scene in enumerate(story_scenes_data):
|
60 |
scenes_summary.append(
|
61 |
-
f"Scene {scene.get('scene_number', i+1)} ({scene.get('emotional_beat','')})
|
62 |
-
f"
|
63 |
-
f"
|
64 |
-
f"- Characters: {', '.join(scene.get('characters_involved',[]))}\n"
|
65 |
-
f"- Implied Dialogue/Thought: {scene.get('dialogue_snippet','(none)')}"
|
66 |
)
|
67 |
-
|
68 |
-
full_summary_text = "\n\n".join(scenes_summary)
|
69 |
|
70 |
-
|
71 |
-
|
72 |
-
|
|
|
|
|
73 |
|
74 |
-
|
|
|
|
|
|
|
75 |
{full_summary_text}
|
76 |
-
--- END SCENE
|
77 |
|
78 |
-
Overall
|
79 |
-
Overall
|
|
|
80 |
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
Do not include scene numbers or explicit directives like "(Voiceover)" in the output. Just provide the pure narration text.
|
88 |
-
Focus on evocative language.
|
89 |
|
90 |
-
|
91 |
-
"The red dust of Mars whispered secrets of a forgotten age. Deep within the chasm, an impossible structure pulsed with an alien light, beckoning humanity towards a destiny unknown, and perhaps, a truth too vast to comprehend."
|
92 |
-
|
93 |
-
Output ONLY the narration script text.
|
94 |
"""
|
95 |
return " ".join(prompt.split())
|
96 |
|
97 |
-
|
98 |
-
# create_scene_regeneration_prompt - REMAINS SAME
|
99 |
def create_scene_regeneration_prompt(original_scene_data, user_feedback, full_story_context=None):
|
100 |
-
|
|
|
101 |
if full_story_context: context_str += f"Full story context:\n{json.dumps(full_story_context, indent=2)}\n\n"
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
# core/prompt_engineering.py
|
2 |
import json
|
3 |
|
4 |
+
def create_cinematic_treatment_prompt(user_idea, genre, mood, num_scenes=3, creative_guidance="standard"):
|
5 |
+
"""
|
6 |
+
Generates a prompt for Gemini to create a full cinematic treatment, including
|
7 |
+
proactive suggestions for visual style, camera, sound, and even thematic elements.
|
8 |
+
creative_guidance: "standard", "more_artistic", "experimental_narrative"
|
9 |
+
"""
|
10 |
+
guidance_detail = {
|
11 |
+
"standard": "Provide solid, genre-appropriate suggestions.",
|
12 |
+
"more_artistic": "Lean into more artistic, unconventional, and visually striking suggestions for style and camera. Suggest unique color palettes or lighting.",
|
13 |
+
"experimental_narrative": "Feel free to suggest a minor unexpected narrative twist or a symbolic visual motif that could enhance the story within one of the scenes."
|
14 |
+
}[creative_guidance]
|
15 |
+
|
16 |
return f"""
|
17 |
+
You are an AI Creative Director and Master Storyteller, collaborating on a cinematic concept.
|
18 |
+
Base Idea: "{user_idea}"
|
19 |
+
Genre: "{genre}"
|
20 |
+
Mood: "{mood}"
|
21 |
+
Number of Key Scenes: {num_scenes}
|
22 |
+
Creative Guidance Level: {creative_guidance} ({guidance_detail})
|
23 |
+
|
24 |
+
Task: Develop a rich cinematic treatment. For EACH of the {num_scenes} key scenes, provide:
|
25 |
+
1. `scene_number` (int): Sequential.
|
26 |
+
2. `scene_title` (str): A short, evocative title for the scene (e.g., "The Neon Rains of Sector 7", "Echoes in the Void").
|
27 |
+
3. `setting_description` (str): Vivid, sensory details (sight, sound, atmosphere). Where are we? What makes it unique? (40-60 words).
|
28 |
+
4. `characters_involved` (list of str): Names of characters central to this scene.
|
29 |
+
5. `character_focus_moment` (str): For the primary character(s) in this scene, describe a key internal thought, subtle expression, or micro-action that reveals their state of mind or advances their arc.
|
30 |
+
6. `key_plot_beat` (str): The most critical plot development or character action in this scene (1-2 sentences).
|
31 |
+
7. `suggested_dialogue_hook` (str): One potent line of dialogue that captures the scene's essence or a character's voice. (If no dialogue, state "Silent scene").
|
32 |
+
8. `PROACTIVE_visual_style_κ°λ
` (str): Your proactive, detailed suggestion for this scene's visual style. Go beyond generic terms. Think specific art movements, film references, color theory, lighting techniques (e.g., "Dutch angles with chiaroscuro lighting, using a desaturated palette with piercing cyan highlights, reminiscent of early Tarkovsky but with a cyberpunk edge").
|
33 |
+
9. `PROACTIVE_camera_work_κ°λ
` (str): Your proactive suggestion for impactful camera work. Describe a specific shot or short sequence (e.g., "Slow dolly zoom into the protagonist's eyes, followed by a whip pan to reveal the approaching threat off-screen").
|
34 |
+
10. `PROACTIVE_sound_design_κ°λ
` (str): Key ambient sounds, specific SFX, and a suggestion for the musical mood/instrumentation for this scene (e.g., "Ambient: Distant city hum, dripping water. SFX: Glitching electronic spark. Music: Low, ominous synth pads with a recurring, detuned piano motif").
|
35 |
+
11. `dalle_image_prompt_keywords` (str): A concise list of 5-7 powerful keywords extracted from the above, specifically for generating a DALL-E image that captures the visual essence of this scene. Focus on nouns, strong adjectives, and artistic styles. (e.g., "cyberpunk alleyway, neon rain, lone figure, glowing data streams, high contrast, cinematic").
|
36 |
+
12. `pexels_search_query_κ°λ
` (str): A concise, effective search query (2-4 words) for Pexels to find a background or atmospheric shot relevant to this scene's setting or mood (e.g., "rainy neon city," "vast desert landscape," "server room interior").
|
37 |
+
|
38 |
+
If `creative_guidance` is "experimental_narrative", for one scene, you may subtly alter `key_plot_beat` or add a symbolic element to `setting_description` to introduce an unexpected twist, explaining your reasoning briefly in a `director_note` field for that scene only.
|
39 |
+
|
40 |
+
Output ONLY a valid JSON list of these scene objects. Ensure all field names are exactly as specified (κ°λ
denotes your proactive directorial input).
|
41 |
"""
|
42 |
|
43 |
+
# create_image_prompt_from_scene_data - THIS WILL NOW BE SIMPLER.
|
44 |
+
# Gemini already gave us dalle_image_prompt_keywords. We can build upon that.
|
45 |
+
def construct_dalle_prompt(scene_data, character_definitions=None, global_style_additions=""):
|
46 |
+
"""
|
47 |
+
Constructs the final DALL-E prompt using keywords from Gemini,
|
48 |
+
character details, and global style.
|
49 |
+
"""
|
50 |
+
base_keywords = scene_data.get('dalle_image_prompt_keywords', 'cinematic scene')
|
51 |
+
setting_desc = scene_data.get('setting_description', '') # For context
|
52 |
+
action_desc = scene_data.get('key_plot_beat', '') # For context
|
53 |
+
director_visual_style = scene_data.get('PROACTIVE_visual_style_κ°λ
', '')
|
54 |
+
director_camera = scene_data.get('PROACTIVE_camera_work_κ°λ
', '')
|
55 |
|
56 |
+
character_details_for_prompt = []
|
57 |
+
# ... (Character injection logic remains the same as your last version, using char_name_lookup etc.)
|
58 |
+
if scene_data.get('characters_involved'):
|
59 |
+
for char_name_in_scene in scene_data.get('characters_involved', []):
|
60 |
+
char_name_clean = char_name_in_scene.strip(); char_lookup_key = char_name_clean.lower()
|
|
|
|
|
|
|
|
|
|
|
61 |
if character_definitions and char_lookup_key in character_definitions:
|
62 |
+
character_details_for_prompt.append(f"{char_name_clean} ({character_definitions[char_lookup_key]})")
|
63 |
else: character_prompt_segments.append(char_name_clean)
|
64 |
+
|
65 |
+
character_narrative = ""
|
66 |
+
if character_details_for_prompt:
|
67 |
+
character_narrative = f" Characters featured: {', '.join(character_details_for_prompt)}."
|
68 |
+
|
69 |
+
# DALL-E 3 often prefers more natural language but benefits from strong keywords.
|
70 |
+
# We combine Gemini's suggestions with a structured approach.
|
71 |
+
prompt = (
|
72 |
+
f"Create an ultra-detailed, photorealistic, and highly cinematic masterpiece image. "
|
73 |
+
f"Theme: '{scene_data.get('scene_title', 'A dramatic moment')}'. "
|
74 |
+
f"Core visual elements based on keywords: {base_keywords}. " # Gemini's keywords
|
75 |
+
f"{character_narrative} " # Injected character descriptions
|
76 |
+
f"The scene unfolds in this setting: {setting_desc}. The key moment is: {action_desc}. "
|
77 |
+
f"Artistic Direction -- Visual Style: {director_visual_style}. {global_style_additions}. "
|
78 |
+
f"Cinematography -- Camera Work: {director_camera}. "
|
79 |
+
f"Overall Impression: Evoke the mood of '{scene_data.get('mood', 'intense')}' with an atmosphere of '{scene_data.get('emotional_beat', 'suspense')}'. "
|
80 |
+
f"Render with extreme detail, complex lighting, and rich textures suitable for a blockbuster film's concept art. "
|
81 |
+
)
|
82 |
+
return " ".join(prompt.split())
|
83 |
+
|
84 |
+
|
85 |
+
def create_narration_script_prompt_enhanced(story_scenes_data, overall_mood, overall_genre, voice_style="cinematic_trailer"):
|
86 |
"""
|
87 |
+
Generates a more nuanced narration script prompt for Gemini.
|
88 |
+
voice_style: "cinematic_trailer", "documentary_neutral", "introspective_character"
|
89 |
"""
|
90 |
+
# ... (scene summary logic remains the same as your last version) ...
|
91 |
scenes_summary = []
|
92 |
for i, scene in enumerate(story_scenes_data):
|
93 |
scenes_summary.append(
|
94 |
+
f"Scene {scene.get('scene_number', i+1)} ({scene.get('scene_title','Untitled')} - {scene.get('emotional_beat','')})"
|
95 |
+
f": {scene.get('key_plot_beat','')} Focus: {scene.get('character_focus_moment','')} "
|
96 |
+
f"Soundscape hint: {scene.get('PROACTIVE_sound_design_κ°λ
','')}"
|
|
|
|
|
97 |
)
|
98 |
+
full_summary_text = "\n".join(scenes_summary)
|
|
|
99 |
|
100 |
+
voice_style_description = {
|
101 |
+
"cinematic_trailer": "deep, resonant, and slightly epic, building anticipation.",
|
102 |
+
"documentary_neutral": "clear, informative, and objective.",
|
103 |
+
"introspective_character": f"reflective, personal, perhaps echoing the thoughts of a key character (e.g., Jax, if present)."
|
104 |
+
}[voice_style]
|
105 |
|
106 |
+
prompt = f"""
|
107 |
+
You are an award-winning voiceover scriptwriter.
|
108 |
+
Craft a compelling, continuous narration script for a short cinematic animatic based on these scene insights:
|
109 |
+
--- SCENE INSIGHTS ---
|
110 |
{full_summary_text}
|
111 |
+
--- END SCENE INSIGHTS ---
|
112 |
|
113 |
+
Overall Genre: {overall_genre}
|
114 |
+
Overall Mood: {overall_mood}
|
115 |
+
Desired Voiceover Style: {voice_style} (Characteristics: {voice_style_description})
|
116 |
|
117 |
+
The narration should:
|
118 |
+
- Weave a cohesive narrative thread through the scenes.
|
119 |
+
- Enhance emotional impact and atmosphere, guided by the scene's 'emotional_beat' and 'soundscape_hint'.
|
120 |
+
- Be concise: Aim for 1-2 powerful sentences per scene. Total words ~60-100 for 3-4 scenes.
|
121 |
+
- Avoid merely describing the action; instead, offer insight, build tension, or evoke thematic depth.
|
122 |
+
- If style is 'introspective_character', imagine one of the characters is narrating their internal monologue.
|
|
|
|
|
123 |
|
124 |
+
Output ONLY the pure narration script text, ready for text-to-speech. No scene numbers, no "VO:", just the spoken words.
|
|
|
|
|
|
|
125 |
"""
|
126 |
return " ".join(prompt.split())
|
127 |
|
128 |
+
# create_scene_regeneration_prompt - Now uses the new fields
|
|
|
129 |
def create_scene_regeneration_prompt(original_scene_data, user_feedback, full_story_context=None):
|
130 |
+
# ... (context_str same) ...
|
131 |
+
context_str = f"Original scene (Scene Number {original_scene_data.get('scene_number')} - Title: {original_scene_data.get('scene_title')} ):\n{json.dumps(original_scene_data, indent=2)}\n\n"
|
132 |
if full_story_context: context_str += f"Full story context:\n{json.dumps(full_story_context, indent=2)}\n\n"
|
133 |
+
|
134 |
+
return f"""
|
135 |
+
You are an AI Script Supervisor and Creative Consultant.
|
136 |
+
{context_str}
|
137 |
+
User Feedback for this scene: "{user_feedback}"
|
138 |
+
|
139 |
+
Regenerate ONLY the JSON object for this single scene, incorporating the feedback.
|
140 |
+
Maintain the exact field structure: (scene_number, scene_title, setting_description, characters_involved, character_focus_moment, key_plot_beat, suggested_dialogue_hook, PROACTIVE_visual_style_κ°λ
, PROACTIVE_camera_work_κ°λ
, PROACTIVE_sound_design_κ°λ
, dalle_image_prompt_keywords, pexels_search_query_κ°λ
).
|
141 |
+
'scene_number' MUST NOT change.
|
142 |
+
If feedback targets plot, characters, or dialogue, adjust relevant fields.
|
143 |
+
If feedback targets visuals, camera, or sound, update the 'PROACTIVE_..._κ°λ
' fields AND the 'dalle_image_prompt_keywords' and 'pexels_search_query_κ°λ
' to reflect the new direction.
|
144 |
+
Ensure 'key_plot_beat' is a concise sentence (max 15-20 words).
|
145 |
+
If adding a `director_note` due to experimental narrative changes, ensure it's brief.
|
146 |
+
"""
|
147 |
+
|
148 |
+
# create_visual_regeneration_prompt - Now uses more context for Gemini to rewrite DALL-E prompt
|
149 |
+
def create_visual_regeneration_prompt(original_dalle_prompt, user_feedback, scene_data, character_definitions=None, global_style_additions=""):
|
150 |
+
# ... (character_narrative same as in construct_dalle_prompt) ...
|
151 |
+
characters_involved_in_scene = scene_data.get('characters_involved', [])
|
152 |
+
character_prompt_segments = []
|
153 |
+
if characters_involved_in_scene:
|
154 |
+
for char_name_from_scene in characters_involved_in_scene:
|
155 |
+
char_name_clean = char_name_from_scene.strip(); char_lookup_key = char_name_clean.lower()
|
156 |
+
if character_definitions and char_lookup_key in character_definitions: character_prompt_segments.append(f"{char_name_clean} ({character_definitions[char_lookup_key]})")
|
157 |
+
else: character_prompt_segments.append(char_name_clean)
|
158 |
+
characters_narrative = f" Characters to feature: {', '.join(character_prompt_segments) if character_prompt_segments else 'None specifically detailed'}."
|
159 |
+
|
160 |
+
full_prompt_for_gemini = f"""
|
161 |
+
You are an AI Art Director specializing in refining DALL-E 3 prompts for cinematic visuals.
|
162 |
+
The goal is to update an image prompt based on user feedback.
|
163 |
+
|
164 |
+
Scene Context:
|
165 |
+
- Title: "{scene_data.get('scene_title', '')}"
|
166 |
+
- Setting: "{scene_data.get('setting_description', '')}"
|
167 |
+
- Key Plot Beat: "{scene_data.get('key_plot_beat', '')}"
|
168 |
+
- {characters_narrative}
|
169 |
+
- Director's Suggested Visual Style: "{scene_data.get('PROACTIVE_visual_style_κ°λ
', '')}"
|
170 |
+
- Director's Suggested Camera: "{scene_data.get('PROACTIVE_camera_work_κ°λ
', '')}"
|
171 |
+
- Current Global Style Additions: "{global_style_additions}"
|
172 |
+
|
173 |
+
The PREVIOUS DALL-E 3 prompt was:
|
174 |
+
"{original_dalle_prompt}"
|
175 |
+
|
176 |
+
User Feedback on the image generated by the previous prompt:
|
177 |
+
"{user_feedback}"
|
178 |
+
|
179 |
+
Your Task: Generate a NEW, revised DALL-E 3 prompt.
|
180 |
+
This new prompt must incorporate the user's feedback to achieve the desired visual changes.
|
181 |
+
It should remain ultra-detailed, photorealistic, and highly cinematic.
|
182 |
+
The prompt should guide DALL-E 3 to create a stunning image suitable for a film's concept art.
|
183 |
+
Maintain core scene elements (setting, characters, plot beat) unless feedback explicitly requests changes.
|
184 |
+
Translate feedback into concrete visual descriptions (lighting, color, composition, character appearance/pose, atmosphere).
|
185 |
+
Reinforce character descriptions if they are relevant to the feedback.
|
186 |
+
|
187 |
+
Output ONLY the new, revised DALL-E 3 prompt string. Do not add any other text.
|
188 |
+
"""
|
189 |
+
return " ".join(full_prompt_for_gemini.split())
|