openfree commited on
Commit
de06f60
ยท
verified ยท
1 Parent(s): 7da37b6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +236 -38
app.py CHANGED
@@ -276,12 +276,51 @@ class LiteraryQualityEnhancer:
276
  "couldn't breathe"
277
  ]
278
 
279
- def enhance_prompt(self, base_prompt: str, role: str, chapter: int) -> str:
280
  """๋ฌธํ•™์  ํ’ˆ์งˆ ํ–ฅ์ƒ์„ ์œ„ํ•œ ํ”„๋กฌํ”„ํŠธ ๊ฐ•ํ™”"""
281
 
282
- literary_guidelines = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  \n=== LITERARY QUALITY REQUIREMENTS ===
284
 
 
 
285
  1. **SENSORY IMMERSION**
286
  - Use all five senses in descriptions
287
  - Example: Instead of "The explosion was loud"
@@ -314,7 +353,15 @@ class LiteraryQualityEnhancer:
314
  """.format(cliches=", ".join(self.cliche_patterns[:3]))
315
 
316
  if role.startswith("writer"):
317
- literary_guidelines += """
 
 
 
 
 
 
 
 
318
  \n7. **CHAPTER-SPECIFIC FOCUS**
319
  - Opening: Hook with sensory detail or intriguing action
320
  - Middle: Develop at least one meaningful character moment
@@ -1086,10 +1133,43 @@ Creatively incorporate the information from search results naturally into the no
1086
  """Enhanced Director AI initial prompt with deeper plot structure"""
1087
  base_prompt = self.create_director_initial_prompt(user_query, language)
1088
 
1089
- plot_structure_guide = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1090
 
1091
  === ENHANCED PLOT STRUCTURE DESIGN ===
1092
 
 
 
1093
  1. **Three-Act Structure with Character Arcs**
1094
  - Act 1 (Chapters 1-3): Setting establishment + Internal conflict introduction
1095
  - Act 2 First Half (Chapters 4-6): External conflict rising + Internal change beginning
@@ -1114,24 +1194,15 @@ Creatively incorporate the information from search results naturally into the no
1114
  - Moral Tension: Value conflicts
1115
  """
1116
 
1117
- if language == "Korean":
1118
- return base_prompt + plot_structure_guide.replace(
1119
- "Three-Act Structure", "3๋ง‰ ๊ตฌ์กฐ"
1120
- ).replace(
1121
- "Character Transformation", "์บ๋ฆญํ„ฐ ๋ณ€ํ™”"
1122
- ).replace(
1123
- "Theme Layering", "์ฃผ์ œ ๋ ˆ์ด์–ด๋ง"
1124
- ).replace(
1125
- "Tension Design", "๊ธด์žฅ๊ฐ ์„ค๊ณ„"
1126
- )
1127
- else:
1128
- return base_prompt + plot_structure_guide
1129
 
1130
  def create_director_initial_prompt(self, user_query: str, language: str = "English") -> str:
1131
  """Director AI initial prompt - Novel planning for 10 writers"""
1132
  if language == "Korean":
1133
  return f"""๋‹น์‹ ์€ 30ํŽ˜์ด์ง€ ๋ถ„๋Ÿ‰์˜ ์ค‘ํŽธ ์†Œ์„ค์„ ๊ธฐํšํ•˜๋Š” ๋ฌธํ•™ ๊ฐ๋…์ž์ž…๋‹ˆ๋‹ค.
1134
 
 
 
1135
  ์‚ฌ์šฉ์ž ์š”์ฒญ: {user_query}
1136
 
1137
  ๋‹ค์Œ ์š”์†Œ๋“ค์„ ์ฒด๊ณ„์ ์œผ๋กœ ๊ตฌ์„ฑํ•˜์—ฌ 30ํŽ˜์ด์ง€ ์ค‘ํŽธ ์†Œ์„ค์˜ ๊ธฐ์ดˆ๋ฅผ ๋งŒ๋“œ์„ธ์š”:
@@ -1167,6 +1238,8 @@ Creatively incorporate the information from search results naturally into the no
1167
  else:
1168
  return f"""You are a literary director planning a 30-page novella.
1169
 
 
 
1170
  User Request: {user_query}
1171
 
1172
  Systematically compose the following elements to create the foundation for a 30-page novella:
@@ -1204,10 +1277,38 @@ Provide clear guidelines for each writer to compose 3 pages."""
1204
  """Enhanced critic's review of director's plan"""
1205
  base_prompt = self.create_critic_director_prompt(director_plan, language)
1206
 
1207
- enhanced_criteria = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1208
 
1209
  === ENHANCED CRITIQUE CRITERIA ===
1210
 
 
 
1211
  **Literary Quality Assessment:**
1212
  1. Originality Score (1-10): How fresh and unique is this concept?
1213
  2. Emotional Resonance (1-10): Will readers connect emotionally?
@@ -1234,6 +1335,8 @@ Provide specific examples for each critique point.
1234
  if language == "Korean":
1235
  return f"""๋‹น์‹ ์€ ๋ฌธํ•™ ๋น„ํ‰๊ฐ€์ž…๋‹ˆ๋‹ค. ๊ฐ๋…์ž์˜ ์†Œ์„ค ๊ธฐํš์„ ๊ฒ€ํ† ํ•˜๊ณ  ๊ฐœ์„ ์ ์„ ์ œ์‹œํ•˜์„ธ์š”.
1236
 
 
 
1237
  ๊ฐ๋…์ž์˜ ๊ธฐํš:
1238
  {director_plan}
1239
 
@@ -1267,6 +1370,8 @@ Provide specific examples for each critique point.
1267
  else:
1268
  return f"""You are a literary critic. Review the director's novel plan and suggest improvements.
1269
 
 
 
1270
  Director's Plan:
1271
  {director_plan}
1272
 
@@ -1303,6 +1408,8 @@ Provide specific and constructive feedback."""
1303
  if language == "Korean":
1304
  return f"""๊ฐ๋…์ž๋กœ์„œ ๋น„ํ‰๊ฐ€์˜ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ˜์˜ํ•˜์—ฌ ์†Œ์„ค ๊ธฐํš์„ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
1305
 
 
 
1306
  ์ดˆ๊ธฐ ๊ธฐํš:
1307
  {initial_plan}
1308
 
@@ -1341,6 +1448,8 @@ Provide specific and constructive feedback."""
1341
  else:
1342
  return f"""As director, revise the novel plan reflecting the critic's feedback.
1343
 
 
 
1344
  Initial Plan:
1345
  {initial_plan}
1346
 
@@ -1385,15 +1494,26 @@ Create a final masterplan that all 10 writers can clearly understand."""
1385
  # Add character context
1386
  character_context = self.state_tracker.get_character_context(writer_number)
1387
 
1388
- # Add literary enhancement
1389
- literary_guidelines = self.literary_enhancer.enhance_prompt(base_prompt, f"writer{writer_number}", writer_number)
1390
 
1391
  # Combine all elements
1392
  enhanced_prompt = base_prompt + character_context + literary_guidelines
1393
 
1394
  if writer_number > 1:
1395
  # Add consistency reminder
1396
- consistency_reminder = """
 
 
 
 
 
 
 
 
 
 
 
1397
 
1398
  === CONSISTENCY REQUIREMENTS ===
1399
  You MUST maintain consistency with previous chapters:
