openfree commited on
Commit
bd1f9da
ยท
verified ยท
1 Parent(s): c1fd40d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +223 -105
app.py CHANGED
@@ -115,22 +115,38 @@ GENRE_TEMPLATES = {
115
  }
116
 
117
  # Screenplay stages definition
 
118
  SCREENPLAY_STAGES = [
119
- ("producer", "๐ŸŽฌ Producer: Concept Development & Market Analysis"),
120
- ("story_developer", "๐Ÿ“– Story Developer: Synopsis & Three-Act Structure"),
121
- ("character_designer", "๐Ÿ‘ฅ Character Designer: Cast & Relationships"),
122
- ("critic_structure", "๐Ÿ” Structure Critic: Story & Character Review"),
123
- ("scene_planner", "๐ŸŽฏ Scene Planner: Detailed Scene Breakdown"),
124
- ("screenwriter", "โœ๏ธ Screenwriter: Act 1 - Setup (25%)"),
125
- ("script_doctor", "๐Ÿ”ง Script Doctor: Act 1 Review & Polish"),
126
- ("screenwriter", "โœ๏ธ Screenwriter: Act 2A - Rising Action (25%)"),
127
- ("script_doctor", "๐Ÿ”ง Script Doctor: Act 2A Review & Polish"),
128
- ("screenwriter", "โœ๏ธ Screenwriter: Act 2B - Complications (25%)"),
129
- ("script_doctor", "๐Ÿ”ง Script Doctor: Act 2B Review & Polish"),
130
- ("screenwriter", "โœ๏ธ Screenwriter: Act 3 - Resolution (25%)"),
131
- ("final_reviewer", "๐ŸŽญ Final Review: Complete Screenplay Analysis"),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  ]
133
 
 
134
  # Save the Cat Beat Sheet
