mgbam commited on
Commit
ada066c
Β·
verified Β·
1 Parent(s): 1cb1db0

Update core/prompt_engineering.py

Browse files
Files changed (1) hide show
  1. 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
- # create_story_breakdown_prompt - (ensure key_action and emotional_beat are descriptive) - REMAINS SAME
5
- def create_story_breakdown_prompt(user_idea, genre="sci-fi", mood="suspenseful", num_scenes=3):
 
 
 
 
 
 
 
 
 
 
6
  return f"""
7
- You are an expert screenwriter and visual storyteller. Based on: "{user_idea}", genre: "{genre}", mood: "{mood}".
8
- Generate a {num_scenes}-scene story breakdown. For each scene:
9
- 1. scene_number (int)
10
- 2. emotional_beat (str): Short title for the scene's core feeling.
11
- 3. setting_description (str): Vivid description (30-50 words).
12
- 4. characters_involved (list of str): Names of characters.
13
- 5. key_action (str): Main event for video overlay (15-20 words).
14
- 6. dialogue_snippet (str): Brief impactful dialogue.
15
- 7. visual_style_suggestion (str): Keywords for visual style.
16
- 8. camera_angle_suggestion (str): Specific camera shot.
17
- Output ONLY the JSON list of scenes. Example:
18
- {{ "scene_number": 1, "emotional_beat": "Tense Standoff", "setting_description": "Rain-slicked, neon-drenched alleyway...", "characters_involved": ["Detective Kaito", "Informant"], "key_action": "Kaito cautiously approaches a nervous informant.", "dialogue_snippet": "Informant: 'They know...'", "visual_style_suggestion": "Neo-noir, cyberpunk...", "camera_angle_suggestion": "Medium shot..."}}
19
- [{{"scene1_details..."}}, {{"scene2_details..."}}]
 
 
 
 
 
 
 
 
 
 
 
20
  """
21
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
- # create_image_prompt_from_scene_data - (injects char defs & style) - REMAINS SAME
24
- def create_image_prompt_from_scene_data(scene_data, character_definitions=None, global_style_reference=""):
25
- emotional_beat_title = scene_data.get('emotional_beat', 'A cinematic scene')
26
- setting_desc = scene_data.get('setting_description', 'A visually interesting setting.')
27
- key_action_desc = scene_data.get('key_action', 'A significant moment unfolds.')
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
- character_prompt_segments.append(f"{char_name_clean} (described as: {character_definitions[char_lookup_key]})")
35
  else: character_prompt_segments.append(char_name_clean)
36
- characters_narrative = ""
37
- if character_prompt_segments:
38
- if len(character_prompt_segments) == 1: characters_narrative = f"The main character is {character_prompt_segments[0]}."
39
- else: characters_narrative = f"The scene features {', '.join(character_prompt_segments[:-1])}, and {character_prompt_segments[-1]}."
40
- narrative_prompt = f"Scene Number: {scene_data.get('scene_number', 'N/A')}. Setting: {setting_desc}. {characters_narrative} Key Action: {key_action_desc}. Emotional Tone: {scene_data.get('emotional_beat', '')}."
41
- style_instructions = f"Visual Style: {scene_data.get('visual_style_suggestion', 'cinematic, photorealistic')}."
42
- if global_style_reference: style_instructions += f" Specific style reference: {global_style_reference}."
43
- camera_instructions = f"Camera Perspective: {scene_data.get('camera_angle_suggestion', 'eye-level medium shot')}."
44
- full_prompt = (f"Generate an ultra-detailed, photorealistic, and highly cinematic digital painting or concept art image. "
45
- f"The image should depict: '{emotional_beat_title}'. Narrative Context: {narrative_prompt} "
46
- f"Artistic & Technical Instructions: {style_instructions} {camera_instructions} "
47
- f"Emphasize: Cinematic composition, dramatic lighting, rich textures, depth of field, strong atmospheric effects. "
48
- f"The image must feel like a high-quality film still. Pay close attention to character details.")
49
- return " ".join(full_prompt.split())
50
-
51
-
52
- # --- NEW: Prompt for Narration Script ---
53
- def create_narration_script_prompt(story_scenes_data, overall_mood, overall_genre):
 
 
 
 
54
  """
55
- Generates a prompt for Gemini to write a concise narration script for an animatic,
56
- covering all provided scenes.
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','')}):\n"
62
- f"- Setting: {scene.get('setting_description','')}\n"
63
- f"- Key Action: {scene.get('key_action','')}\n"
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
- prompt = f"""
71
- You are a professional scriptwriter for documentary-style voiceovers and cinematic trailers.
72
- Given the following scene summaries for an animatic storyboard:
 
 
73
 
74
- --- SCENE SUMMARIES ---
 
 
 
75
  {full_summary_text}
76
- --- END SCENE SUMMARIES ---
77
 
78
- Overall Story Genre: {overall_genre}
79
- Overall Story Mood: {overall_mood}
 
80
 
81
- Write a concise, engaging, and continuous narration script that flows smoothly across these scenes.
82
- The narration should enhance the visual storytelling, not just describe what's visible.
83
- It should set the tone, build suspense or emotion, and connect the scenes thematically.
84
- The tone of the narration should match the overall mood and genre.
85
- Keep the narration for each scene relatively brief (1-2 short sentences per scene on average).
86
- The total narration should be suitable for a short animatic (e.g., if 3 scenes at 4 seconds each, total ~12 seconds of video, so narration should be ~60-90 words max).
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
- Example (if scenes were about a space discovery):
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
- context_str = f"Original scene (Scene Number {original_scene_data.get('scene_number')}):\n{json.dumps(original_scene_data, indent=2)}\n\n"
 
101
  if full_story_context: context_str += f"Full story context:\n{json.dumps(full_story_context, indent=2)}\n\n"
102
- return (f"Expert script doctor. Original scene:\n{context_str}User feedback: \"{user_feedback}\"\n"
103
- f"Regenerate ONLY the JSON for this single scene, incorporating feedback. Maintain structure. 'key_action' max 15-20 words.")
104
-
105
- # create_visual_regeneration_prompt - REMAINS SAME
106
- def create_visual_regeneration_prompt(original_image_prompt_text, user_feedback_on_visuals, scene_data, character_definitions=None, global_style_reference=""):
107
- scene_context_summary = (f"Scene: {scene_data.get('emotional_beat', '')}. Setting: {scene_data.get('setting_description', '')}. "
108
- f"Action: {scene_data.get('key_action', '')}. Characters: {', '.join(scene_data.get('characters_involved',[]))}.")
109
- char_details_str = "Relevant characters: " + (", ".join([f"{name} ({desc})" for name, desc in character_definitions.items() if name.lower() in [cn.lower() for cn in scene_data.get('characters_involved',[])]])) if character_definitions else "None specified."
110
- return (f"AI assistant for refining DALL-E 3 prompts. Original Scene Context: {scene_context_summary} {char_details_str} "
111
- f"Global Style: \"{global_style_reference}\". Original DALL-E 3 prompt was: \"{original_image_prompt_text}\". "
112
- f"User feedback on visual: \"{user_feedback_on_visuals}\". Generate a new, revised DALL-E 3 prompt. "
113
- f"It must be ultra-detailed, photorealistic, cinematic, film/game quality. Translate feedback into concrete visual descriptions. "
114
- f"Respect character descriptions. Output ONLY the new prompt string.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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())