@@ -1414,6 +1534,8 @@ You MUST maintain consistency with previous chapters:
1414
  if language == "Korean":
1415
  return f"""๋‹น์‹ ์€ ์ž‘์„ฑ์ž {writer_number}๋ฒˆ์ž…๋‹ˆ๋‹ค. 30ํŽ˜์ด์ง€ ์ค‘ํŽธ ์†Œ์„ค์˜ {pages_start}-{pages_end}ํŽ˜์ด์ง€(3ํŽ˜์ด์ง€)๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”.
1416
 
 
 
1417
  ๊ฐ๋…์ž์˜ ๋งˆ์Šคํ„ฐํ”Œ๋žœ:
1418
  {director_plan}
1419
 
@@ -1445,10 +1567,12 @@ You MUST maintain consistency with previous chapters:
1445
  - ๋…์ž์˜ ๊ด€์‹ฌ ์œ ์ง€
1446
 
1447
  **์ž‘์„ฑ ์‹œ์ž‘:**
1448
- ์ด์ œ 1,400-1,500๋‹จ์–ด ๋ถ„๋Ÿ‰์˜ ์†Œ์„ค์„ ์ž‘์„ฑํ•˜์„ธ์š”. ํŽ˜์ด์ง€ ๊ตฌ๋ถ„ ํ‘œ์‹œ๋Š” ํ•˜์ง€ ๋งˆ์„ธ์š”."""
1449
  else:
1450
  return f"""You are Writer #{writer_number}. Write pages {pages_start}-{pages_end} (3 pages) of the 30-page novella.
1451
 
 
 
1452
  Director's Masterplan:
1453
  {director_plan}
1454
 
@@ -1480,7 +1604,7 @@ Director's Masterplan:
1480
  - Maintain reader interest
1481
 
1482
  **BEGIN WRITING:**
1483
- Now write your 1,400-1,500 word section. Do not use any page markers."""
1484
 