135
  SAVE_THE_CAT_BEATS = {
136
  1: "Opening Image (0-1%)",
@@ -382,13 +398,53 @@ class ScreenplayDatabase:
382
  conn.commit()
383
  return session_id
384
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385
  @staticmethod
386
  def save_stage(session_id: str, stage_number: int, stage_name: str,
387
  role: str, content: str, status: str = 'complete'):
388
  page_count = 0
389
  if role == "screenwriter" and content:
390
- # Estimate pages based on screenplay format (rough estimate)
391
- page_count = len(content.split('\n')) / 55 # ~55 lines per page
 
392
 
393
  with ScreenplayDatabase.get_db() as conn:
394
  cursor = conn.cursor()
@@ -401,14 +457,24 @@ class ScreenplayDatabase:
401
  ''', (session_id, stage_number, stage_name, role, content, page_count, status,
402
  content, page_count, status))
403
 
404
- # Update session info
405
- cursor.execute('''
406
- UPDATE screenplay_sessions
407
- SET current_stage = ?, updated_at = datetime('now')
408
- WHERE session_id = ?
409
- ''', (stage_number, session_id))
 
 
 
 
 
 
 
 
410
 
411
  conn.commit()
 
 
412
 
413
  @staticmethod
414
  def save_screenplay_bible(session_id: str, bible: ScreenplayBible):
@@ -450,19 +516,33 @@ class ScreenplayDatabase:
450
  )
451
  conn.commit()
452
 
 
453
  @staticmethod
454
  def get_screenplay_content(session_id: str) -> str:
455
- """Get complete screenplay content"""
456
  with ScreenplayDatabase.get_db() as conn:
 
457
  rows = conn.cursor().execute('''
458
  SELECT content FROM screenplay_stages
459
- WHERE session_id = ? AND role = 'screenwriter'
 
 
460
  ORDER BY stage_number
461
  ''', (session_id,)).fetchall()
462
 
463
  if rows:
464
  return '\n\n'.join(row['content'] for row in rows if row['content'])
 
 
 
 
 
 
 
 
465
  return ""
 
 
466
 
467
  @staticmethod
468
  def update_final_screenplay(session_id: str, final_screenplay: str, title: str, logline: str):
@@ -1060,17 +1140,22 @@ Plan each scene to advance story and develop character."""
1060
  def create_screenwriter_prompt(self, act: str, scene_breakdown: str,
1061
  characters: str, previous_acts: str,
1062
  screenplay_type: str, genre: str, language: str) -> str:
1063
- """Screenwriter prompt for actual screenplay pages"""
1064
 
1065
  act_pages = int(SCREENPLAY_LENGTHS[screenplay_type]['pages'] * 0.25)
 
 
 
 
1066
 
1067
  lang_prompts = {
1068
  "Korean": f"""๋‹น์‹ ์€ ํ”„๋กœ ์‹œ๋‚˜๋ฆฌ์˜ค ์ž‘๊ฐ€์ž…๋‹ˆ๋‹ค. {act}์„ ํ‘œ์ค€ ์‹œ๋‚˜๋ฆฌ์˜ค ํฌ๋งท์œผ๋กœ ์ž‘์„ฑํ•˜์„ธ์š”.
1069
-
1070
- **ํƒ€๊ฒŸ ๋ถ„๋Ÿ‰:** {act_pages}ํŽ˜์ด์ง€
 
1071
 
1072
  **์”ฌ ๋ธŒ๋ ˆ์ดํฌ๋‹ค์šด:**
1073
- {self._extract_act_scenes(scene_breakdown, act)}
1074
 
1075
  **์บ๋ฆญํ„ฐ ์ •๋ณด:**
1076
  {characters}
@@ -1078,46 +1163,51 @@ Plan each scene to advance story and develop character."""
1078
  **์ด์ „ ๋‚ด์šฉ:**
1079
  {previous_acts if previous_acts else "์ฒซ ๋ง‰์ž…๋‹ˆ๋‹ค."}
1080
 
1081
- **์‹œ๋‚˜๋ฆฌ์˜ค ํฌ๋งท ๊ทœ์น™:**
1082
-
1083
- 1. **์”ฌ ํ—ค๋”ฉ**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1084
  INT. ์žฅ์†Œ - ์‹œ๊ฐ„
1085
- EXT. ์žฅ์†Œ - ์‹œ๊ฐ„
1086
-
1087
- 2. **์•ก์…˜ ๋ผ์ธ**
1088
- - ํ˜„์žฌ ์‹œ์ œ ์‚ฌ์šฉ
1089
- - ์‹œ๊ฐ์ ์œผ๋กœ ๋ณด์ด๋Š” ๊ฒƒ๋งŒ ๋ฌ˜์‚ฌ
1090
- - 4์ค„ ์ดํ•˜๋กœ ์œ ์ง€
1091
- - ๊ฐ์ •์€ ํ–‰๋™์œผ๋กœ ํ‘œํ˜„
1092
-
1093
- 3. **์บ๋ฆญํ„ฐ ์†Œ๊ฐœ**
1094
- ์ฒซ ๋“ฑ์žฅ์‹œ: ์ด๋ฆ„๊ณผ ๊ฐ„๋‹จํ•œ ๋ฌ˜์‚ฌ
1095
-
1096
- 4. **๋Œ€ํ™”**
1097
  ์บ๋ฆญํ„ฐ๋ช…
1098
  (์ง€๋ฌธ)
1099
  ๋Œ€์‚ฌ
1100
 
1101
- 5. **์ค‘์š” ์›์น™**
1102
- - Show, don't tell
1103
- - ์„œ๋ธŒํ…์ŠคํŠธ ํ™œ์šฉ
1104
- - ์ž์—ฐ์Šค๋Ÿฌ์šด ๋Œ€ํ™”
1105
- - ์‹œ๊ฐ์  ์Šคํ† ๋ฆฌํ…”๋ง
1106
- - ํŽ˜์ด์ง€๋‹น 1๋ถ„ ๊ทœ์น™
1107
-
1108
- **{genre} ์žฅ๋ฅด ํŠน์„ฑ:**
1109
- - ๋Œ€ํ™” ๋น„์œจ: {GENRE_TEMPLATES[genre]['dialogue_ratio']*100}%
1110
- - ์”ฌ ๊ธธ์ด: {GENRE_TEMPLATES[genre]['scene_length']}
1111
- - ํ•ต์‹ฌ ์š”์†Œ: {', '.join(GENRE_TEMPLATES[genre]['key_elements'][:2])}
1112
 
1113
- ์ •ํ™•ํ•œ ํฌ๋งท๊ณผ ๋ชฐ์ž…๊ฐ ์žˆ๋Š” ์Šคํ† ๋ฆฌํ…”๋ง์œผ๋กœ ์ž‘์„ฑํ•˜์„ธ์š”.""",
1114
 
1115
- "English": f"""You are a professional screenwriter. Write {act} in standard screenplay format.
1116
-
1117
- **Target Length:** {act_pages} pages
1118
 
1119
  **Scene Breakdown:**
1120
- {self._extract_act_scenes(scene_breakdown, act)}
1121
 
1122
  **Character Info:**
1123
  {characters}
@@ -1125,43 +1215,49 @@ Plan each scene to advance story and develop character."""
1125
  **Previous Content:**
1126
  {previous_acts if previous_acts else "This is the first act."}
1127
 
1128
- **Screenplay Format Rules:**
1129
-
1130
- 1. **Scene Headings**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1131
  INT. LOCATION - TIME
1132
- EXT. LOCATION - TIME
1133
-
1134
- 2. **Action Lines**
1135
- - Present tense
1136
- - Only what's visually seen
1137
- - Keep under 4 lines
1138
- - Emotions through actions
1139
-
1140
- 3. **Character Intros**
1141
- First appearance: NAME with brief description
1142
-
1143
- 4. **Dialogue**
1144
  CHARACTER NAME
1145
  (parenthetical)
1146
  Dialogue
1147
 
1148
- 5. **Key Principles**
1149
- - Show, don't tell
1150
- - Use subtext
1151
- - Natural dialogue
1152
- - Visual storytelling
1153
- - One page = one minute
1154
-
1155
- **{genre} Genre Characteristics:**
1156
- - Dialogue Ratio: {GENRE_TEMPLATES[genre]['dialogue_ratio']*100}%
1157
- - Scene Length: {GENRE_TEMPLATES[genre]['scene_length']}
1158
- - Key Elements: {', '.join(GENRE_TEMPLATES[genre]['key_elements'][:2])}
1159
-
1160
- Write with proper format and engaging storytelling."""
1161
  }
1162
-
1163
  return lang_prompts.get(language, lang_prompts["English"])
1164
 
 
 
1165
  def create_script_doctor_prompt(self, act_content: str, act: str,
1166
  genre: str, language: str) -> str:
1167
  """Script doctor review and polish"""
@@ -1487,14 +1583,14 @@ Provide specific solutions for each issue."""
1487
  *messages
1488
  ]
1489
 
1490
- max_tokens = 15000 if role == "screenwriter" else 8000
1491
 
1492
  payload = {
1493
  "model": self.model_id,
1494
  "messages": full_messages,
1495
  "max_tokens": max_tokens,
1496
- "temperature": 0.7 if role in ["screenwriter", "script_doctor"] else 0.8,
1497
- "top_p": 0.9,
1498
  "presence_penalty": 0.3,
1499
  "frequency_penalty": 0.3,
1500
  "stream": True
@@ -1804,7 +1900,9 @@ You provide feedback that's critical yet encouraging."""
1804
  def get_stage_prompt(self, stage_idx: int, role: str, query: str,
1805
  screenplay_type: str, genre: str, language: str,
1806
  stages: List[Dict]) -> str:
1807
- """Generate stage-specific prompt"""
 
 
1808
  if stage_idx == 0: # Producer
1809
  return self.create_producer_prompt(query, screenplay_type, genre, language)
1810
 
@@ -1828,26 +1926,44 @@ You provide feedback that's critical yet encouraging."""
1828
  stages[1]["content"], stages[2]["content"], screenplay_type, genre, language
1829
  )
1830
 
1831
- # Screenwriter acts
1832
- if role == "screenwriter":
1833
- act_mapping = {5: "Act 1", 7: "Act 2A", 9: "Act 2B", 11: "Act 3"}
1834
- if stage_idx in act_mapping:
1835
- act = act_mapping[stage_idx]
 
 
 
 
 
 
 
 
 
 
 
1836
  previous_acts = self._get_previous_acts(stages, stage_idx)
1837
  return self.create_screenwriter_prompt(
1838
  act, stages[4]["content"], stages[2]["content"],
1839
  previous_acts, screenplay_type, genre, language
1840
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1841
 
1842
- # Script doctor reviews
1843
- if role == "script_doctor":
1844
- act_mapping = {6: "Act 1", 8: "Act 2A", 10: "Act 2B"}
1845
- if stage_idx in act_mapping:
1846
- act = act_mapping[stage_idx]
1847
- act_content = stages[stage_idx-1]["content"]
1848
- return self.create_script_doctor_prompt(act_content, act, genre, language)
1849
-
1850
- # Final reviewer
1851
  if role == "final_reviewer":
1852
  complete_screenplay = ScreenplayDatabase.get_screenplay_content(self.current_session_id)
1853
  return self.create_final_reviewer_prompt(
@@ -1855,6 +1971,8 @@ You provide feedback that's critical yet encouraging."""
1855
  )
1856
 
1857
  return ""
 
 
1858
 
1859
  def _get_previous_acts(self, stages: List[Dict], current_idx: int) -> str:
1860
  """Get previous acts content"""
 
115
  }
116
 
117
  # Screenplay stages definition
118
+ # Screenplay stages definition - Enhanced with expansion stages
119
  SCREENPLAY_STAGES = [
120
+ ("producer", "๐ŸŽฌ Producer: Concept Development & Market Analysis"),
121
+ ("story_developer", "๐Ÿ“– Story Developer: Synopsis & Three-Act Structure"),
122
+ ("character_designer", "๐Ÿ‘ฅ Character Designer: Cast & Relationships"),
123
+ ("critic_structure", "๐Ÿ” Structure Critic: Story & Character Review"),
124
+ ("scene_planner", "๐ŸŽฏ Scene Planner: Detailed Scene Breakdown"),
125
+
126
+ # Act 1 - 3 stages: Draft -> Review -> Expansion
127
+ ("screenwriter", "โœ๏ธ Screenwriter: Act 1 - Setup (25%) - First Draft"),
128
+ ("script_doctor", "๐Ÿ”ง Script Doctor: Act 1 Review & Expansion Notes"),
129
+ ("screenwriter", "โœ๏ธ Screenwriter: Act 1 - Expanded Final Version"),
130
+
131
+ # Act 2A - 3 stages
132
+ ("screenwriter", "โœ๏ธ Screenwriter: Act 2A - Rising Action (25%) - First Draft"),
133
+ ("script_doctor", "๐Ÿ”ง Script Doctor: Act 2A Review & Expansion Notes"),
134
+ ("screenwriter", "โœ๏ธ Screenwriter: Act 2A - Expanded Final Version"),
135
+
136
+ # Act 2B - 3 stages
137
+ ("screenwriter", "โœ๏ธ Screenwriter: Act 2B - Complications (25%) - First Draft"),
138
+ ("script_doctor", "๐Ÿ”ง Script Doctor: Act 2B Review & Expansion Notes"),
139
+ ("screenwriter", "โœ๏ธ Screenwriter: Act 2B - Expanded Final Version"),
140
+
141
+ # Act 3 - 3 stages
142
+ ("screenwriter", "โœ๏ธ Screenwriter: Act 3 - Resolution (25%) - First Draft"),
143
+ ("script_doctor", "๐Ÿ”ง Script Doctor: Act 3 Review & Expansion Notes"),
144
+ ("screenwriter", "โœ๏ธ Screenwriter: Act 3 - Expanded Final Version"),
145
+
146
+ ("final_reviewer", "๐ŸŽญ Final Review: Complete Screenplay Analysis"),
147
  ]
148
 
149
+
150
  # Save the Cat Beat Sheet
151
  SAVE_THE_CAT_BEATS = {
152
  1: "Opening Image (0-1%)",
 
398
  conn.commit()
399
  return session_id
400
 
401
+ # In ScreenplayDatabase.save_stage method, add page count tracking
402
+ @staticmethod
403
+ def save_stage(session_id: str, stage_number: int, stage_name: str,
404
+ role: str, content: str, status: str = 'complete'):
405
+ page_count = 0
406
+ if role == "screenwriter" and content:
407
+ # Use the accurate page calculation
408
+ system = ScreenplayGenerationSystem()
409
+ page_count = system.calculate_screenplay_pages(content)
410
+
411
+ with ScreenplayDatabase.get_db() as conn:
412
+ cursor = conn.cursor()
413
+ cursor.execute('''
414
+ INSERT INTO screenplay_stages
415
+ (session_id, stage_number, stage_name, role, content, page_count, status)
416
+ VALUES (?, ?, ?, ?, ?, ?, ?)
417
+ ON CONFLICT(session_id, stage_number)
418
+ DO UPDATE SET content=?, page_count=?, status=?, updated_at=datetime('now')
419
+ ''', (session_id, stage_number, stage_name, role, content, page_count, status,
420
+ content, page_count, status))
421
+
422
+ # Update total pages in session
423
+ if role == "screenwriter" and "Expanded" in stage_name:
424
+ cursor.execute('''
425
+ UPDATE screenplay_sessions
426
+ SET total_pages = (
427
+ SELECT SUM(page_count)
428
+ FROM screenplay_stages
429
+ WHERE session_id = ?
430
+ AND role = 'screenwriter'
431
+ AND stage_name LIKE '%Expanded%'
432
+ ),
433
+ updated_at = datetime('now')
434
+ WHERE session_id = ?
435
+ ''', (session_id, session_id))
436
+
437
+ conn.commit()# In ScreenplayDatabase.save_stage method, add page count tracking
438
+
439
+
440
  @staticmethod
441
  def save_stage(session_id: str, stage_number: int, stage_name: str,
442
  role: str, content: str, status: str = 'complete'):
443
  page_count = 0
444
  if role == "screenwriter" and content:
445
+ # Use the accurate page calculation
446
+ system = ScreenplayGenerationSystem()
447
+ page_count = system.calculate_screenplay_pages(content)
448
 
449
  with ScreenplayDatabase.get_db() as conn:
450
  cursor = conn.cursor()
 
457
  ''', (session_id, stage_number, stage_name, role, content, page_count, status,
458
  content, page_count, status))
