mgbam commited on
Commit
55e2347
Β·
verified Β·
1 Parent(s): 5089920

Update core/prompt_engineering.py

Browse files
Files changed (1) hide show
  1. core/prompt_engineering.py +154 -81
core/prompt_engineering.py CHANGED
@@ -4,15 +4,17 @@ import json
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}"
@@ -21,103 +23,160 @@ def create_cinematic_treatment_prompt(user_idea, genre, mood, num_scenes=3, crea
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 the following fields EXACTLY as named:
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. If a character is non-speaking or an entity (e.g., "Scavenger Drone"), list them.
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. If no specific character focus, describe the general atmosphere's impact.
30
- 6. `key_plot_beat` (str): The most critical plot development or character action in this scene (1-2 sentences). This should be suitable for a brief video overlay.
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" or describe key non-verbal communication).
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 all the above details (setting, characters, action, style, camera), 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 Jax, glowing data streams, high contrast shadows, cinematic low-angle").
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," "dark server room interior").
37
-
38
- If `creative_guidance` is "experimental_narrative", for ONLY ONE of the scenes, you may subtly alter `key_plot_beat` or add a symbolic element to `setting_description` to introduce an unexpected twist. If you do this, add a field `director_note` (str) to THAT SCENE ONLY, briefly explaining your creative choice for the twist.
 
 
 
 
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
- Example for one scene object (ensure all fields are present for every scene):
42
  {{
43
  "scene_number": 1,
44
  "scene_title": "Sun-Bleached Mirage",
45
- "setting_description": "The relentless sun beats down on endless rust-colored dunes, shimmering with heat haze. Skeletal remains of colossal, forgotten machinery litter the landscape, half-buried by the sands of time. The air hangs heavy with the scent of dust and decay, punctuated by the occasional groan of shifting metal.",
 
46
  "characters_involved": ["Anya"],
47
- "character_focus_moment": "Anya's hand, cracked and sunburnt, instinctively reaches for the worn leather strap of her water canteen - almost empty. A flicker of doubt crosses her face, quickly masked by a determined set to her jaw.",
48
- "key_plot_beat": "Anya, fueled by a tattered map and dwindling hope, navigates the treacherous dunes, avoiding a patrol of mechanical scavengers.",
49
- "suggested_dialogue_hook": "(Anya, to herself, raspy whisper) 'Almost there... just a little further.'",
50
- "PROACTIVE_visual_style_감독": "Widescreen anamorphic, sun-bleached desaturated palette with occasional metallic glints. High dynamic range, emphasizing the harshness of the sun and the deep shadows. Inspired by 'Mad Max: Fury Road' meets 'Dune (2021)' cinematography. Visible heat distortion.",
51
- "PROACTIVE_camera_work_감독": "Extreme long shot establishing Anya as a tiny figure in the vast desert, then a gritty close-up on her determined, weathered face. Slow, deliberate tracking shots as she moves.",
52
- "PROACTIVE_sound_design_감독": "Ambient: Howling wind, metallic creaks of distant machinery. SFX: Crunch of sand underfoot, Anya's strained breathing. Music: Sparse, atmospheric, with low, mournful synth drones and occasional percussive hits.",
53
- "dalle_image_prompt_keywords": "post-apocalyptic desert, lone wanderer Anya, rust-colored dunes, colossal wreckages, heat haze, cinematic widescreen, sun-bleached",
 
 
 
54
  "pexels_search_query_감독": "vast desert sun"
55
  }}
56
  """
57
 
58
  def construct_dalle_prompt(scene_data, character_definitions=None, global_style_additions=""):
59
  """
60
- Constructs the final DALL-E prompt using keywords from Gemini's treatment,
61
  injecting character details, and global style preferences.
62
  """
63
  scene_title = scene_data.get('scene_title', 'A dramatic moment')
64
- base_keywords = scene_data.get('dalle_image_prompt_keywords', 'cinematic scene, highly detailed')
65
- setting_desc_context = scene_data.get('setting_description', '')
66
- action_desc_context = scene_data.get('key_plot_beat', '')
67
- director_visual_style = scene_data.get('PROACTIVE_visual_style_감독', '') # This is key
68
- director_camera = scene_data.get('PROACTIVE_camera_work_감독', '') # This is key
69
- emotional_beat_context = scene_data.get('emotional_beat', scene_title) # Fallback to scene_title
70
-
71
- # --- Character Injection ---
72
- # This variable MUST be initialized OUTSIDE the conditional block if it's used in an else inside the loop
73
- current_scene_character_details = []
74
  characters_involved_in_scene = scene_data.get('characters_involved', [])
75
  if characters_involved_in_scene:
76
  for char_name_from_scene in characters_involved_in_scene:
77
  char_name_clean = char_name_from_scene.strip()
78
  char_lookup_key = char_name_clean.lower()
79
-
80
  if character_definitions and char_lookup_key in character_definitions:
81
  char_visual_desc = character_definitions[char_lookup_key]
82
  current_scene_character_details.append(f"{char_name_clean} (depicted as: {char_visual_desc})")
83
  else:
84
- current_scene_character_details.append(char_name_clean) # Character present but no specific definition
85
-
86
  character_narrative = ""
87
  if current_scene_character_details:
88
  if len(current_scene_character_details) == 1:
89
  character_narrative = f"The scene focuses on {current_scene_character_details[0]}."
90
  else:
91
  character_narrative = f"The scene prominently features {', '.join(current_scene_character_details[:-1])} and {current_scene_character_details[-1]}."
92
- # --- End Character Injection ---
93
 
94
  final_style_directive = director_visual_style
95
  if global_style_additions:
96
  final_style_directive = f"{director_visual_style}. Additional global style notes: {global_style_additions}."
97
 
98
- # Constructing the DALL-E 3 prompt
99
  prompt = (
100
- f"Create an ultra-detailed, photorealistic, and intensely cinematic digital painting or high-fidelity concept art. "
101
  f"The image must visually embody the scene titled: '{scene_title}'. "
102
- f"Core visual elements and keywords to include: {base_keywords}. "
103
- f"{character_narrative} "
104
- f"Contextual narrative for the visual: The setting is '{setting_desc_context}'. The key moment unfolding is '{action_desc_context}'. "
105
  f"Artistic Direction -- Overall Visual Style and Mood: {final_style_directive}. "
106
- f"Cinematography -- Camera Framing and Perspective: {director_camera}. "
107
  f"Emotional Impact: Convey a strong sense of '{emotional_beat_context}'. "
108
- f"Technical Execution: Render with extreme detail, sophisticated lighting that sculpts the forms and defines the mood (e.g., dramatic rim lighting, soft diffused light, harsh contrasts), rich and believable textures, and palpable atmospheric effects (e.g., mist, dust, lens flares, rain). "
109
- f"The final image should be of exceptional quality, suitable for a major film production's visual development phase. "
110
- f"Ensure all specified characters are distinct and adhere to their descriptions if provided."
111
  )
112
-
113
  return " ".join(prompt.split()) # Normalize whitespace
114
 
115
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  def create_narration_script_prompt_enhanced(story_scenes_data, overall_mood, overall_genre, voice_style="cinematic_trailer"):
117
  scenes_summary = []
118
  for i, scene in enumerate(story_scenes_data):
119
  scenes_summary.append(
120
- f"Scene {scene.get('scene_number', i+1)} (Title: '{scene.get('scene_title','Untitled')}', Beat: '{scene.get('emotional_beat','')}'):\n"
121
  f" Setting: {scene.get('setting_description','')}\n"
122
  f" Plot Beat: {scene.get('key_plot_beat','')}\n"
123
  f" Character Focus: {scene.get('character_focus_moment','(general atmosphere)')}\n"
@@ -129,40 +188,45 @@ def create_narration_script_prompt_enhanced(story_scenes_data, overall_mood, ove
129
  voice_style_description = {
130
  "cinematic_trailer": "deep, resonant, slightly epic, building anticipation, and authoritative.",
131
  "documentary_neutral": "clear, informative, objective, and well-paced.",
132
- "introspective_character": f"reflective, personal, possibly first-person, echoing the thoughts of a key character involved in the scenes."
133
  }[voice_style]
134
 
135
  prompt = f"""
136
- You are an award-winning voiceover scriptwriter tasked with creating narration for a cinematic animatic.
137
- The animatic is based on the following scene treatments:
138
 
139
  --- SCENE TREATMENTS ---
140
  {full_summary_text}
141
  --- END SCENE TREATMENTS ---
142
 
143
- Overall Story Genre: {overall_genre}
144
- Overall Story Mood: {overall_mood}
145
  Desired Voiceover Style: {voice_style} (Characteristics: {voice_style_description})
146
 
147
  Your narration script should:
148
- - Weave a cohesive and compelling narrative thread through all the provided scenes.
149
- - Enhance the emotional impact and atmosphere, drawing inspiration from each scene's 'emotional_beat', 'character_focus_moment', and 'sound_hint'.
150
- - Be concise yet powerful. Aim for 1-3 impactful sentences per scene. For {len(story_scenes_data)} scenes, the total script should be roughly {len(story_scenes_data) * 20}-{len(story_scenes_data) * 30} words.
151
- - Transcend simple description of action. Instead, offer insight, build tension/emotion, or evoke thematic depth.
152
- - If the style is 'introspective_character', choose one prominent character and write from their perspective, reflecting their internal state and observations.
153
- - The final output must be ONLY the narration script text, ready for text-to-speech. Do not include scene numbers, titles, or any directives like "(Voiceover)" or "Narrator:".
154
 
155
- Example of desired output format (for a different story):
156
- "Dust motes danced in the lone shaft of light, illuminating forgotten relics. Each step echoed in the vast silence, a countdown to an unknown answerm or perhaps, a more terrifying question. The air grew colder, heavy with the scent of ozone and ancient despair..."
157
 
158
- Craft your narration now.
159
  """
160
  return " ".join(prompt.split())
161
 
162
 
163
  def create_scene_regeneration_prompt(original_scene_data, user_feedback, full_story_context=None):
164
- 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"
165
- if full_story_context: context_str += f"Full story context for reference:\n{json.dumps(full_story_context, indent=2)}\n\n"
 
 
 
 
 
166
 
167
  return f"""
168
  You are an AI Script Supervisor and Creative Consultant.
@@ -170,27 +234,36 @@ def create_scene_regeneration_prompt(original_scene_data, user_feedback, full_st
170
  User Feedback for this scene: "{user_feedback}"
171
 
172
  Regenerate ONLY the JSON object for this single scene, incorporating the feedback.
173
- 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_감독).
174
- The 'scene_number' MUST NOT change.
175
- The 'key_plot_beat' should be a concise descriptive sentence (max 15-20 words).
176
- The 'dalle_image_prompt_keywords' should be updated to reflect any visual changes.
177
- The 'pexels_search_query_감독' should also be updated if the setting or mood changes significantly.
178
- If the user's feedback implies experimental narrative changes and the original scene had a `director_note`, you may update or remove it. If introducing a new experimental twist, add/update the `director_note` field.
 
 
 
 
 
 
179
  """
180
 
181
  def create_visual_regeneration_prompt(original_dalle_prompt, user_feedback, scene_data, character_definitions=None, global_style_additions=""):
 
 
 
182
  characters_involved_in_scene = scene_data.get('characters_involved', [])
183
- current_scene_character_details = [] # Initialize correctly
184
  if characters_involved_in_scene:
185
  for char_name_from_scene in characters_involved_in_scene:
186
  char_name_clean = char_name_from_scene.strip(); char_lookup_key = char_name_clean.lower()
187
- if character_definitions and char_lookup_key in character_definitions:
188
  current_scene_character_details.append(f"{char_name_clean} (described as: {character_definitions[char_lookup_key]})")
189
  else: current_scene_character_details.append(char_name_clean)
190
  characters_narrative = f" Characters to feature: {', '.join(current_scene_character_details) if current_scene_character_details else 'None specifically detailed'}."
191
 
192
  full_prompt_for_gemini = f"""
193
- You are an AI Art Director specializing in refining DALL-E 3 prompts for cinematic visuals.
194
  The goal is to update an image prompt based on user feedback.
195
 
196
  Scene Context:
@@ -208,12 +281,12 @@ def create_visual_regeneration_prompt(original_dalle_prompt, user_feedback, scen
208
  User Feedback on the visual generated by the previous prompt:
209
  "{user_feedback}"
210
 
211
- Your Task: Generate a NEW, revised DALL-E 3 prompt.
212
  This new prompt must incorporate the user's feedback to achieve the desired visual changes.
213
  It should remain ultra-detailed, photorealistic, and highly cinematic.
214
- The prompt should guide DALL-E 3 to create a stunning image suitable for a film's concept art.
215
  Maintain core scene elements (setting, characters, plot beat) unless feedback explicitly asks to change them.
216
- Translate feedback into concrete visual descriptions (lighting, color, composition, character appearance/pose, atmosphere).
217
  Reinforce character descriptions from the context if they are relevant to the feedback.
218
  The prompt should be a single block of text.
219
 
 
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, thematic elements,
8
+ and whether a scene is better as an image or a short video clip.
9
  creative_guidance: "standard", "more_artistic", "experimental_narrative"
10
  """
11
  guidance_detail = {
12
+ "standard": "Provide solid, genre-appropriate suggestions. Recommend 'image' for most asset types unless strong motion is implied.",
13
+ "more_artistic": "Lean into more artistic, unconventional, and visually striking suggestions for style and camera. Suggest unique color palettes or lighting. Consider where a 'video_clip' might offer more impact.",
14
+ "experimental_narrative": "Feel free to suggest a minor unexpected narrative twist or a symbolic visual motif. If a scene has significant implied motion or transformation, recommend 'video_clip'."
15
  }[creative_guidance]
16
 
17
+ # Updated list of fields to request from Gemini
18
  return f"""
19
  You are an AI Creative Director and Master Storyteller, collaborating on a cinematic concept.
20
  Base Idea: "{user_idea}"
 
23
  Number of Key Scenes: {num_scenes}
24
  Creative Guidance Level: {creative_guidance} ({guidance_detail})
25
 
26
+ Task: Develop a rich cinematic treatment. For EACH of the {num_scenes} key scenes, provide the following 16 fields EXACTLY as named:
27
  1. `scene_number` (int): Sequential.
28
+ 2. `scene_title` (str): A short, evocative title (e.g., "The Neon Rains of Sector 7").
29
+ 3. `emotional_beat` (str): The core emotion or feeling this scene should evoke (e.g., "Tension and Suspense", "Hopeful Discovery", "Tragic Realization").
30
+ 4. `setting_description` (str): Vivid, sensory details (sight, sound, atmosphere). Where are we? What makes it unique? (40-60 words).
31
+ 5. `characters_involved` (list of str): Names of characters central to this scene. If non-speaking or an entity (e.g., "Scavenger Drone"), list them.
32
+ 6. `character_focus_moment` (str): For primary character(s), describe a key internal thought, expression, or micro-action revealing their state or arc. If no specific character focus, describe the general atmosphere's impact.
33
+ 7. `key_plot_beat` (str): Critical plot development or character action (1-2 sentences). Suitable for brief video overlay.
34
+ 8. `suggested_dialogue_hook` (str): One potent line of dialogue. (If no dialogue, state "Silent scene" or describe key non-verbal communication).
35
+ 9. `PROACTIVE_visual_style_감독` (str): Your detailed suggestion for this scene's visual style. Specific art movements, film references, color theory, lighting (e.g., "Dutch angles, chiaroscuro, desaturated palette with cyan highlights, Tarkovsky-esque cyberpunk").
36
+ 10. `PROACTIVE_camera_work_감독` (str): Your suggestion for impactful camera work. Describe a specific shot or short sequence (e.g., "Slow dolly zoom into protagonist's eyes, whip pan to reveal threat").
37
+ 11. `PROACTIVE_sound_design_감독` (str): Key ambient sounds, SFX, and musical mood/instrumentation (e.g., "Ambient: City hum, dripping water. SFX: Glitching spark. Music: Ominous synth pads, detuned piano motif").
38
+ 12. `suggested_asset_type_감독` (str): Your recommendation for the primary visual asset for this scene: "image" (for a still) or "video_clip" (for a short ~3-7 second generated video). Default to "image" unless strong motion is described or implied.
39
+ 13. `video_clip_motion_description_감독` (str): If `suggested_asset_type_감독` is "video_clip", describe the primary motion in the scene (e.g., "Protagonist slowly turns to face the camera", "Raindrops striking neon puddles, camera pans up", "Spaceship flies past from left to right"). Otherwise, "N/A".
40
+ 14. `video_clip_duration_estimate_secs_감독` (int): If `suggested_asset_type_감독` is "video_clip", provide an estimated duration in seconds (e.g., 3, 5, 7). Otherwise, 0.
41
+ 15. `image_generation_keywords_감독` (str): A concise list of 5-8 powerful keywords extracted from all above details (setting, characters, action, style, camera, motion if video), for generating a visual asset (image OR video). Focus on nouns, strong adjectives, artistic styles, and key motion verbs if applicable. (e.g., "cyberpunk alleyway, neon rain, lone figure Jax, glowing data streams, high contrast shadows, cinematic low-angle, slow pan").
42
+ 16. `pexels_search_query_감독` (str): A concise, effective search query (2-4 words) for Pexels for a background or atmospheric shot (e.g., "rainy neon city," "vast desert landscape," "dark server room").
43
+
44
+ If `creative_guidance` is "experimental_narrative", for ONLY ONE scene, you may subtly alter `key_plot_beat` or add a symbolic element to `setting_description` for an unexpected twist. If so, add `director_note` (str) to THAT SCENE ONLY, explaining the choice.
45
 
46
  Output ONLY a valid JSON list of these scene objects. Ensure all field names are exactly as specified (감독 denotes your proactive directorial input).
47
+ Example for one scene object (ensure all 16 fields are present for every scene, plus optional director_note):
48
  {{
49
  "scene_number": 1,
50
  "scene_title": "Sun-Bleached Mirage",
51
+ "emotional_beat": "Desperate Survival",
52
+ "setting_description": "Relentless sun on endless rust-colored dunes, shimmering with heat haze. Skeletal remains of colossal, forgotten machinery litter the landscape. Air heavy with dust and decay.",
53
  "characters_involved": ["Anya"],
54
+ "character_focus_moment": "Anya's sunburnt hand reaches for her nearly empty water canteen. Doubt flickers, then masked by determination.",
55
+ "key_plot_beat": "Anya navigates treacherous dunes, guided by a tattered map, avoiding mechanical scavengers.",
56
+ "suggested_dialogue_hook": "(Anya, raspy whisper) 'Almost... just a little further.'",
57
+ "PROACTIVE_visual_style_감독": "Widescreen anamorphic, sun-bleached desaturated palette, metallic glints. HDR, harsh sun, deep shadows. 'Mad Max: Fury Road' meets 'Dune (2021)'. Visible heat distortion.",
58
+ "PROACTIVE_camera_work_감독": "Extreme long shot of Anya in vast desert, then gritty close-up on her face. Slow, deliberate tracking.",
59
+ "PROACTIVE_sound_design_감독": "Ambient: Howling wind, distant creaks. SFX: Sand crunch, strained breathing. Music: Sparse, atmospheric synth drones, percussive hits.",
60
+ "suggested_asset_type_감독": "image",
61
+ "video_clip_motion_description_감독": "N/A",
62
+ "video_clip_duration_estimate_secs_감독": 0,
63
+ "image_generation_keywords_감독": "post-apocalyptic desert, lone wanderer Anya, rust dunes, colossal wrecks, heat haze, cinematic widescreen, sun-bleached, determined expression",
64
  "pexels_search_query_감독": "vast desert sun"
65
  }}
66
  """
67
 
68
  def construct_dalle_prompt(scene_data, character_definitions=None, global_style_additions=""):
69
  """
70
+ Constructs the final DALL-E prompt for an IMAGE, using keywords from Gemini's treatment,
71
  injecting character details, and global style preferences.
72
  """
73
  scene_title = scene_data.get('scene_title', 'A dramatic moment')
74
+ # Use the more generic keyword field, suitable for images
75
+ base_keywords = scene_data.get('image_generation_keywords_감독', 'cinematic scene, highly detailed')
76
+ setting_desc_context = scene_data.get('setting_description', '')
77
+ action_desc_context = scene_data.get('key_plot_beat', '')
78
+ director_visual_style = scene_data.get('PROACTIVE_visual_style_감독', '')
79
+ director_camera = scene_data.get('PROACTIVE_camera_work_감독', '')
80
+ emotional_beat_context = scene_data.get('emotional_beat', scene_title)
81
+
82
+ current_scene_character_details = []
 
83
  characters_involved_in_scene = scene_data.get('characters_involved', [])
84
  if characters_involved_in_scene:
85
  for char_name_from_scene in characters_involved_in_scene:
86
  char_name_clean = char_name_from_scene.strip()
87
  char_lookup_key = char_name_clean.lower()
 
88
  if character_definitions and char_lookup_key in character_definitions:
89
  char_visual_desc = character_definitions[char_lookup_key]
90
  current_scene_character_details.append(f"{char_name_clean} (depicted as: {char_visual_desc})")
91
  else:
92
+ current_scene_character_details.append(char_name_clean)
93
+
94
  character_narrative = ""
95
  if current_scene_character_details:
96
  if len(current_scene_character_details) == 1:
97
  character_narrative = f"The scene focuses on {current_scene_character_details[0]}."
98
  else:
99
  character_narrative = f"The scene prominently features {', '.join(current_scene_character_details[:-1])} and {current_scene_character_details[-1]}."
 
100
 
101
  final_style_directive = director_visual_style
102
  if global_style_additions:
103
  final_style_directive = f"{director_visual_style}. Additional global style notes: {global_style_additions}."
104
 
 
105
  prompt = (
106
+ f"Create an ultra-detailed, photorealistic, and intensely cinematic still image (digital painting or high-fidelity concept art). "
107
  f"The image must visually embody the scene titled: '{scene_title}'. "
108
+ f"Core visual elements and keywords: {base_keywords}. "
109
+ f"{character_narrative} "
110
+ f"Contextual narrative for the visual: The setting is '{setting_desc_context}'. The key moment is '{action_desc_context}'. "
111
  f"Artistic Direction -- Overall Visual Style and Mood: {final_style_directive}. "
112
+ f"Cinematography -- Camera Framing and Perspective for a still image: {director_camera}. " # Emphasize still image context
113
  f"Emotional Impact: Convey a strong sense of '{emotional_beat_context}'. "
114
+ f"Technical Execution: Render with extreme detail, sophisticated lighting (e.g., dramatic rim lighting, soft diffused light, harsh contrasts), rich textures, palpable atmospheric effects (e.g., mist, dust, lens flares, rain). "
115
+ f"The final image should be of exceptional quality, suitable for a major film production's visual development. "
116
+ f"Ensure all specified characters are distinct and adhere to their descriptions if provided. Still image, no motion implied unless essential to the pose."
117
  )
 
118
  return " ".join(prompt.split()) # Normalize whitespace
119
 
120
 
121
+ def construct_text_to_video_prompt(scene_data, character_definitions=None, global_style_additions="", seed_image_path=None):
122
+ """
123
+ Constructs a prompt for a text-to-video (or image-to-video) generation model
124
+ like Runway Gen-1/Gen-2.
125
+ """
126
+ scene_title = scene_data.get('scene_title', 'A dynamic scene')
127
+ # Keywords can be used for styling and core elements
128
+ base_keywords = scene_data.get('image_generation_keywords_감독', 'cinematic video clip')
129
+ setting_desc = scene_data.get('setting_description', '')
130
+ plot_beat = scene_data.get('key_plot_beat', '')
131
+ motion_desc = scene_data.get('video_clip_motion_description_감독', 'subtle ambient motion')
132
+ visual_style = scene_data.get('PROACTIVE_visual_style_감독', '')
133
+ camera_work = scene_data.get('PROACTIVE_camera_work_감독', 'dynamic camera movement')
134
+ emotional_beat = scene_data.get('emotional_beat', scene_title)
135
+
136
+ current_scene_character_details = []
137
+ characters_involved = scene_data.get('characters_involved', [])
138
+ if characters_involved:
139
+ for char_name in characters_involved:
140
+ char_lookup_key = char_name.strip().lower()
141
+ if character_definitions and char_lookup_key in character_definitions:
142
+ current_scene_character_details.append(f"{char_name.strip()} (as: {character_definitions[char_lookup_key]})")
143
+ else:
144
+ current_scene_character_details.append(char_name.strip())
145
+
146
+ character_narrative = ""
147
+ if current_scene_character_details:
148
+ character_narrative = f"Characters involved: {', '.join(current_scene_character_details)}. Their appearance and actions should be central."
149
+
150
+ final_style_directive = visual_style
151
+ if global_style_additions:
152
+ final_style_directive = f"{visual_style}. Global style notes: {global_style_additions}."
153
+
154
+ prompt_parts = [
155
+ f"Generate a highly cinematic video clip for a scene titled '{scene_title}'.",
156
+ f"Setting: {setting_desc}.",
157
+ f"Key moment: {plot_beat}.",
158
+ character_narrative if character_narrative else "Focus on the environment and atmosphere if no specific characters are detailed.",
159
+ f"Primary Motion: {motion_desc}. This motion should be the central dynamic element of the clip.",
160
+ f"Visual Style & Mood: {final_style_directive}. Infuse with a strong sense of '{emotional_beat}'.",
161
+ f"Cinematography: Implement camera work described as '{camera_work}'. If specific shots like 'dolly zoom' or 'tracking shot' are mentioned, execute them clearly.",
162
+ f"Core visual keywords for styling and content: {base_keywords}.",
163
+ "The video should be photorealistic, with extreme detail, sophisticated lighting, rich textures, and palpable atmospheric effects.",
164
+ "Ensure high fidelity and smooth motion. The clip should feel like a shot from a major film production."
165
+ ]
166
+
167
+ if seed_image_path:
168
+ prompt_parts.append(f"Use the provided seed image at '{seed_image_path}' to guide the visual style, composition, and content of the video, while incorporating the described motion.")
169
+ else:
170
+ prompt_parts.append("Generate the video from text description only, creating all visual elements based on the prompt.")
171
+
172
+ return " ".join(" ".join(prompt_parts).split()) # Normalize whitespace
173
+
174
+
175
  def create_narration_script_prompt_enhanced(story_scenes_data, overall_mood, overall_genre, voice_style="cinematic_trailer"):
176
  scenes_summary = []
177
  for i, scene in enumerate(story_scenes_data):
178
  scenes_summary.append(
179
+ f"Scene {scene.get('scene_number', i+1)} (Title: '{scene.get('scene_title','Untitled')}', Beat: '{scene.get('emotional_beat','N/A')}', Asset: {scene.get('suggested_asset_type_감독','image')}):\n"
180
  f" Setting: {scene.get('setting_description','')}\n"
181
  f" Plot Beat: {scene.get('key_plot_beat','')}\n"
182
  f" Character Focus: {scene.get('character_focus_moment','(general atmosphere)')}\n"
 
188
  voice_style_description = {
189
  "cinematic_trailer": "deep, resonant, slightly epic, building anticipation, and authoritative.",
190
  "documentary_neutral": "clear, informative, objective, and well-paced.",
191
+ "introspective_character": f"reflective, personal, possibly first-person, echoing the thoughts of a key character."
192
  }[voice_style]
193
 
194
  prompt = f"""
195
+ You are an award-winning voiceover scriptwriter for a cinematic animatic.
196
+ The animatic uses a mix of still images and short video clips, based on these scene treatments:
197
 
198
  --- SCENE TREATMENTS ---
199
  {full_summary_text}
200
  --- END SCENE TREATMENTS ---
201
 
202
+ Overall Genre: {overall_genre}
203
+ Overall Mood: {overall_mood}
204
  Desired Voiceover Style: {voice_style} (Characteristics: {voice_style_description})
205
 
206
  Your narration script should:
207
+ - Weave a cohesive narrative through all scenes.
208
+ - Enhance emotional impact, drawing from 'emotional_beat', 'character_focus_moment', and 'sound_hint'.
209
+ - Be concise: 1-3 impactful sentences per scene. Total for {len(story_scenes_data)} scenes: approx {len(story_scenes_data) * 15}-{len(story_scenes_data) * 25} words.
210
+ - Transcend simple description; offer insight, build tension/emotion, evoke thematic depth.
211
+ - If 'introspective_character', write from one prominent character's perspective.
212
+ - The output MUST be ONLY the narration script text, ready for text-to-speech. No scene numbers, titles, or directives like "(Voiceover)".
213
 
214
+ Example (different story):
215
+ "Dust motes danced in the lone shaft of light. Each step echoed, a countdown. The air grew colder, heavy with ozone and ancient despair..."
216
 
217
+ Craft your narration.
218
  """
219
  return " ".join(prompt.split())
220
 
221
 
222
  def create_scene_regeneration_prompt(original_scene_data, user_feedback, full_story_context=None):
223
+ 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"
224
+ if full_story_context:
225
+ context_str += f"Full story context for reference (abbreviated):\n"
226
+ for i, scene_ctx in enumerate(full_story_context):
227
+ context_str += f" Scene {scene_ctx.get('scene_number', i+1)} Title: {scene_ctx.get('scene_title', 'Untitled')}, Plot: {scene_ctx.get('key_plot_beat', '')[:50]}...\n"
228
+ context_str += "\n"
229
+
230
 
231
  return f"""
232
  You are an AI Script Supervisor and Creative Consultant.
 
234
  User Feedback for this scene: "{user_feedback}"
235
 
236
  Regenerate ONLY the JSON object for this single scene, incorporating the feedback.
237
+ Maintain the exact 16 field structure:
238
+ (scene_number, scene_title, emotional_beat, setting_description, characters_involved, character_focus_moment, key_plot_beat, suggested_dialogue_hook, PROACTIVE_visual_style_감독, PROACTIVE_camera_work_감독, PROACTIVE_sound_design_감독, suggested_asset_type_감독, video_clip_motion_description_감독, video_clip_duration_estimate_secs_감독, image_generation_keywords_감독, pexels_search_query_감독).
239
+
240
+ Key considerations:
241
+ - 'scene_number' MUST NOT change.
242
+ - 'key_plot_beat' should be a concise descriptive sentence (max 15-20 words).
243
+ - 'image_generation_keywords_감독' should be updated to reflect any visual changes.
244
+ - 'pexels_search_query_감독' should also be updated if the setting or mood changes significantly.
245
+ - If feedback implies changes to motion or asset type, update 'suggested_asset_type_감독', 'video_clip_motion_description_감독', and 'video_clip_duration_estimate_secs_감독' accordingly. For 'video_clip_motion_description_감독', if type is 'image', set to "N/A". For 'video_clip_duration_estimate_secs_감독', if type is 'image', set to 0.
246
+ - If the user's feedback implies experimental narrative changes and the original scene had a `director_note`, you may update or remove it. If introducing a new experimental twist, add/update the `director_note` field.
247
+
248
+ Output only the single, updated JSON object for this scene.
249
  """
250
 
251
  def create_visual_regeneration_prompt(original_dalle_prompt, user_feedback, scene_data, character_definitions=None, global_style_additions=""):
252
+ """
253
+ Creates a prompt for Gemini to refine an existing DALL-E prompt for an IMAGE.
254
+ """
255
  characters_involved_in_scene = scene_data.get('characters_involved', [])
256
+ current_scene_character_details = []
257
  if characters_involved_in_scene:
258
  for char_name_from_scene in characters_involved_in_scene:
259
  char_name_clean = char_name_from_scene.strip(); char_lookup_key = char_name_clean.lower()
260
+ if character_definitions and char_lookup_key in character_definitions:
261
  current_scene_character_details.append(f"{char_name_clean} (described as: {character_definitions[char_lookup_key]})")
262
  else: current_scene_character_details.append(char_name_clean)
263
  characters_narrative = f" Characters to feature: {', '.join(current_scene_character_details) if current_scene_character_details else 'None specifically detailed'}."
264
 
265
  full_prompt_for_gemini = f"""
266
+ You are an AI Art Director specializing in refining DALL-E 3 prompts for cinematic STILL IMAGES.
267
  The goal is to update an image prompt based on user feedback.
268
 
269
  Scene Context:
 
281
  User Feedback on the visual generated by the previous prompt:
282
  "{user_feedback}"
283
 
284
+ Your Task: Generate a NEW, revised DALL-E 3 prompt specifically for a STILL IMAGE.
285
  This new prompt must incorporate the user's feedback to achieve the desired visual changes.
286
  It should remain ultra-detailed, photorealistic, and highly cinematic.
287
+ The prompt should guide DALL-E 3 to create a stunning still image suitable for a film's concept art.
288
  Maintain core scene elements (setting, characters, plot beat) unless feedback explicitly asks to change them.
289
+ Translate feedback into concrete visual descriptions for a static image (lighting, color, composition, character appearance/pose, atmosphere).
290
  Reinforce character descriptions from the context if they are relevant to the feedback.
291
  The prompt should be a single block of text.
292