1485
  def create_enhanced_critic_writer_prompt(self, writer_number: int, writer_content: str,
1486
  director_plan: str, all_previous_content: str,
@@ -1495,15 +1619,38 @@ Now write your 1,400-1,500 word section. Do not use any page markers."""
1495
  # Get quality scores
1496
  quality_scores = self.quality_scorer.score_content(writer_content, self.state_tracker, writer_number)
1497
 
1498
- consistency_section = f"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1499
 
1500
  === CONSISTENCY VALIDATION RESULTS ===
1501
  {'No consistency errors detected.' if not consistency_errors else 'CRITICAL ERRORS FOUND:'}
1502
  """
1503
- for error in consistency_errors:
1504
- consistency_section += f"- {error}\n"
1505
-
1506
- quality_section = f"""
1507
 
1508
  === QUALITY ASSESSMENT ===
1509
  Literary Quality: {quality_scores['literary_quality']:.1f}/10
@@ -1513,6 +1660,8 @@ Originality: {quality_scores['originality']:.1f}/10
1513
  Pacing: {quality_scores['pacing']:.1f}/10
1514
 
1515
  Overall Score: {sum(quality_scores.values())/len(quality_scores):.1f}/10
 
 
1516
  """
1517
 
1518
  return base_prompt + consistency_section + quality_section
@@ -1522,6 +1671,8 @@ Overall Score: {sum(quality_scores.values())/len(quality_scores):.1f}/10
1522
  if language == "Korean":
1523
  return f"""์ž‘์„ฑ์ž {writer_number}๋ฒˆ์˜ ์ž‘ํ’ˆ์„ ๋น„ํ‰ํ•ฉ๋‹ˆ๋‹ค.
1524
 
 
 
1525
  ๊ฐ๋…์ž์˜ ๋งˆ์Šคํ„ฐํ”Œ๋žœ:
1526
  {director_plan}
1527
 
@@ -1564,6 +1715,8 @@ Overall Score: {sum(quality_scores.values())/len(quality_scores):.1f}/10
1564
  else:
1565
  return f"""Critiquing Writer #{writer_number}'s work.
1566
 
 
 
1567
  Director's Masterplan:
1568
  {director_plan}
1569
 
@@ -1609,6 +1762,8 @@ Clearly distinguish between mandatory revisions and optional improvements."""
1609
  if language == "Korean":
1610
  return f"""์ž‘์„ฑ์ž {writer_number}๋ฒˆ์œผ๋กœ์„œ ๋น„ํ‰๊ฐ€์˜ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ˜์˜ํ•˜์—ฌ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
1611
 
 
 
1612
  ์ดˆ๊ธฐ ์ž‘์„ฑ ๋‚ด์šฉ:
1613
  {initial_content}
1614
 
@@ -1635,11 +1790,13 @@ Clearly distinguish between mandatory revisions and optional improvements."""
1635
  - ์ด์ „/์ดํ›„ ๋‚ด์šฉ๊ณผ์˜ ์ž์—ฐ์Šค๋Ÿฌ์šด ์—ฐ๊ฒฐ
1636
  - ์ˆ˜์ •์œผ๋กœ ์ธํ•œ ์ƒˆ๋กœ์šด ๋ชจ์ˆœ ๋ฐฉ์ง€
1637
 
1638
- ์ˆ˜์ •๋œ ์ตœ์ข…๋ณธ์„ ์ œ์‹œํ•˜์„ธ์š”. ํŽ˜์ด์ง€ ๋งˆํฌ๋Š” ์ ˆ๋Œ€ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”.
1639
  ๋ฐ˜๋“œ์‹œ 1,400-1,500๋‹จ์–ด ๋ถ„๋Ÿ‰์„ ์œ ์ง€ํ•˜์„ธ์š”."""
1640
  else:
1641
  return f"""As Writer #{writer_number}, revise based on critic's feedback.
1642
 
 
 
1643
  Initial Content:
1644
  {initial_content}
1645
 
@@ -1666,7 +1823,7 @@ Write a revision reflecting:
1666
  - Natural connection with previous/next content
1667
  - Prevent new contradictions from revisions
1668
 
1669
- Present the revised final version. Never use page markers.
1670
  You MUST maintain 1,400-1,500 words."""
1671
 
1672
  def create_test_writer_remaining_prompt(self, director_plan: str, writer1_content: str, language: str) -> str:
@@ -1674,6 +1831,8 @@ You MUST maintain 1,400-1,500 words."""
1674
  if language == "Korean":
1675
  return f"""[ํ…Œ์ŠคํŠธ ๋ชจ๋“œ] ๋‹น์‹ ์€ ๋‚˜๋จธ์ง€ 9๊ฐœ ์ฑ•ํ„ฐ(Chapter 2-10)๋ฅผ ์ž‘์„ฑํ•˜๋Š” ํŠน๋ณ„ ์ž‘๊ฐ€์ž…๋‹ˆ๋‹ค.
1676
 
 
 
1677
  ๊ฐ๋…์ž์˜ ๋งˆ์Šคํ„ฐํ”Œ๋žœ:
1678
  {director_plan}
1679
 
@@ -1686,24 +1845,27 @@ You MUST maintain 1,400-1,500 words."""
1686
  3. ์ด 12,600-13,500 ๋‹จ์–ด (9๊ฐœ ์ฑ•ํ„ฐ)
1687
  4. Chapter 1๊ณผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ด์–ด์ง€๋„๋ก ์ž‘์„ฑํ•˜์„ธ์š”
1688
  5. ๋งˆ์Šคํ„ฐํ”Œ๋žœ์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ํฌํ•จํ•˜์—ฌ ์™„๊ฒฐ๋œ ์ด์•ผ๊ธฐ๋ฅผ ๋งŒ๋“œ์„ธ์š”
 
1689
 
1690
  **ํ•„์ˆ˜ ํ˜•์‹:**
1691
  ๋ฐ˜๋“œ์‹œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ฑ•ํ„ฐ๋ฅผ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„ํ•˜์„ธ์š”:
1692
 
1693
  [Chapter 2]
1694
- (1,400-1,500 ๋‹จ์–ด์˜ ๋‚ด์šฉ)
1695
 
1696
  [Chapter 3]
1697
- (1,400-1,500 ๋‹จ์–ด์˜ ๋‚ด์šฉ)
1698
 
1699
  ...์ด๋Ÿฐ ์‹์œผ๋กœ [Chapter 10]๊นŒ์ง€...
1700
 
1701
  ๊ฐ ์ฑ•ํ„ฐ๋Š” ๋ฐ˜๋“œ์‹œ [Chapter ์ˆซ์ž] ํ˜•์‹์œผ๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
1702
  ์ฑ•ํ„ฐ ์‚ฌ์ด์—๋Š” ๋นˆ ์ค„์„ ๋„ฃ์–ด ๊ตฌ๋ถ„ํ•˜์„ธ์š”.
1703
- Chapter 2๋ถ€ํ„ฐ 10๊นŒ์ง€ ์ž‘์„ฑํ•˜์„ธ์š”."""
1704
  else:
1705
  return f"""[TEST MODE] You are a special writer creating the remaining 9 chapters (Chapters 2-10).
1706
 
 
 
1707
  Director's Masterplan:
1708
  {director_plan}
1709
 
@@ -1716,21 +1878,22 @@ Writer 1 has already written Chapter 1:
1716
  3. Total 12,600-13,500 words (9 chapters)
1717
  4. Continue naturally from Chapter 1
1718
  5. Include all elements from the masterplan to create a complete story
 
1719
 
1720
  **MANDATORY FORMAT:**
1721
  You MUST clearly separate chapters as follows:
1722
 
1723
  [Chapter 2]
1724
- (1,400-1,500 words of content)
1725
 
1726
  [Chapter 3]
1727
- (1,400-1,500 words of content)
1728
 
1729
  ...continue this way until [Chapter 10]...
1730
 
1731
  Each chapter MUST start with [Chapter number] format.
1732
  Leave blank lines between chapters for separation.
1733
- Write Chapters 2-10 now."""
1734
 
1735
  def simulate_streaming(self, text: str, role: str) -> Generator[str, None, None]:
1736
  """Simulate streaming in test mode"""
@@ -1780,12 +1943,18 @@ Write Chapters 2-10 now."""
1780
  # Enhanced system prompt for writers
1781
  if role.startswith("writer"):
1782
  if language == "Korean":
1783
- system_prompts[role] += "\n\n**์ ˆ๋Œ€์  ์š”๊ตฌ์‚ฌํ•ญ**: ๋‹น์‹ ์€ ๋ฐ˜๋“œ์‹œ 1,400-1,500๋‹จ์–ด๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํ˜‘์ƒ ๋ถˆ๊ฐ€๋Šฅํ•œ ์š”๊ตฌ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค."
1784
  else:
1785
  system_prompts[role] += "\n\n**ABSOLUTE REQUIREMENT**: You MUST write 1,400-1,500 words. This is non-negotiable."
1786
 
 
 
 
 
 
 
1787
  full_messages = [
1788
- {"role": "system", "content": system_prompts.get(role, "")},
1789
  *messages
1790
  ]
1791
 
@@ -1803,6 +1972,12 @@ Write Chapters 2-10 now."""
1803
  temperature = 0.6
1804
  top_p = 0.9
1805
 
 
 
 
 
 
 
1806
  payload = {
1807
  "model": self.model_id,
1808
  "messages": full_messages,
@@ -1813,7 +1988,18 @@ Write Chapters 2-10 now."""
1813
  "stream_options": {"include_usage": True}
1814
  }
1815
 
1816
- logger.info(f"API streaming call started - Role: {role}, Max tokens: {max_tokens}")
 
 
 
 
 
 
 
 
 
 
 
1817
 
1818
  response = requests.post(
1819
  self.api_url,
@@ -2291,6 +2477,14 @@ Five years ago, her younger sister Seojin had died in a car accident. The memory
2291
  # Get appropriate prompt based on stage
2292
  prompt = self.get_stage_prompt(stage_idx, role, query, language, stages, test_quick_mode)
2293
 
 
 
 
 
 
 
 
 
2294
  # Create stage info for web search and validation
2295
  stage_info = {
2296
  'stage_idx': stage_idx,
@@ -2455,6 +2649,8 @@ Five years ago, her younger sister Seojin had died in a car accident. The memory
2455
  def get_stage_prompt(self, stage_idx: int, role: str, query: str,
2456
  language: str, stages: List[Dict], test_mode: bool = False) -> str:
2457
  """Get appropriate prompt for each stage with enhancements"""
 
 
2458
  # Stage 0: Director Initial
2459
  if stage_idx == 0:
2460
  return self.create_enhanced_director_initial_prompt(query, language)
@@ -2487,11 +2683,13 @@ Five years ago, her younger sister Seojin had died in a car accident. The memory
2487
  if "์ดˆ์•ˆ" in stages[stage_idx]["name"] or "Draft" in stages[stage_idx]["name"]:
2488
  # Get accumulated content from DB
2489
  accumulated_content = NovelDatabase.get_all_writer_content(self.current_session_id)
 
2490
  return self.create_enhanced_writer_prompt(writer_num, final_plan, accumulated_content, language)
2491
  else: # Revision
2492
  # Find the initial draft and critic feedback
2493
  initial_draft_idx = stage_idx - 2
2494
  critic_feedback_idx = stage_idx - 1
 
2495
  return self.create_writer_revision_prompt(
2496
  writer_num,
2497
  stages[initial_draft_idx]["content"],
 
276
  "couldn't breathe"
277
  ]
278
 
279
+ def enhance_prompt(self, base_prompt: str, role: str, chapter: int, language: str = "English") -> str:
280
  """๋ฌธํ•™์  ํ’ˆ์งˆ ํ–ฅ์ƒ์„ ์œ„ํ•œ ํ”„๋กฌํ”„ํŠธ ๊ฐ•ํ™”"""
281
 
282
+ if language == "Korean":
283
+ literary_guidelines = """
284
+ \n=== ๋ฌธํ•™์  ํ’ˆ์งˆ ์š”๊ตฌ์‚ฌํ•ญ ===
285
+
286
+ **๋ฐ˜๋“œ์‹œ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”. ์˜์–ด ์‚ฌ์šฉ์€ ์ ˆ๋Œ€ ๊ธˆ์ง€์ž…๋‹ˆ๋‹ค.**
287
+
288
+ 1. **๊ฐ๊ฐ์  ๋ชฐ์ž…**
289
+ - ์˜ค๊ฐ์„ ๋ชจ๋‘ ํ™œ์šฉํ•œ ๋ฌ˜์‚ฌ
290
+ - ์˜ˆ์‹œ: "ํญ๋ฐœ์Œ์ด ์ปธ๋‹ค" ๋Œ€์‹ 
291
+ โ†’ "ํญ๋ฐœ์ด ๊ณต๊ธฐ๋ฅผ ์ฐข์œผ๋ฉฐ ๊ณ ๋ง‰์„ ์••๋ฐ•ํ–ˆ๊ณ , ๋งค์บํ•œ ์—ฐ๊ธฐ๊ฐ€ ์ฝง์†์„ ์ฐ”๋ €์œผ๋ฉฐ
292
+ ๋œจ๊ฑฐ์šด ํŒŒํŽธ์ด ํ”ผ๋ถ€๋ฅผ ์Šค์ณค๋‹ค"
293
+
294
+ 2. **๊ฐ์ •์  ๊นŠ์ด**
295
+ - ์‹ ์ฒด ๋ฐ˜์‘๊ณผ ๋‚ด์  ๋…๋ฐฑ์„ ํ†ตํ•œ ๊ฐ์ • ํ‘œํ˜„
296
+ - "๊ทธ๋Š” ์Šฌํސ๋‹ค"์™€ ๊ฐ™์€ ์ง์ ‘์  ๊ฐ์ • ์„œ์ˆ  ๊ธˆ์ง€
297
+ - ๋ชธ์ง“, ์ƒ๊ฐ, ๊ธฐ์–ต ํ™œ์šฉ
298
+
299
+ 3. **๊ณ ์œ ํ•œ ๋ชฉ์†Œ๋ฆฌ**
300
+ - ๊ฐ ์ธ๋ฌผ๋งˆ๋‹ค ๋…ํŠนํ•œ ๋งํˆฌ ์‚ฌ์šฉ
301
+ - ๋Œ€ํ™” ์† ์ˆจ๊ฒจ์ง„ ์˜๋ฏธ(subtext) ํ™œ์šฉ
302
+ - ์ž์—ฐ์Šค๋Ÿฌ์šด ์ค‘๋‹จ, ๋จธ๋ญ‡๊ฑฐ๋ฆผ, ๋ฐฉ์–ธ
303
+
304
+ 4. **๋ฆฌ๋“ฌ๊ณผ ์†๋„**
305
+ - ๋ฌธ์žฅ ๊ธธ์ด๋ฅผ ๋‹ค์–‘ํ•˜๊ฒŒ ๋ณ€ํ™”
306
+ - ๊ธด์žฅ๊ฐ: ์งง๊ณ  ๋‚ ์นด๋กœ์šด ๋ฌธ์žฅ
307
+ - ์„ฑ์ฐฐ: ๊ธธ๊ณ  ํ๋ฅด๋Š” ๋ฌธ์žฅ
308
+ - ๊ฐ•์กฐ๋ฅผ ์œ„ํ•œ ๋‹จ๋ฝ ๊ตฌ๋ถ„
309
+
310
+ 5. **ํด๋ฆฌ์…ฐ ๊ธˆ์ง€**
311
+ ์ ˆ๋Œ€ ์‚ฌ์šฉ ๊ธˆ์ง€: {cliches}
312
+
313
+ 6. **์ƒ์ง•๊ณผ ๋ชจํ‹ฐํ”„**
314
+ - ์ฃผ์ œ์™€ ์—ฐ๊ฒฐ๋œ ๋ฐ˜๋ณต ์ด๋ฏธ์ง€/์‚ฌ๋ฌผ
315
+ - ์ž์—ฐ ์š”์†Œ์™€ ๊ฐ์ • ์ƒํƒœ ์—ฐ๊ฒฐ
316
+ - ๊ณผํ•˜์ง€ ์•Š๊ฒŒ ์˜๋ฏธ ์ธต์œ„ ์Œ“๊ธฐ
317
+ """.format(cliches=", ".join(self.cliche_patterns[:3]))
318
+ else:
319
+ literary_guidelines = """
320
  \n=== LITERARY QUALITY REQUIREMENTS ===
321
 
322
+ **You must write in English.**
323
+
324
  1. **SENSORY IMMERSION**
325
  - Use all five senses in descriptions
326
  - Example: Instead of "The explosion was loud"
 
353
  """.format(cliches=", ".join(self.cliche_patterns[:3]))
354
 
355
  if role.startswith("writer"):
356
+ if language == "Korean":
357
+ literary_guidelines += """
358
+ \n7. **์ฑ•ํ„ฐ๋ณ„ ์ง‘์ค‘ ์‚ฌํ•ญ**
359
+ - ์‹œ์ž‘: ๊ฐ๊ฐ์  ๋””ํ…Œ์ผ์ด๋‚˜ ํฅ๋ฏธ๋กœ์šด ํ–‰๋™์œผ๋กœ ๋…์ž ์‚ฌ๋กœ์žก๊ธฐ
360
+ - ์ค‘๊ฐ„: ์ตœ์†Œ ํ•˜๋‚˜์˜ ์˜๋ฏธ ์žˆ๋Š” ์บ๋ฆญํ„ฐ ์ˆœ๊ฐ„ ๋ฐœ์ „์‹œํ‚ค๊ธฐ
361
+ - ๋: ์ง„๋ถ€ํ•œ ํด๋ฆฌํ”„ํ–‰์–ด ์—†์ด ๋‹ค์Œ ์ฑ•ํ„ฐ๋กœ์˜ ์ถ”์ง„๋ ฅ ์ƒ์„ฑ
362
+ """
363
+ else:
364
+ literary_guidelines += """
365
  \n7. **CHAPTER-SPECIFIC FOCUS**
366
  - Opening: Hook with sensory detail or intriguing action
367
  - Middle: Develop at least one meaningful character moment
 
1133
  """Enhanced Director AI initial prompt with deeper plot structure"""
1134
  base_prompt = self.create_director_initial_prompt(user_query, language)
1135
 
1136
+ if language == "Korean":
1137
+ plot_structure_guide = """
1138
+
1139
+ === ๊ฐ•ํ™”๋œ ํ”Œ๋กฏ ๊ตฌ์กฐ ์„ค๊ณ„ ===
1140
+
1141
+ **๋ชจ๋“  ๋‚ด์šฉ์„ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”.**
1142
+
1143
+ 1. **์บ๋ฆญํ„ฐ ์•„ํฌ๋ฅผ ํฌํ•จํ•œ 3๋ง‰ ๊ตฌ์กฐ**
1144
+ - 1๋ง‰ (์ฑ•ํ„ฐ 1-3): ์„ค์ • ํ™•๋ฆฝ + ๋‚ด์  ๊ฐˆ๋“ฑ ๋„์ž…
1145
+ - 2๋ง‰ ์ „๋ฐ˜๋ถ€ (์ฑ•ํ„ฐ 4-6): ์™ธ์  ๊ฐˆ๋“ฑ ์ƒ์Šน + ๋‚ด์  ๋ณ€ํ™” ์‹œ์ž‘
1146
+ - 2๋ง‰ ํ›„๋ฐ˜๋ถ€ (์ฑ•ํ„ฐ 7-8): ์œ„๊ธฐ์˜ ์ •์  + ๊ฐ€์น˜๊ด€ ์ „ํ™˜
1147
+ - 3๋ง‰ (์ฑ•ํ„ฐ 9-10): ํด๋ผ์ด๋งฅ์Šค + ์ƒˆ๋กœ์šด ๊ท ํ˜•
1148
+
1149
+ 2. **์บ๋ฆญํ„ฐ ๋ณ€ํ™” ๊ถค์ **
1150
+ ๋ชจ๋“  ์ฃผ์š” ์บ๋ฆญํ„ฐ์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ์•„ํฌ ์ƒ์„ฑ:
1151
+ | ์บ๋ฆญํ„ฐ | ์‹œ์ž‘์  | ์ „ํ™˜์  | ๋„์ฐฉ์  |
1152
+ |--------|--------|--------|--------|
1153
+ | [์ด๋ฆ„] | [์‹ ๋…/๊ฒฐํ•] | [์‹œ๋ จ/๊นจ๋‹ฌ์Œ] | [์„ฑ์žฅ/ํ•ด๊ฒฐ] |
1154
+
1155
+ 3. **์ฃผ์ œ ๋ ˆ์ด์–ด๋ง**
1156
+ - ํ‘œ๋ฉด ์ฃผ์ œ: [์ด์•ผ๊ธฐ๊ฐ€ ๋ณด์ด๋Š” ์ฃผ์ œ]
1157
+ - ์‹ฌ์ธต ์ฃผ์ œ: [์ด์•ผ๊ธฐ์˜ ์ง„์งœ ์ฃผ์ œ]
1158
+ - ๊ฐœ์ธ ์ฃผ์ œ: [๊ฐ ์บ๋ฆญํ„ฐ์˜ ๋‚ด์  ์—ฌ์ •]
1159
+
1160
+ 4. **๊ธด์žฅ ์„ค๊ณ„**
1161
+ ์„ธ ๊ฐ€์ง€ ์œ ํ˜•์˜ ๊ธด์žฅ ๊ณก์„  ๊ณ„ํš:
1162
+ - ๋ฌผ๋ฆฌ์  ๊ธด์žฅ: ์ „ํˆฌ์™€ ์œ„ํ—˜
1163
+ - ๊ฐ์ •์  ๊ธด์žฅ: ๊ด€๊ณ„์™€ ์„ ํƒ
1164
+ - ๋„๋•์  ๊ธด์žฅ: ๊ฐ€์น˜๊ด€ ์ถฉ๋Œ
1165
+ """
1166
+ else:
1167
+ plot_structure_guide = """
1168
 
1169
  === ENHANCED PLOT STRUCTURE DESIGN ===
1170
 
1171
+ **Write all content in English.**
1172
+
1173
  1. **Three-Act Structure with Character Arcs**
1174
  - Act 1 (Chapters 1-3): Setting establishment + Internal conflict introduction
1175
  - Act 2 First Half (Chapters 4-6): External conflict rising + Internal change beginning
 
1194
  - Moral Tension: Value conflicts
1195
  """
1196
 
1197
+ return base_prompt + plot_structure_guide
 
 
 
 
 
 
 
 
 
 
 
1198
 
1199
  def create_director_initial_prompt(self, user_query: str, language: str = "English") -> str:
1200
  """Director AI initial prompt - Novel planning for 10 writers"""
1201
  if language == "Korean":
1202
  return f"""๋‹น์‹ ์€ 30ํŽ˜์ด์ง€ ๋ถ„๋Ÿ‰์˜ ์ค‘ํŽธ ์†Œ์„ค์„ ๊ธฐํšํ•˜๋Š” ๋ฌธํ•™ ๊ฐ๋…์ž์ž…๋‹ˆ๋‹ค.
1203
 
1204
+ **์–ธ์–ด ์„ค์ •: ๋ชจ๋“  ๋‚ด์šฉ์„ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”.**
1205
+
1206
  ์‚ฌ์šฉ์ž ์š”์ฒญ: {user_query}
1207
 
1208
  ๋‹ค์Œ ์š”์†Œ๋“ค์„ ์ฒด๊ณ„์ ์œผ๋กœ ๊ตฌ์„ฑํ•˜์—ฌ 30ํŽ˜์ด์ง€ ์ค‘ํŽธ ์†Œ์„ค์˜ ๊ธฐ์ดˆ๋ฅผ ๋งŒ๋“œ์„ธ์š”:
 
1238
  else:
1239
  return f"""You are a literary director planning a 30-page novella.
1240
 
1241
+ **Language Setting: Write all content in English.**
1242
+
1243
  User Request: {user_query}
1244
 
1245
  Systematically compose the following elements to create the foundation for a 30-page novella:
 
1277
  """Enhanced critic's review of director's plan"""
1278
  base_prompt = self.create_critic_director_prompt(director_plan, language)
1279
 
1280
+ if language == "Korean":
1281
+ enhanced_criteria = """
1282
+
1283
+ === ๊ฐ•ํ™”๋œ ๋น„ํ‰ ๊ธฐ์ค€ ===
1284
+
1285
+ **๋ชจ๋“  ๋น„ํ‰์„ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”.**
1286
+
1287
+ **๋ฌธํ•™์  ํ’ˆ์งˆ ํ‰๊ฐ€:**
1288
+ 1. ๋…์ฐฝ์„ฑ ์ ์ˆ˜ (1-10): ์ด ์ปจ์…‰์ด ์–ผ๋งˆ๋‚˜ ์‹ ์„ ํ•˜๊ณ  ๋…ํŠนํ•œ๊ฐ€?
1289
+ 2. ๊ฐ์ •์  ๊ณต๋ช… (1-10): ๋…์ž๊ฐ€ ๊ฐ์ •์ ์œผ๋กœ ์—ฐ๊ฒฐ๋  ์ˆ˜ ์žˆ๋Š”๊ฐ€?
1290
+ 3. ์ฃผ์ œ์  ๊นŠ์ด (1-10): ์ฃผ์ œ๊ฐ€ ๊ฒน๊ฒน์ด ์Œ“์—ฌ ์žˆ๊ณ  ์˜๋ฏธ๊ฐ€ ์žˆ๋Š”๊ฐ€?
1291
+ 4. ์บ๋ฆญํ„ฐ ๋ณต์žก์„ฑ (1-10): ์บ๋ฆญํ„ฐ๊ฐ€ ๋‹ค์ฐจ์›์ ์ธ๊ฐ€?
1292
+
1293
+ **๊ตฌ์กฐ์  ๋ถ„์„:**
1294
+ - ๊ฐ ์ฑ•ํ„ฐ๊ฐ€ ์ „์ฒด ์•„ํฌ์—์„œ ๋ช…ํ™•ํ•œ ๋ชฉ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๊ฐ€?
1295
+ - ํŽ˜์ด์‹ฑ ๋ฌธ์ œ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋Š”๊ฐ€?
1296
+ - ํด๋ผ์ด๋งฅ์Šค๊ฐ€ ํšจ๊ณผ์ ์œผ๋กœ ๋ฐฐ์น˜๋˜์—ˆ๋Š”๊ฐ€?
1297
+
1298
+ **์‹คํ–‰ ๊ฐ€๋Šฅ์„ฑ ์ฒดํฌ:**
1299
+ - 10๋ช…์˜ ๋‹ค๋ฅธ ์ž‘๊ฐ€๊ฐ€ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€?
1300
+ - ์บ๋ฆญํ„ฐ ๋ชฉ์†Œ๋ฆฌ๊ฐ€ ์ถฉ๋ถ„ํžˆ ๊ตฌ๋ณ„๋˜๋Š”๊ฐ€?
1301
+ - ์—ฌ๋Ÿฌ ์ž‘๊ฐ€๋ฅผ ์œ„ํ•œ ์„ธ๊ณ„๊ด€์ด ์ถฉ๋ถ„ํžˆ ๋ช…ํ™•ํ•œ๊ฐ€?
1302
+
1303
+ ๊ฐ ๋น„ํ‰ ํฌ์ธํŠธ์— ๋Œ€ํ•ด ๊ตฌ์ฒด์ ์ธ ์˜ˆ์‹œ๋ฅผ ์ œ๊ณตํ•˜์„ธ์š”.
1304
+ """
1305
+ else:
1306
+ enhanced_criteria = """
1307
 
1308
  === ENHANCED CRITIQUE CRITERIA ===
1309
 
1310
+ **Write all critique in English.**
1311
+
1312
  **Literary Quality Assessment:**
1313
  1. Originality Score (1-10): How fresh and unique is this concept?
1314
  2. Emotional Resonance (1-10): Will readers connect emotionally?
 
1335
  if language == "Korean":
1336
  return f"""๋‹น์‹ ์€ ๋ฌธํ•™ ๋น„ํ‰๊ฐ€์ž…๋‹ˆ๋‹ค. ๊ฐ๋…์ž์˜ ์†Œ์„ค ๊ธฐํš์„ ๊ฒ€ํ† ํ•˜๊ณ  ๊ฐœ์„ ์ ์„ ์ œ์‹œํ•˜์„ธ์š”.
1337
 
1338
+ **์–ธ์–ด ์„ค์ •: ๋ชจ๋“  ๋‚ด์šฉ์„ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”.**
1339
+
1340
  ๊ฐ๋…์ž์˜ ๊ธฐํš:
1341
  {director_plan}
1342
 
 
1370
  else:
1371
  return f"""You are a literary critic. Review the director's novel plan and suggest improvements.
1372
 
1373
+ **Language Setting: Write all content in English.**
1374
+
1375
  Director's Plan:
1376
  {director_plan}
1377
 
 
1408
  if language == "Korean":
1409
  return f"""๊ฐ๋…์ž๋กœ์„œ ๋น„ํ‰๊ฐ€์˜ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ˜์˜ํ•˜์—ฌ ์†Œ์„ค ๊ธฐํš์„ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
1410
 
1411
+ **์–ธ์–ด ์„ค์ •: ๋ชจ๋“  ๋‚ด์šฉ์„ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”.**
1412
+
1413
  ์ดˆ๊ธฐ ๊ธฐํš:
1414
  {initial_plan}
1415
 
 
1448
  else:
1449
  return f"""As director, revise the novel plan reflecting the critic's feedback.
1450
 
1451
+ **Language Setting: Write all content in English.**
1452
+
1453
  Initial Plan:
1454
  {initial_plan}
1455
 
 
1494
  # Add character context
1495
  character_context = self.state_tracker.get_character_context(writer_number)
1496
 
1497
+ # Add literary enhancement with language parameter
1498
+ literary_guidelines = self.literary_enhancer.enhance_prompt(base_prompt, f"writer{writer_number}", writer_number, language)
1499
 
1500
  # Combine all elements
1501
  enhanced_prompt = base_prompt + character_context + literary_guidelines
1502
 
1503
  if writer_number > 1:
1504
  # Add consistency reminder
1505
+ if language == "Korean":
1506
+ consistency_reminder = """
1507
+
1508
+ === ์ผ๊ด€์„ฑ ์š”๊ตฌ์‚ฌํ•ญ ===
1509
+ ์ด์ „ ์ฑ•ํ„ฐ์™€์˜ ์ผ๊ด€์„ฑ์„ ๋ฐ˜๋“œ์‹œ ์œ ์ง€ํ•˜์„ธ์š”:
1510
+ - ์บ๋ฆญํ„ฐ ์ƒํƒœ ํ™•์ธ (์ƒ์‚ฌ, ๋ถ€์ƒ, ์œ„์น˜)
1511
+ - ํ™•๋ฆฝ๋œ ๊ธฐ์ˆ ๊ณผ ์„ค์ • ์œ ์ง€
1512
+ - ์ด์ „ ์ฑ•ํ„ฐ์˜ ์‹œ๊ฐ„์„  ๋”ฐ๋ฅด๊ธฐ
1513
+ - ์บ๋ฆญํ„ฐ ๊ด€๊ณ„์™€ ๊ฐ์ • ์ƒํƒœ ์กด์ค‘
1514
+ """
1515
+ else:
1516
+ consistency_reminder = """
1517
 
1518
  === CONSISTENCY REQUIREMENTS ===
1519
  You MUST maintain consistency with previous chapters:
 
1534
  if language == "Korean":
1535
  return f"""๋‹น์‹ ์€ ์ž‘์„ฑ์ž {writer_number}๋ฒˆ์ž…๋‹ˆ๋‹ค. 30ํŽ˜์ด์ง€ ์ค‘ํŽธ ์†Œ์„ค์˜ {pages_start}-{pages_end}ํŽ˜์ด์ง€(3ํŽ˜์ด์ง€)๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”.
1536
 
1537
+ **์–ธ์–ด ์„ค์ •: ๋ฐ˜๋“œ์‹œ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”. ์˜์–ด ์‚ฌ์šฉ์€ ์ ˆ๋Œ€ ๊ธˆ์ง€์ž…๋‹ˆ๋‹ค.**
1538
+
1539
  ๊ฐ๋…์ž์˜ ๋งˆ์Šคํ„ฐํ”Œ๋žœ:
1540
  {director_plan}
1541
 
 
1567
  - ๋…์ž์˜ ๊ด€์‹ฌ ์œ ์ง€
1568
 
1569
  **์ž‘์„ฑ ์‹œ์ž‘:**
1570
+ ์ด์ œ 1,400-1,500๋‹จ์–ด ๋ถ„๋Ÿ‰์˜ ์†Œ์„ค์„ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”. ํŽ˜์ด์ง€ ๊ตฌ๋ถ„ ํ‘œ์‹œ๋Š” ํ•˜์ง€ ๋งˆ์„ธ์š”."""
1571
  else:
1572
  return f"""You are Writer #{writer_number}. Write pages {pages_start}-{pages_end} (3 pages) of the 30-page novella.
1573
 
1574
+ **Language Setting: You must write in English.**
1575
+
1576
  Director's Masterplan:
1577
  {director_plan}
1578
 
 
1604
  - Maintain reader interest
1605
 
1606
  **BEGIN WRITING:**
1607
+ Now write your 1,400-1,500 word section in English. Do not use any page markers."""
1608
 
1609
  def create_enhanced_critic_writer_prompt(self, writer_number: int, writer_content: str,
1610
  director_plan: str, all_previous_content: str,
 
1619
  # Get quality scores
1620
  quality_scores = self.quality_scorer.score_content(writer_content, self.state_tracker, writer_number)
1621
 
1622
+ if language == "Korean":
1623
+ consistency_section = f"""
1624
+
1625
+ === ์ผ๊ด€์„ฑ ๊ฒ€์ฆ ๊ฒฐ๊ณผ ===
1626
+ {'์ผ๊ด€์„ฑ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.' if not consistency_errors else '์น˜๋ช…์  ์˜ค๋ฅ˜ ๋ฐœ๊ฒฌ:'}
1627
+ """
1628
+ for error in consistency_errors:
1629
+ consistency_section += f"- {error}\n"
1630
+
1631
+ quality_section = f"""
1632
+
1633
+ === ํ’ˆ์งˆ ํ‰๊ฐ€ ===
1634
+ ๋ฌธํ•™์  ํ’ˆ์งˆ: {quality_scores['literary_quality']:.1f}/10
1635
+ ์ผ๊ด€์„ฑ: {quality_scores['consistency']:.1f}/10
1636
+ ๊ฐ์ •์  ๊นŠ์ด: {quality_scores['emotional_depth']:.1f}/10
1637
+ ๋…์ฐฝ์„ฑ: {quality_scores['originality']:.1f}/10
1638
+ ํŽ˜์ด์‹ฑ: {quality_scores['pacing']:.1f}/10
1639
+
1640
+ ์ „์ฒด ์ ์ˆ˜: {sum(quality_scores.values())/len(quality_scores):.1f}/10
1641
+
1642
+ **๋ชจ๋“  ํ”ผ๋“œ๋ฐฑ์„ ํ•œ๊ตญ์–ด๋กœ ์ œ๊ณตํ•˜์„ธ์š”.**
1643
+ """
1644
+ else:
1645
+ consistency_section = f"""
1646
 
1647
  === CONSISTENCY VALIDATION RESULTS ===
1648
  {'No consistency errors detected.' if not consistency_errors else 'CRITICAL ERRORS FOUND:'}
1649
  """
1650
+ for error in consistency_errors:
1651
+ consistency_section += f"- {error}\n"
1652
+
1653
+ quality_section = f"""
1654
 
1655
  === QUALITY ASSESSMENT ===
1656
  Literary Quality: {quality_scores['literary_quality']:.1f}/10
 
1660
  Pacing: {quality_scores['pacing']:.1f}/10
1661
 
1662
  Overall Score: {sum(quality_scores.values())/len(quality_scores):.1f}/10
1663
+
1664
+ **Provide all feedback in English.**
1665
  """
1666
 
1667
  return base_prompt + consistency_section + quality_section
 
1671
  if language == "Korean":
1672
  return f"""์ž‘์„ฑ์ž {writer_number}๋ฒˆ์˜ ์ž‘ํ’ˆ์„ ๋น„ํ‰ํ•ฉ๋‹ˆ๋‹ค.
1673
 
1674
+ **์–ธ์–ด ์„ค์ •: ๋ชจ๋“  ๋น„ํ‰์„ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”.**
1675
+
1676
  ๊ฐ๋…์ž์˜ ๋งˆ์Šคํ„ฐํ”Œ๋žœ:
1677
  {director_plan}
1678
 
 
1715
  else:
1716
  return f"""Critiquing Writer #{writer_number}'s work.
1717
 
1718
+ **Language Setting: Write all critique in English.**
1719
+
1720
  Director's Masterplan:
1721
  {director_plan}
1722
 
 
1762
  if language == "Korean":
1763
  return f"""์ž‘์„ฑ์ž {writer_number}๋ฒˆ์œผ๋กœ์„œ ๋น„ํ‰๊ฐ€์˜ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ˜์˜ํ•˜์—ฌ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
1764
 
1765
+ **์–ธ์–ด ์„ค์ •: ๋ฐ˜๋“œ์‹œ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”. ์˜์–ด ์‚ฌ์šฉ์€ ์ ˆ๋Œ€ ๊ธˆ์ง€์ž…๋‹ˆ๋‹ค.**
1766
+
1767
  ์ดˆ๊ธฐ ์ž‘์„ฑ ๋‚ด์šฉ:
1768
  {initial_content}
1769
 
 
1790
  - ์ด์ „/์ดํ›„ ๋‚ด์šฉ๊ณผ์˜ ์ž์—ฐ์Šค๋Ÿฌ์šด ์—ฐ๊ฒฐ
1791
  - ์ˆ˜์ •์œผ๋กœ ์ธํ•œ ์ƒˆ๋กœ์šด ๋ชจ์ˆœ ๋ฐฉ์ง€
1792
 
1793
+ ์ˆ˜์ •๋œ ์ตœ์ข…๋ณธ์„ ํ•œ๊ตญ์–ด๋กœ ์ œ์‹œํ•˜์„ธ์š”. ํŽ˜์ด์ง€ ๋งˆํฌ๋Š” ์ ˆ๋Œ€ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”.
1794
  ๋ฐ˜๋“œ์‹œ 1,400-1,500๋‹จ์–ด ๋ถ„๋Ÿ‰์„ ์œ ์ง€ํ•˜์„ธ์š”."""
1795
  else:
1796
  return f"""As Writer #{writer_number}, revise based on critic's feedback.
1797
 
1798
+ **Language Setting: You must write in English.**
1799
+
1800
  Initial Content:
1801
  {initial_content}
1802
 
 
1823
  - Natural connection with previous/next content
1824
  - Prevent new contradictions from revisions
1825
 
1826
+ Present the revised final version in English. Never use page markers.
1827
  You MUST maintain 1,400-1,500 words."""
1828
 
1829
  def create_test_writer_remaining_prompt(self, director_plan: str, writer1_content: str, language: str) -> str:
 
1831
  if language == "Korean":
1832
  return f"""[ํ…Œ์ŠคํŠธ ๋ชจ๋“œ] ๋‹น์‹ ์€ ๋‚˜๋จธ์ง€ 9๊ฐœ ์ฑ•ํ„ฐ(Chapter 2-10)๋ฅผ ์ž‘์„ฑํ•˜๋Š” ํŠน๋ณ„ ์ž‘๊ฐ€์ž…๋‹ˆ๋‹ค.
1833
 
1834
+ **์–ธ์–ด ์„ค์ •: ๋ฐ˜๋“œ์‹œ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”. ์˜์–ด ์‚ฌ์šฉ์€ ์ ˆ๋Œ€ ๊ธˆ์ง€์ž…๋‹ˆ๋‹ค.**
1835
+
1836
  ๊ฐ๋…์ž์˜ ๋งˆ์Šคํ„ฐํ”Œ๋žœ:
1837
  {director_plan}
1838
 
 
1845
  3. ์ด 12,600-13,500 ๋‹จ์–ด (9๊ฐœ ์ฑ•ํ„ฐ)
1846
  4. Chapter 1๊ณผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ด์–ด์ง€๋„๋ก ์ž‘์„ฑํ•˜์„ธ์š”
1847
  5. ๋งˆ์Šคํ„ฐํ”Œ๋žœ์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ํฌํ•จํ•˜์—ฌ ์™„๊ฒฐ๋œ ์ด์•ผ๊ธฐ๋ฅผ ๋งŒ๋“œ์„ธ์š”
1848
+ 6. ๋ชจ๋“  ๋‚ด์šฉ์„ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”
1849
 
1850
  **ํ•„์ˆ˜ ํ˜•์‹:**
1851
  ๋ฐ˜๋“œ์‹œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ฑ•ํ„ฐ๋ฅผ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„ํ•˜์„ธ์š”:
1852
 
1853
  [Chapter 2]
1854
+ (1,400-1,500 ๋‹จ์–ด์˜ ํ•œ๊ตญ์–ด ๋‚ด์šฉ)
1855
 
1856
  [Chapter 3]
1857
+ (1,400-1,500 ๋‹จ์–ด์˜ ํ•œ๊ตญ์–ด ๋‚ด์šฉ)
1858
 
1859
  ...์ด๋Ÿฐ ์‹์œผ๋กœ [Chapter 10]๊นŒ์ง€...
1860
 
1861
  ๊ฐ ์ฑ•ํ„ฐ๋Š” ๋ฐ˜๋“œ์‹œ [Chapter ์ˆซ์ž] ํ˜•์‹์œผ๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
1862
  ์ฑ•ํ„ฐ ์‚ฌ์ด์—๋Š” ๋นˆ ์ค„์„ ๋„ฃ์–ด ๊ตฌ๋ถ„ํ•˜์„ธ์š”.
1863
+ Chapter 2๋ถ€ํ„ฐ 10๊นŒ์ง€ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”."""
1864
  else:
1865
  return f"""[TEST MODE] You are a special writer creating the remaining 9 chapters (Chapters 2-10).
1866
 
1867
+ **Language Setting: You must write in English.**
1868
+
1869
  Director's Masterplan:
1870
  {director_plan}
1871
 
 
1878
  3. Total 12,600-13,500 words (9 chapters)
1879
  4. Continue naturally from Chapter 1
1880
  5. Include all elements from the masterplan to create a complete story
1881
+ 6. Write all content in English
1882
 
1883
  **MANDATORY FORMAT:**
1884
  You MUST clearly separate chapters as follows:
1885
 
1886
  [Chapter 2]
1887
+ (1,400-1,500 words of content in English)
1888
 
1889
  [Chapter 3]
1890
+ (1,400-1,500 words of content in English)
1891
 
1892
  ...continue this way until [Chapter 10]...
1893
 
1894
  Each chapter MUST start with [Chapter number] format.
1895
  Leave blank lines between chapters for separation.
1896
+ Write Chapters 2-10 in English now."""
1897
 
1898
  def simulate_streaming(self, text: str, role: str) -> Generator[str, None, None]:
1899
  """Simulate streaming in test mode"""
 
1943
  # Enhanced system prompt for writers
1944
  if role.startswith("writer"):
1945
  if language == "Korean":
1946
+ system_prompts[role] += "\n\n**์ ˆ๋Œ€์  ์š”๊ตฌ์‚ฌํ•ญ**: ๋‹น์‹ ์€ ๋ฐ˜๋“œ์‹œ 1,400-1,500๋‹จ์–ด๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํ˜‘์ƒ ๋ถˆ๊ฐ€๋Šฅํ•œ ์š”๊ตฌ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ๋ฐ˜๋“œ์‹œ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”."
1947
  else:
1948
  system_prompts[role] += "\n\n**ABSOLUTE REQUIREMENT**: You MUST write 1,400-1,500 words. This is non-negotiable."
1949
 
1950
+ # Add language enforcement to system prompt
1951
+ if language == "Korean":
1952
+ language_enforcement = "\n\n**์ค‘์š”**: ๋ชจ๋“  ์‘๋‹ต์€ ๋ฐ˜๋“œ์‹œ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”. ์˜์–ด ์‚ฌ์šฉ์€ ์ ˆ๋Œ€ ๊ธˆ์ง€์ž…๋‹ˆ๋‹ค."
1953
+ else:
1954
+ language_enforcement = "\n\n**IMPORTANT**: All responses must be written in English."
1955
+
1956
  full_messages = [
1957
+ {"role": "system", "content": system_prompts.get(role, "") + language_enforcement},
1958
  *messages
1959
  ]
1960
 
 
1972
  temperature = 0.6
1973
  top_p = 0.9
1974
 
1975
+ # Add language hint to first user message if needed
1976
+ if messages and messages[0]["role"] == "user" and language == "Korean":
1977
+ # Prepend language instruction to first user message
1978
+ original_content = messages[0]["content"]
1979
+ messages[0]["content"] = "**๋ฐ˜๋“œ์‹œ ํ•œ๊ตญ์–ด๋กœ ์‘๋‹ตํ•˜์„ธ์š”.**\n\n" + original_content
1980
+
1981
  payload = {
1982
  "model": self.model_id,
1983
  "messages": full_messages,
 
1988
  "stream_options": {"include_usage": True}
1989
  }
1990
 
1991
+ # Some models support language parameter
1992
+ if language == "Korean":
1993
+ payload["language"] = "ko"
1994
+ else:
1995
+ payload["language"] = "en"
1996
+
1997
+ logger.info(f"API streaming call started - Role: {role}, Max tokens: {max_tokens}, Temperature: {temperature}, Language: {language}")
1998
+
1999
+ # Log the first part of system prompt for debugging
2000
+ if full_messages and full_messages[0]["role"] == "system":
2001
+ system_preview = full_messages[0]["content"][:200] + "..." if len(full_messages[0]["content"]) > 200 else full_messages[0]["content"]
2002
+ logger.debug(f"System prompt preview: {system_preview}")
2003
 
2004
  response = requests.post(
2005
  self.api_url,
 
2477
  # Get appropriate prompt based on stage
2478
  prompt = self.get_stage_prompt(stage_idx, role, query, language, stages, test_quick_mode)
2479
 
2480
+ # Log prompt language for debugging
2481
+ if "ํ•œ๊ตญ์–ด๋กœ" in prompt or "Korean" in prompt[:500]:
2482
+ logger.info(f"Prompt contains Korean language instruction")
2483
+ elif "English" in prompt[:500]:
2484
+ logger.info(f"Prompt contains English language instruction")
2485
+ else:
2486
+ logger.warning(f"Prompt may not have clear language instruction")
2487
+
2488
  # Create stage info for web search and validation
2489
  stage_info = {
2490
  'stage_idx': stage_idx,
 
2649
  def get_stage_prompt(self, stage_idx: int, role: str, query: str,
2650
  language: str, stages: List[Dict], test_mode: bool = False) -> str:
2651
  """Get appropriate prompt for each stage with enhancements"""
2652
+ logger.info(f"Getting prompt for stage {stage_idx}, role: {role}, language: {language}")
2653
+
2654
  # Stage 0: Director Initial
2655
  if stage_idx == 0:
2656
  return self.create_enhanced_director_initial_prompt(query, language)
 
2683
  if "์ดˆ์•ˆ" in stages[stage_idx]["name"] or "Draft" in stages[stage_idx]["name"]:
2684
  # Get accumulated content from DB
2685
  accumulated_content = NovelDatabase.get_all_writer_content(self.current_session_id)
2686
+ logger.info(f"Creating writer {writer_num} draft prompt in {language}")
2687
  return self.create_enhanced_writer_prompt(writer_num, final_plan, accumulated_content, language)
2688
  else: # Revision
2689
  # Find the initial draft and critic feedback
2690
  initial_draft_idx = stage_idx - 2
2691
  critic_feedback_idx = stage_idx - 1
2692
+ logger.info(f"Creating writer {writer_num} revision prompt in {language}")
2693
  return self.create_writer_revision_prompt(
2694
  writer_num,
2695
  stages[initial_draft_idx]["content"],