459
 
460
+ # Update total pages in session
461
+ if role == "screenwriter" and "Expanded" in stage_name:
462
+ cursor.execute('''
463
+ UPDATE screenplay_sessions
464
+ SET total_pages = (
465
+ SELECT SUM(page_count)
466
+ FROM screenplay_stages
467
+ WHERE session_id = ?
468
+ AND role = 'screenwriter'
469
+ AND stage_name LIKE '%Expanded%'
470
+ ),
471
+ updated_at = datetime('now')
472
+ WHERE session_id = ?
473
+ ''', (session_id, session_id))
474
 
475
  conn.commit()
476
+
477
+
478
 
479
  @staticmethod
480
  def save_screenplay_bible(session_id: str, bible: ScreenplayBible):
 
516
  )
517
  conn.commit()
518
 
519
+
520
  @staticmethod
521
  def get_screenplay_content(session_id: str) -> str:
522
+ """Get complete screenplay content - only expanded versions"""
523
  with ScreenplayDatabase.get_db() as conn:
524
+ # Get only the expanded final versions
525
  rows = conn.cursor().execute('''
526
  SELECT content FROM screenplay_stages
527
+ WHERE session_id = ?
528
+ AND role = 'screenwriter'
529
+ AND stage_name LIKE '%Expanded Final Version%'
530
  ORDER BY stage_number
531
  ''', (session_id,)).fetchall()
