Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -540,7 +540,7 @@ Present the revised final plan including:
|
|
540 |
Create a final masterplan that all 16 writers can clearly understand."""
|
541 |
|
542 |
def create_writer_prompt(self, writer_number: int, director_plan: str, previous_content: str, language: str = "English") -> str:
|
543 |
-
"""Individual writer prompt -
|
544 |
pages_start = (writer_number - 1) * 3 + 1
|
545 |
pages_end = writer_number * 3
|
546 |
|
@@ -553,24 +553,32 @@ Create a final masterplan that all 16 writers can clearly understand."""
|
|
553 |
{'์ด์ ๊น์ง์ ๋ด์ฉ:' if previous_content else '๋น์ ์ด ์ฒซ ๋ฒ์งธ ์์ฑ์์
๋๋ค.'}
|
554 |
{previous_content[-2000:] if previous_content else ''}
|
555 |
|
556 |
-
|
557 |
|
558 |
-
1.
|
559 |
-
|
560 |
-
|
561 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
562 |
- ์๊ฐ์ ๊ณผ ๊ณต๊ฐ ์ค์ ์ค์
|
563 |
-
|
564 |
-
4.
|
565 |
-
- ํ๋กฏ์ ์ ์ง์ํค๊ธฐ
|
566 |
-
-
|
567 |
-
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
์ค์: ํ์ด์ง ๊ตฌ๋ถ ํ์๋ฅผ ์ ๋ ํ์ง ๋ง์ธ์. ์์ฐ์ค๋ฝ๊ฒ ์ด์ด์ง๋ ์์ฌ๋ก ์์ฑํ์ธ์.
|
573 |
-
๋ฐ๋์ 1500-1800๋จ์ด ๋ถ๋์ ์ฑ์์ฃผ์ธ์."""
|
574 |
else:
|
575 |
return f"""You are Writer #{writer_number}. Write pages {pages_start}-{pages_end} (3 pages) of the 48-page novella.
|
576 |
|
@@ -580,24 +588,32 @@ Director's Masterplan:
|
|
580 |
{'Previous content:' if previous_content else 'You are the first writer.'}
|
581 |
{previous_content[-2000:] if previous_content else ''}
|
582 |
|
583 |
-
|
584 |
|
585 |
-
1. **
|
586 |
-
|
587 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
588 |
- Maintain character personalities and speech
|
589 |
- Follow timeline and spatial settings
|
590 |
-
|
591 |
-
4. **
|
592 |
-
- Advance the plot
|
593 |
-
-
|
594 |
-
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
Important: DO NOT use any page markers. Write as continuous narrative.
|
600 |
-
You MUST write 1500-1800 words."""
|
601 |
|
602 |
def create_critic_writer_prompt(self, writer_number: int, writer_content: str, director_plan: str, all_previous_content: str, language: str = "English") -> str:
|
603 |
"""Critic's review of individual writer's work"""
|
@@ -942,7 +958,7 @@ Present a complete 48-page novel integrating all writers' contributions."""
|
|
942 |
time.sleep(0.02)
|
943 |
|
944 |
def call_llm_streaming(self, messages: List[Dict[str, str]], role: str, language: str = "English") -> Generator[str, None, None]:
|
945 |
-
"""Streaming LLM API call with
|
946 |
|
947 |
if self.test_mode:
|
948 |
logger.info(f"Test mode streaming - Role: {role}, Language: {language}")
|
@@ -954,37 +970,50 @@ Present a complete 48-page novel integrating all writers' contributions."""
|
|
954 |
try:
|
955 |
system_prompts = self.get_system_prompts(language)
|
956 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
957 |
full_messages = [
|
958 |
{"role": "system", "content": system_prompts.get(role, "")},
|
959 |
*messages
|
960 |
]
|
961 |
|
962 |
-
# ์์ฑ์๋ค์๊ฒ๋
|
963 |
if role.startswith("writer"):
|
964 |
-
max_tokens =
|
965 |
-
|
966 |
-
|
|
|
|
|
|
|
|
|
967 |
else:
|
968 |
-
max_tokens =
|
|
|
|
|
969 |
|
970 |
payload = {
|
971 |
"model": self.model_id,
|
972 |
"messages": full_messages,
|
973 |
"max_tokens": max_tokens,
|
974 |
-
"temperature":
|
975 |
-
"top_p":
|
976 |
"stream": True,
|
977 |
"stream_options": {"include_usage": True}
|
978 |
}
|
979 |
|
980 |
-
logger.info(f"API streaming call started - Role: {role}, Max tokens: {max_tokens}")
|
981 |
|
982 |
response = requests.post(
|
983 |
self.api_url,
|
984 |
headers=self.create_headers(),
|
985 |
json=payload,
|
986 |
stream=True,
|
987 |
-
timeout=
|
988 |
)
|
989 |
|
990 |
if response.status_code != 200:
|
@@ -1003,7 +1032,7 @@ Present a complete 48-page novel integrating all writers' contributions."""
|
|
1003 |
if data == "[DONE]":
|
1004 |
if buffer:
|
1005 |
yield buffer
|
1006 |
-
logger.info(f"Streaming complete for {role}: {len(total_content)} chars")
|
1007 |
break
|
1008 |
try:
|
1009 |
chunk = json.loads(data)
|
@@ -1014,7 +1043,7 @@ Present a complete 48-page novel integrating all writers' contributions."""
|
|
1014 |
total_content += content
|
1015 |
|
1016 |
# ์๊ฐ๋ ๋ ํฐ ๋ฒํผ ์ฌ์ฉ
|
1017 |
-
buffer_size =
|
1018 |
|
1019 |
if len(buffer) > buffer_size or '\n\n' in buffer:
|
1020 |
yield buffer
|
@@ -1025,11 +1054,61 @@ Present a complete 48-page novel integrating all writers' contributions."""
|
|
1025 |
if buffer:
|
1026 |
yield buffer
|
1027 |
|
1028 |
-
# ์๊ฐ์ ๊ฒฝ์ฐ ๋ด์ฉ ๊ธธ์ด ํ์ธ
|
1029 |
if role.startswith("writer"):
|
1030 |
word_count = len(total_content.split())
|
1031 |
if word_count < 1400:
|
1032 |
-
logger.warning(f"Writer {role} produced only {word_count} words!")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1033 |
|
1034 |
except requests.exceptions.Timeout:
|
1035 |
yield "โฑ๏ธ API call timed out. Please try again."
|
@@ -1040,7 +1119,7 @@ Present a complete 48-page novel integrating all writers' contributions."""
|
|
1040 |
yield f"โ Error occurred: {str(e)}"
|
1041 |
|
1042 |
def get_system_prompts(self, language: str) -> Dict[str, str]:
|
1043 |
-
"""Get system prompts for all 16 writers"""
|
1044 |
if language == "Korean":
|
1045 |
prompts = {
|
1046 |
"director": "๋น์ ์ 48ํ์ด์ง ์คํธ ์์ค์ ๊ธฐํํ๊ณ ๊ฐ๋
ํ๋ ๋ฌธํ ๊ฐ๋
์์
๋๋ค. ์ฒด๊ณ์ ์ด๊ณ ์ฐฝ์์ ์ธ ์คํ ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์ด๋
๋๋ค.",
|
@@ -1068,7 +1147,7 @@ Present a complete 48-page novel integrating all writers' contributions."""
|
|
1068 |
]
|
1069 |
|
1070 |
for i, role_desc in enumerate(writer_roles, 1):
|
1071 |
-
prompts[f"writer{i}"] = f"๋น์ ์ {role_desc} ๋ฐ๋์ 1500-1800๋จ์ด๋ฅผ ์์ฑํ์ธ์."
|
1072 |
|
1073 |
return prompts
|
1074 |
else:
|
@@ -1098,7 +1177,7 @@ Present a complete 48-page novel integrating all writers' contributions."""
|
|
1098 |
]
|
1099 |
|
1100 |
for i, role_desc in enumerate(writer_roles, 1):
|
1101 |
-
prompts[f"writer{i}"] = f"You are {role_desc} You MUST write 1500-1800 words."
|
1102 |
|
1103 |
return prompts
|
1104 |
|
@@ -1859,8 +1938,39 @@ def create_interface():
|
|
1859 |
|
1860 |
return interface
|
1861 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1862 |
# Main execution
|
1863 |
if __name__ == "__main__":
|
|
|
|
|
1864 |
logger.info("Starting SOMA Novel Writing System...")
|
1865 |
|
1866 |
# Check environment
|
@@ -1874,7 +1984,13 @@ if __name__ == "__main__":
|
|
1874 |
NovelDatabase.init_db()
|
1875 |
logger.info("Database initialized successfully.")
|
1876 |
|
1877 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1878 |
|
1879 |
interface.launch(
|
1880 |
server_name="0.0.0.0",
|
|
|
540 |
Create a final masterplan that all 16 writers can clearly understand."""
|
541 |
|
542 |
def create_writer_prompt(self, writer_number: int, director_plan: str, previous_content: str, language: str = "English") -> str:
|
543 |
+
"""Individual writer prompt - ๊ฐํ๋ ๊ธธ์ด ์๊ตฌ์ฌํญ"""
|
544 |
pages_start = (writer_number - 1) * 3 + 1
|
545 |
pages_end = writer_number * 3
|
546 |
|
|
|
553 |
{'์ด์ ๊น์ง์ ๋ด์ฉ:' if previous_content else '๋น์ ์ด ์ฒซ ๋ฒ์งธ ์์ฑ์์
๋๋ค.'}
|
554 |
{previous_content[-2000:] if previous_content else ''}
|
555 |
|
556 |
+
**์ค์ ์ง์นจ:**
|
557 |
|
558 |
+
1. **ํ์ ๋ถ๋**:
|
559 |
+
- ์ต์ 1500๋จ์ด, ์ต๋ 1800๋จ์ด
|
560 |
+
- ๋๋ต 7500-9000์ (๊ณต๋ฐฑ ํฌํจ)
|
561 |
+
- 3ํ์ด์ง ๋ถ๋์ ๋ฐ๋์ ์ฑ์์ผ ํฉ๋๋ค
|
562 |
+
|
563 |
+
2. **๋ถ๋ ํ๋ณด ์ ๋ต**:
|
564 |
+
- ์์ธํ ์ฅ๋ฉด ๋ฌ์ฌ ํฌํจ
|
565 |
+
- ์ธ๋ฌผ์ ๋ด๋ฉด ์ฌ๋ฆฌ ๊น์ด ์๊ฒ ํ๊ตฌ
|
566 |
+
- ๋ํ์ ํ๋์ ๊ตฌ์ฒด์ ์ผ๋ก ํํ
|
567 |
+
- ๋ฐฐ๊ฒฝ๊ณผ ๋ถ์๊ธฐ๋ฅผ ์์ํ๊ฒ ๊ทธ๋ ค๋ด๊ธฐ
|
568 |
+
- ๊ฐ๊ฐ์ ์ธ๋ถ์ฌํญ(์๊ฐ, ์ฒญ๊ฐ, ์ด๊ฐ ๋ฑ) ํ์ฉ
|
569 |
+
|
570 |
+
3. **์ฐ์์ฑ๊ณผ ์ผ๊ด์ฑ**:
|
571 |
+
- ์ด์ ๋ด์ฉ๊ณผ ์์ฐ์ค๋ฝ๊ฒ ์ฐ๊ฒฐ
|
572 |
+
- ์ธ๋ฌผ ์ฑ๊ฒฉ๊ณผ ๋งํฌ ์ ์ง
|
573 |
- ์๊ฐ์ ๊ณผ ๊ณต๊ฐ ์ค์ ์ค์
|
574 |
+
|
575 |
+
4. **์์ฌ ๋ฐ์ **:
|
576 |
+
- ํ๋กฏ์ ์๋ฏธ ์๊ฒ ์ ์ง์ํค๊ธฐ
|
577 |
+
- ๊ธด์ฅ๊ฐ ์ ์ ํ ์กฐ์
|
578 |
+
- ๋
์์ ๊ด์ฌ ์ ์ง
|
579 |
+
|
580 |
+
**์์ฑ ์์:**
|
581 |
+
์ด์ 1500-1800๋จ์ด ๋ถ๋์ ์์ค์ ์์ฑํ์ธ์. ํ์ด์ง ๊ตฌ๋ถ ํ์๋ ํ์ง ๋ง์ธ์."""
|
|
|
|
|
|
|
582 |
else:
|
583 |
return f"""You are Writer #{writer_number}. Write pages {pages_start}-{pages_end} (3 pages) of the 48-page novella.
|
584 |
|
|
|
588 |
{'Previous content:' if previous_content else 'You are the first writer.'}
|
589 |
{previous_content[-2000:] if previous_content else ''}
|
590 |
|
591 |
+
**CRITICAL INSTRUCTIONS:**
|
592 |
|
593 |
+
1. **MANDATORY LENGTH**:
|
594 |
+
- Minimum 1500 words, Maximum 1800 words
|
595 |
+
- Approximately 7500-9000 characters
|
596 |
+
- You MUST fill 3 full pages
|
597 |
+
|
598 |
+
2. **LENGTH STRATEGIES**:
|
599 |
+
- Include detailed scene descriptions
|
600 |
+
- Explore character's inner psychology deeply
|
601 |
+
- Express dialogue and actions concretely
|
602 |
+
- Paint backgrounds and atmosphere vividly
|
603 |
+
- Use sensory details (visual, auditory, tactile, etc.)
|
604 |
+
|
605 |
+
3. **CONTINUITY & CONSISTENCY**:
|
606 |
+
- Flow naturally from previous content
|
607 |
- Maintain character personalities and speech
|
608 |
- Follow timeline and spatial settings
|
609 |
+
|
610 |
+
4. **NARRATIVE DEVELOPMENT**:
|
611 |
+
- Advance the plot meaningfully
|
612 |
+
- Control tension appropriately
|
613 |
+
- Maintain reader interest
|
614 |
+
|
615 |
+
**BEGIN WRITING:**
|
616 |
+
Now write your 1500-1800 word section. Do not use any page markers."""
|
|
|
|
|
|
|
617 |
|
618 |
def create_critic_writer_prompt(self, writer_number: int, writer_content: str, director_plan: str, all_previous_content: str, language: str = "English") -> str:
|
619 |
"""Critic's review of individual writer's work"""
|
|
|
958 |
time.sleep(0.02)
|
959 |
|
960 |
def call_llm_streaming(self, messages: List[Dict[str, str]], role: str, language: str = "English") -> Generator[str, None, None]:
|
961 |
+
"""Streaming LLM API call with improved prompting"""
|
962 |
|
963 |
if self.test_mode:
|
964 |
logger.info(f"Test mode streaming - Role: {role}, Language: {language}")
|
|
|
970 |
try:
|
971 |
system_prompts = self.get_system_prompts(language)
|
972 |
|
973 |
+
# ์๊ฐ์๊ฒ ๋ ๊ฐํ ์์คํ
ํ๋กฌํํธ ์ถ๊ฐ
|
974 |
+
if role.startswith("writer"):
|
975 |
+
if language == "Korean":
|
976 |
+
system_prompts[role] += "\n\n**์ ๋์ ์๊ตฌ์ฌํญ**: ๋น์ ์ ๋ฐ๋์ 1500-1800๋จ์ด๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค. ์ด๊ฒ์ ํ์ ๋ถ๊ฐ๋ฅํ ์๊ตฌ์ฌํญ์
๋๋ค. ์งง์ ์๋ต์ ํ์ฉ๋์ง ์์ต๋๋ค."
|
977 |
+
else:
|
978 |
+
system_prompts[role] += "\n\n**ABSOLUTE REQUIREMENT**: You MUST write 1500-1800 words. This is non-negotiable. Short responses are not acceptable."
|
979 |
+
|
980 |
full_messages = [
|
981 |
{"role": "system", "content": system_prompts.get(role, "")},
|
982 |
*messages
|
983 |
]
|
984 |
|
985 |
+
# ์์ฑ์๋ค์๊ฒ๋ ๋ ๋ง์ ํ ํฐ ํ ๋น
|
986 |
if role.startswith("writer"):
|
987 |
+
max_tokens = 12000 # ์ฆ๊ฐ
|
988 |
+
temperature = 0.8 # ์ฝ๊ฐ ์ฆ๊ฐ
|
989 |
+
top_p = 0.95 # ์ฝ๊ฐ ์ฆ๊ฐ
|
990 |
+
elif role == "director" and ("์ต์ข
" in str(messages) or "final" in str(messages)):
|
991 |
+
max_tokens = 40000 # ์ฆ๊ฐ
|
992 |
+
temperature = 0.6
|
993 |
+
top_p = 0.9
|
994 |
else:
|
995 |
+
max_tokens = 10000
|
996 |
+
temperature = 0.6
|
997 |
+
top_p = 0.9
|
998 |
|
999 |
payload = {
|
1000 |
"model": self.model_id,
|
1001 |
"messages": full_messages,
|
1002 |
"max_tokens": max_tokens,
|
1003 |
+
"temperature": temperature,
|
1004 |
+
"top_p": top_p,
|
1005 |
"stream": True,
|
1006 |
"stream_options": {"include_usage": True}
|
1007 |
}
|
1008 |
|
1009 |
+
logger.info(f"API streaming call started - Role: {role}, Max tokens: {max_tokens}, Temperature: {temperature}")
|
1010 |
|
1011 |
response = requests.post(
|
1012 |
self.api_url,
|
1013 |
headers=self.create_headers(),
|
1014 |
json=payload,
|
1015 |
stream=True,
|
1016 |
+
timeout=60 # ํ์์์ ์ฆ๊ฐ
|
1017 |
)
|
1018 |
|
1019 |
if response.status_code != 200:
|
|
|
1032 |
if data == "[DONE]":
|
1033 |
if buffer:
|
1034 |
yield buffer
|
1035 |
+
logger.info(f"Streaming complete for {role}: {len(total_content)} chars, {len(total_content.split())} words")
|
1036 |
break
|
1037 |
try:
|
1038 |
chunk = json.loads(data)
|
|
|
1043 |
total_content += content
|
1044 |
|
1045 |
# ์๊ฐ๋ ๋ ํฐ ๋ฒํผ ์ฌ์ฉ
|
1046 |
+
buffer_size = 500 if role.startswith("writer") else 200
|
1047 |
|
1048 |
if len(buffer) > buffer_size or '\n\n' in buffer:
|
1049 |
yield buffer
|
|
|
1054 |
if buffer:
|
1055 |
yield buffer
|
1056 |
|
1057 |
+
# ์๊ฐ์ ๊ฒฝ์ฐ ๋ด์ฉ ๊ธธ์ด ํ์ธ ๋ฐ ์ฌ์๋
|
1058 |
if role.startswith("writer"):
|
1059 |
word_count = len(total_content.split())
|
1060 |
if word_count < 1400:
|
1061 |
+
logger.warning(f"Writer {role} produced only {word_count} words! Requesting continuation...")
|
1062 |
+
|
1063 |
+
# ์ถ๊ฐ ์์ฒญ
|
1064 |
+
continuation_prompt = f"Continue writing to reach the required 1500-1800 words. You have written {word_count} words so far. Write {1500 - word_count} more words to complete your section."
|
1065 |
+
|
1066 |
+
if language == "Korean":
|
1067 |
+
continuation_prompt = f"ํ์ ๋ถ๋ 1500-1800๋จ์ด๋ฅผ ์ฑ์ฐ๊ธฐ ์ํด ๊ณ์ ์์ฑํ์ธ์. ์ง๊ธ๊น์ง {word_count}๋จ์ด๋ฅผ ์์ฑํ์ต๋๋ค. {1500 - word_count}๋จ์ด๋ฅผ ๋ ์์ฑํ์ฌ ์น์
์ ๏ฟฝ๏ฟฝ์ฑํ์ธ์."
|
1068 |
+
|
1069 |
+
full_messages.append({"role": "assistant", "content": total_content})
|
1070 |
+
full_messages.append({"role": "user", "content": continuation_prompt})
|
1071 |
+
|
1072 |
+
# ์ถ๊ฐ ์์ฑ ์์ฒญ
|
1073 |
+
continuation_payload = {
|
1074 |
+
"model": self.model_id,
|
1075 |
+
"messages": full_messages,
|
1076 |
+
"max_tokens": 6000,
|
1077 |
+
"temperature": temperature,
|
1078 |
+
"top_p": top_p,
|
1079 |
+
"stream": True
|
1080 |
+
}
|
1081 |
+
|
1082 |
+
logger.info(f"Requesting continuation for {role}...")
|
1083 |
+
|
1084 |
+
continuation_response = requests.post(
|
1085 |
+
self.api_url,
|
1086 |
+
headers=self.create_headers(),
|
1087 |
+
json=continuation_payload,
|
1088 |
+
stream=True,
|
1089 |
+
timeout=60
|
1090 |
+
)
|
1091 |
+
|
1092 |
+
if continuation_response.status_code == 200:
|
1093 |
+
for line in continuation_response.iter_lines():
|
1094 |
+
if line:
|
1095 |
+
line = line.decode('utf-8')
|
1096 |
+
if line.startswith("data: "):
|
1097 |
+
data = line[6:]
|
1098 |
+
if data == "[DONE]":
|
1099 |
+
break
|
1100 |
+
try:
|
1101 |
+
chunk = json.loads(data)
|
1102 |
+
if "choices" in chunk and chunk["choices"]:
|
1103 |
+
content = chunk["choices"][0].get("delta", {}).get("content", "")
|
1104 |
+
if content:
|
1105 |
+
yield content
|
1106 |
+
total_content += content
|
1107 |
+
except json.JSONDecodeError:
|
1108 |
+
continue
|
1109 |
+
|
1110 |
+
final_word_count = len(total_content.split())
|
1111 |
+
logger.info(f"Final word count for {role}: {final_word_count}")
|
1112 |
|
1113 |
except requests.exceptions.Timeout:
|
1114 |
yield "โฑ๏ธ API call timed out. Please try again."
|
|
|
1119 |
yield f"โ Error occurred: {str(e)}"
|
1120 |
|
1121 |
def get_system_prompts(self, language: str) -> Dict[str, str]:
|
1122 |
+
"""Get system prompts for all 16 writers with enhanced length requirements"""
|
1123 |
if language == "Korean":
|
1124 |
prompts = {
|
1125 |
"director": "๋น์ ์ 48ํ์ด์ง ์คํธ ์์ค์ ๊ธฐํํ๊ณ ๊ฐ๋
ํ๋ ๋ฌธํ ๊ฐ๋
์์
๋๋ค. ์ฒด๊ณ์ ์ด๊ณ ์ฐฝ์์ ์ธ ์คํ ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์ด๋
๋๋ค.",
|
|
|
1147 |
]
|
1148 |
|
1149 |
for i, role_desc in enumerate(writer_roles, 1):
|
1150 |
+
prompts[f"writer{i}"] = f"๋น์ ์ {role_desc} ๋ฐ๋์ 1500-1800๋จ์ด๋ฅผ ์์ฑํ์ธ์. ์ด๋ ์ ๋์ ์ธ ์๊ตฌ์ฌํญ์
๋๋ค."
|
1151 |
|
1152 |
return prompts
|
1153 |
else:
|
|
|
1177 |
]
|
1178 |
|
1179 |
for i, role_desc in enumerate(writer_roles, 1):
|
1180 |
+
prompts[f"writer{i}"] = f"You are {role_desc} You MUST write 1500-1800 words. This is an absolute requirement."
|
1181 |
|
1182 |
return prompts
|
1183 |
|
|
|
1938 |
|
1939 |
return interface
|
1940 |
|
1941 |
+
# ๋น ๋ฅธ ํ
์คํธ๋ฅผ ์ํ ์ถ์ ๋ฒ์ ์ถ๊ฐ
|
1942 |
+
def create_quick_test_interface():
|
1943 |
+
"""๋น ๋ฅธ ํ
์คํธ๋ฅผ ์ํ ๊ฐ๋จํ ์ธํฐํ์ด์ค"""
|
1944 |
+
with gr.Blocks(title="Novel Writing System - Quick Test") as interface:
|
1945 |
+
gr.Markdown("# ๐ Quick Test Mode - 3 Writers Only")
|
1946 |
+
|
1947 |
+
with gr.Row():
|
1948 |
+
query_input = gr.Textbox(label="Novel Theme", placeholder="Enter theme...")
|
1949 |
+
language = gr.Radio(["English", "Korean"], value="English", label="Language")
|
1950 |
+
submit_btn = gr.Button("Start Quick Test")
|
1951 |
+
|
1952 |
+
output = gr.Textbox(label="Output", lines=20)
|
1953 |
+
|
1954 |
+
def quick_test(query, lang):
|
1955 |
+
system = NovelWritingSystem()
|
1956 |
+
# 3๋ช
์ ์๊ฐ๋ง ํ
์คํธ
|
1957 |
+
stages = ["Director Plan", "Writer 1", "Writer 2", "Writer 3", "Final"]
|
1958 |
+
result = f"Testing with theme: {query}\n\n"
|
1959 |
+
|
1960 |
+
for stage in stages:
|
1961 |
+
result += f"Processing {stage}...\n"
|
1962 |
+
time.sleep(1) # ์๋ฎฌ๋ ์ด์
|
1963 |
+
|
1964 |
+
return result + "\nQuick test complete!"
|
1965 |
+
|
1966 |
+
submit_btn.click(quick_test, inputs=[query_input, language], outputs=output)
|
1967 |
+
|
1968 |
+
return interface
|
1969 |
+
|
1970 |
# Main execution
|
1971 |
if __name__ == "__main__":
|
1972 |
+
import sys
|
1973 |
+
|
1974 |
logger.info("Starting SOMA Novel Writing System...")
|
1975 |
|
1976 |
# Check environment
|
|
|
1984 |
NovelDatabase.init_db()
|
1985 |
logger.info("Database initialized successfully.")
|
1986 |
|
1987 |
+
# ๋น ๋ฅธ ํ
์คํธ ๋ชจ๋ ์ต์
|
1988 |
+
if "--quick-test" in sys.argv:
|
1989 |
+
logger.info("Running in QUICK TEST mode")
|
1990 |
+
interface = create_quick_test_interface()
|
1991 |
+
else:
|
1992 |
+
logger.info("Running in FULL mode")
|
1993 |
+
interface = create_interface()
|
1994 |
|
1995 |
interface.launch(
|
1996 |
server_name="0.0.0.0",
|