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"],