532
 
533
  if rows:
534
  return '\n\n'.join(row['content'] for row in rows if row['content'])
535
+ else:
536
+ # Fallback to any writer content
537
+ rows = conn.cursor().execute('''
538
+ SELECT content FROM screenplay_stages
539
+ WHERE session_id = ? AND role = 'screenwriter'
540
+ ORDER BY stage_number
541
+ ''', (session_id,)).fetchall()
542
+ return '\n\n'.join(row['content'] for row in rows if row['content'])
543
  return ""
544
+
545
+
546
 
547
  @staticmethod
548
  def update_final_screenplay(session_id: str, final_screenplay: str, title: str, logline: str):
 
1140
  def create_screenwriter_prompt(self, act: str, scene_breakdown: str,
1141
  characters: str, previous_acts: str,
1142
  screenplay_type: str, genre: str, language: str) -> str:
1143
+ """Enhanced screenwriter prompt with strict length requirements"""
1144
 
1145
  act_pages = int(SCREENPLAY_LENGTHS[screenplay_type]['pages'] * 0.25)
1146
+ min_lines = act_pages * 55 # 1 page = ~55 lines
1147
+
1148
+ # Extract detailed scene information for this act
1149
+ act_scenes = self._extract_act_scenes(scene_breakdown, act)
1150
 
1151
  lang_prompts = {
1152
  "Korean": f"""๋‹น์‹ ์€ ํ”„๋กœ ์‹œ๋‚˜๋ฆฌ์˜ค ์ž‘๊ฐ€์ž…๋‹ˆ๋‹ค. {act}์„ ํ‘œ์ค€ ์‹œ๋‚˜๋ฆฌ์˜ค ํฌ๋งท์œผ๋กœ ์ž‘์„ฑํ•˜์„ธ์š”.
1153
+
1154
+ **๋ชฉํ‘œ ๋ถ„๋Ÿ‰:** {act_pages}ํŽ˜์ด์ง€ (์ตœ์†Œ {min_lines}์ค„ ํ•„์ˆ˜)
1155
+ **์ ˆ๋Œ€ ๊ทœ์น™: {min_lines}์ค„ ๋ฏธ๋งŒ ์ž‘์„ฑ์‹œ ์‹คํŒจ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค.**
1156
 
1157
  **์”ฌ ๋ธŒ๋ ˆ์ดํฌ๋‹ค์šด:**
1158
+ {act_scenes}
1159
 
1160
  **์บ๋ฆญํ„ฐ ์ •๋ณด:**
1161
  {characters}
 
1163
  **์ด์ „ ๋‚ด์šฉ:**
1164
  {previous_acts if previous_acts else "์ฒซ ๋ง‰์ž…๋‹ˆ๋‹ค."}
1165
 
1166
+ **ํ•„์ˆ˜ ์ž‘์„ฑ ์š”๊ตฌ์‚ฌํ•ญ:**
1167
+
1168
+ 1. **๋ถ„๋Ÿ‰ ๋‹ฌ์„ฑ ์ „๋žต**
1169
+ - ๊ฐ ์”ฌ๋งˆ๋‹ค ์ตœ์†Œ 3-5ํŽ˜์ด์ง€ ํ• ๋‹น
1170
+ - ๋Œ€ํ™”: ์บ๋ฆญํ„ฐ๊ฐ„ ์ถฉ๋ถ„ํ•œ ๊ตํ™˜ (๊ฐ ๋Œ€ํ™” ์‹œํ€€์Šค 10-15์ค„)
1171
+ - ์•ก์…˜: ์ƒ์„ธํ•œ ์‹œ๊ฐ์  ๋ฌ˜์‚ฌ (๊ฐ ์•ก์…˜ ๋น„ํŠธ 3-5์ค„)
1172
+ - ์ „ํ™˜: ์”ฌ ์‚ฌ์ด ์ถฉ๋ถ„ํ•œ ๋ธŒ๋ฆฟ์ง€ ์žฅ๋ฉด
1173
+
1174
+ 2. **๋Œ€ํ™” ์ž‘์„ฑ ์ง€์นจ**
1175
+ - ์„œ๋ธŒํ…์ŠคํŠธ๊ฐ€ ํ’๋ถ€ํ•œ ๋Œ€ํ™”
1176
+ - ๊ฐˆ๋“ฑ์ด ์ ์ง„์ ์œผ๋กœ ๊ณ ์กฐ
1177
+ - ์บ๋ฆญํ„ฐ๋ณ„ ๊ณ ์œ ํ•œ ๋งํˆฌ์™€ ๋ฆฌ๋“ฌ
1178
+ - ์นจ๋ฌต๊ณผ ๋ฐ˜์‘์˜ ์ ์ ˆํ•œ ํ™œ์šฉ
1179
+ - ์ค‘์š”ํ•œ ์ •๋ณด๋Š” ๋Œ€ํ™”๋กœ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ
1180
+
1181
+ 3. **์•ก์…˜ ๋ผ์ธ ์ƒ์„ธํ™”**
1182
+ - ์žฅ์†Œ์˜ ๊ตฌ์ฒด์ ์ด๊ณ  ๋ถ„์œ„๊ธฐ ์žˆ๋Š” ๋ฌ˜์‚ฌ
1183
+ - ์บ๋ฆญํ„ฐ์˜ ๋ฏธ์„ธํ•œ ๋™์ž‘๊ณผ ํ‘œ์ • ํฌ์ฐฉ
1184
+ - ์‹œ๊ฐ„๋Œ€์™€ ๋‚ ์”จ, ์กฐ๋ช… ๋“ฑ ํ™˜๊ฒฝ ๋ฌ˜์‚ฌ
1185
+ - ์†Œํ’ˆ๊ณผ ์˜์ƒ ๋“ฑ ์‹œ๊ฐ์  ๋””ํ…Œ์ผ
1186
+
1187
+ 4. **{genre} ์žฅ๋ฅด ํŠนํ™” ์š”์†Œ**
1188
+ - ํŽ˜์ด์‹ฑ: {GENRE_TEMPLATES[genre]['pacing']}
1189
+ - ์”ฌ ๊ธธ์ด: {GENRE_TEMPLATES[genre]['scene_length']}
1190
+ - ํ•ต์‹ฌ ์š”์†Œ: {', '.join(GENRE_TEMPLATES[genre]['key_elements'])}
1191
+
1192
+ 5. **์‹œ๋‚˜๋ฆฌ์˜ค ํฌ๋งท ๊ทœ์น™**
1193
  INT. ์žฅ์†Œ - ์‹œ๊ฐ„
1194
+
1195
+ ์•ก์…˜ ๋ผ์ธ์€ ํ˜„์žฌ ์‹œ์ œ๋กœ ์ž‘์„ฑ.
1196
+ ์‹œ๊ฐ์ ์œผ๋กœ ๋ณด์ด๋Š” ๊ฒƒ๋งŒ ๋ฌ˜์‚ฌ.
1197
+
 
 
 
 
 
 
 
 
1198
  ์บ๋ฆญํ„ฐ๋ช…
1199
  (์ง€๋ฌธ)
1200
  ๋Œ€์‚ฌ
1201
 
1202
+ **๋ฐ˜๋“œ์‹œ {min_lines}์ค„ ์ด์ƒ ์ž‘์„ฑํ•˜์„ธ์š”. ๊ฐ ์”ฌ์„ ์ถฉ๋ถ„ํžˆ ์ „๊ฐœํ•˜๊ณ  ๋””ํ…Œ์ผ์„ ์‚ด๋ ค์ฃผ์„ธ์š”.**""",
 
 
 
 
 
 
 
 
 
 
1203
 
1204
+ "English": f"""You are a professional screenwriter. Write {act} in standard screenplay format.
1205
 
1206
+ **Target Length:** {act_pages} pages (MINIMUM {min_lines} lines required)
1207
+ **ABSOLUTE RULE: Writing less than {min_lines} lines is considered failure.**
 
1208
 
1209
  **Scene Breakdown:**
1210
+ {act_scenes}
1211
 
1212
  **Character Info:**
1213
  {characters}
 
1215
  **Previous Content:**
1216
  {previous_acts if previous_acts else "This is the first act."}
1217
 
1218
+ **Required Writing Elements:**
1219
+
1220
+ 1. **Volume Achievement Strategy**
1221
+ - Allocate minimum 3-5 pages per scene
1222
+ - Dialogue: Sufficient exchanges (10-15 lines per sequence)
1223
+ - Action: Detailed visual descriptions (3-5 lines per beat)
1224
+ - Transitions: Adequate bridge scenes between
1225
+
1226
+ 2. **Dialogue Guidelines**
1227
+ - Rich subtext in conversations
1228
+ - Gradually escalating conflict
1229
+ - Unique voice and rhythm per character
1230
+ - Appropriate use of pauses and reactions
1231
+ - Important information through natural dialogue
1232
+
1233
+ 3. **Action Line Details**
1234
+ - Specific atmospheric location descriptions
1235
+ - Subtle character movements and expressions
1236
+ - Time, weather, lighting environment
1237
+ - Props and costume visual details
1238
+
1239
+ 4. **{genre} Genre Elements**
1240
+ - Pacing: {GENRE_TEMPLATES[genre]['pacing']}
1241
+ - Scene Length: {GENRE_TEMPLATES[genre]['scene_length']}
1242
+ - Key Elements: {', '.join(GENRE_TEMPLATES[genre]['key_elements'])}
1243
+
1244
+ 5. **Screenplay Format Rules**
1245
  INT. LOCATION - TIME
1246
+
1247
+ Action lines in present tense.
1248
+ Only what's visually seen.
1249
+
 
 
 
 
 
 
 
 
1250
  CHARACTER NAME
1251
  (parenthetical)
1252
  Dialogue
1253
 
1254
+ **MUST write {min_lines}+ lines. Fully develop each scene with rich details.**"""
 
 
 
 
 
 
 
 
 
 
 
 
1255
  }
1256
+
1257
  return lang_prompts.get(language, lang_prompts["English"])
1258
 
1259
+
1260
+
1261
  def create_script_doctor_prompt(self, act_content: str, act: str,
1262
  genre: str, language: str) -> str:
1263
  """Script doctor review and polish"""
 
1583
  *messages
1584
  ]
1585
 
1586
+ max_tokens = 25000 if role == "screenwriter" else 15000
1587
 
1588
  payload = {
1589
  "model": self.model_id,
1590
  "messages": full_messages,
1591
  "max_tokens": max_tokens,
1592
+ "temperature": 0.8 if role in ["screenwriter", "script_doctor"] else 0.7,
1593
+ "top_p": 0.95,
1594
  "presence_penalty": 0.3,
1595
  "frequency_penalty": 0.3,
1596
  "stream": True
 
1900
  def get_stage_prompt(self, stage_idx: int, role: str, query: str,
1901
  screenplay_type: str, genre: str, language: str,
1902
  stages: List[Dict]) -> str:
1903
+ """Generate stage-specific prompt - Enhanced for expansion stages"""
1904
+
1905
+ # Initial stages (0-4)
1906
  if stage_idx == 0: # Producer
1907
  return self.create_producer_prompt(query, screenplay_type, genre, language)
1908
 
 
1926
  stages[1]["content"], stages[2]["content"], screenplay_type, genre, language
1927
  )
1928
 
1929
+ # Act writing stages (5-16)
1930
+ # Act 1: stages 5-7, Act 2A: 8-10, Act 2B: 11-13, Act 3: 14-16
1931
+
1932
+ # Determine which act and phase
1933
+ act_stages = {
1934
+ 5: ("Act 1", "draft"), 6: ("Act 1", "review"), 7: ("Act 1", "expand"),
1935
+ 8: ("Act 2A", "draft"), 9: ("Act 2A", "review"), 10: ("Act 2A", "expand"),
1936
+ 11: ("Act 2B", "draft"), 12: ("Act 2B", "review"), 13: ("Act 2B", "expand"),
1937
+ 14: ("Act 3", "draft"), 15: ("Act 3", "review"), 16: ("Act 3", "expand"),
1938
+ }
1939
+
1940
+ if stage_idx in act_stages:
1941
+ act, phase = act_stages[stage_idx]
1942
+
1943
+ if phase == "draft":
1944
+ # First draft writing
1945
  previous_acts = self._get_previous_acts(stages, stage_idx)
1946
  return self.create_screenwriter_prompt(
1947
  act, stages[4]["content"], stages[2]["content"],
1948
  previous_acts, screenplay_type, genre, language
1949
  )
1950
+
1951
+ elif phase == "review":
1952
+ # Script doctor review for expansion
1953
+ draft_content = stages[stage_idx-1]["content"]
1954
+ return self.create_script_doctor_expansion_prompt(
1955
+ draft_content, act, screenplay_type, genre, language
1956
+ )
1957
+
1958
+ elif phase == "expand":
1959
+ # Expanded rewrite
1960
+ original_content = stages[stage_idx-2]["content"] # Original draft
1961
+ expansion_notes = stages[stage_idx-1]["content"] # Review notes
1962
+ return self.create_expansion_writer_prompt(
1963
+ act, original_content, expansion_notes, screenplay_type, language
1964
+ )
1965
 
1966
+ # Final reviewer (stage 17)
 
 
 
 
 
 
 
 
1967
  if role == "final_reviewer":
1968
  complete_screenplay = ScreenplayDatabase.get_screenplay_content(self.current_session_id)
1969
  return self.create_final_reviewer_prompt(
 
1971
  )
1972
 
1973
  return ""
1974
+
1975
+
1976
 
1977
  def _get_previous_acts(self, stages: List[Dict], current_idx: int) -> str:
1978
  """Get previous acts content"""