Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -754,7 +754,7 @@ Provide specific, practical improvements."""
|
|
754 |
|
755 |
# --- Random theme generator ---
|
756 |
def generate_random_webnovel_theme(genre: str, language: str) -> str:
|
757 |
-
"""Generate random web novel theme using novel_themes.json"""
|
758 |
try:
|
759 |
# Load novel_themes.json
|
760 |
json_path = Path("novel_themes.json")
|
@@ -767,7 +767,7 @@ def generate_random_webnovel_theme(genre: str, language: str) -> str:
|
|
767 |
|
768 |
# Map genres to theme data
|
769 |
genre_mapping = {
|
770 |
-
"๋ก๋งจ์ค": ["romance_fantasy_villainess", "villainess_wants_to_be_lazy"],
|
771 |
"๋กํ": ["romance_fantasy_villainess", "BL_novel_transmigration", "regression_childcare"],
|
772 |
"ํํ์ง": ["system_constellation_hunter", "tower_ascension_challenger", "necromancer_solo_leveling"],
|
773 |
"ํํ": ["system_constellation_hunter", "chaebol_family_intrigue", "post_apocalypse_survival"],
|
@@ -792,17 +792,25 @@ def generate_random_webnovel_theme(genre: str, language: str) -> str:
|
|
792 |
character_data = themes_data["characters"].get(selected_character_key, {})
|
793 |
character_variations = character_data.get("variations", [])
|
794 |
character_desc = random.choice(character_variations) if character_variations else ""
|
|
|
795 |
|
796 |
# Get settings
|
797 |
settings = compatible_elements.get("settings", [])
|
798 |
selected_setting = random.choice(settings) if settings else ""
|
799 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
800 |
# Get mechanics
|
801 |
mechanics_keys = list(themes_data.get("core_mechanics", {}).keys())
|
802 |
selected_mechanic = random.choice(mechanics_keys) if mechanics_keys else ""
|
803 |
mechanic_data = themes_data["core_mechanics"].get(selected_mechanic, {})
|
804 |
plot_points = mechanic_data.get("plot_points", [])
|
805 |
-
|
806 |
|
807 |
# Get hooks
|
808 |
hook_types = list(themes_data.get("episode_hooks", {}).keys())
|
@@ -812,72 +820,93 @@ def generate_random_webnovel_theme(genre: str, language: str) -> str:
|
|
812 |
|
813 |
# Get items/artifacts
|
814 |
item_categories = list(themes_data.get("key_items_and_artifacts", {}).keys())
|
815 |
-
if item_categories:
|
816 |
selected_category = random.choice(item_categories)
|
817 |
items = themes_data["key_items_and_artifacts"].get(selected_category, [])
|
818 |
selected_item = random.choice(items) if items else ""
|
819 |
else:
|
820 |
selected_item = ""
|
821 |
|
822 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
823 |
if language == "Korean":
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
|
|
|
|
|
|
|
|
849 |
else: # English
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
|
880 |
-
return
|
881 |
|
882 |
except Exception as e:
|
883 |
logger.error(f"Error generating theme from JSON: {e}")
|
|
|
754 |
|
755 |
# --- Random theme generator ---
|
756 |
def generate_random_webnovel_theme(genre: str, language: str) -> str:
|
757 |
+
"""Generate random web novel theme using novel_themes.json and LLM"""
|
758 |
try:
|
759 |
# Load novel_themes.json
|
760 |
json_path = Path("novel_themes.json")
|
|
|
767 |
|
768 |
# Map genres to theme data
|
769 |
genre_mapping = {
|
770 |
+
"๋ก๋งจ์ค": ["romance_fantasy_villainess", "villainess_wants_to_be_lazy", "chaebol_family_intrigue"],
|
771 |
"๋กํ": ["romance_fantasy_villainess", "BL_novel_transmigration", "regression_childcare"],
|
772 |
"ํํ์ง": ["system_constellation_hunter", "tower_ascension_challenger", "necromancer_solo_leveling"],
|
773 |
"ํํ": ["system_constellation_hunter", "chaebol_family_intrigue", "post_apocalypse_survival"],
|
|
|
792 |
character_data = themes_data["characters"].get(selected_character_key, {})
|
793 |
character_variations = character_data.get("variations", [])
|
794 |
character_desc = random.choice(character_variations) if character_variations else ""
|
795 |
+
character_traits = character_data.get("traits", [])
|
796 |
|
797 |
# Get settings
|
798 |
settings = compatible_elements.get("settings", [])
|
799 |
selected_setting = random.choice(settings) if settings else ""
|
800 |
|
801 |
+
# Get all available settings for more variety
|
802 |
+
all_settings = themes_data.get("settings", {})
|
803 |
+
setting_details = []
|
804 |
+
for setting_list in all_settings.values():
|
805 |
+
setting_details.extend(setting_list)
|
806 |
+
specific_setting = random.choice(setting_details) if setting_details else selected_setting
|
807 |
+
|
808 |
# Get mechanics
|
809 |
mechanics_keys = list(themes_data.get("core_mechanics", {}).keys())
|
810 |
selected_mechanic = random.choice(mechanics_keys) if mechanics_keys else ""
|
811 |
mechanic_data = themes_data["core_mechanics"].get(selected_mechanic, {})
|
812 |
plot_points = mechanic_data.get("plot_points", [])
|
813 |
+
reader_questions = mechanic_data.get("reader_questions", [])
|
814 |
|
815 |
# Get hooks
|
816 |
hook_types = list(themes_data.get("episode_hooks", {}).keys())
|
|
|
820 |
|
821 |
# Get items/artifacts
|
822 |
item_categories = list(themes_data.get("key_items_and_artifacts", {}).keys())
|
823 |
+
if item_categories and genre in ["ํํ์ง", "ํํ", "๋ฌดํ"]:
|
824 |
selected_category = random.choice(item_categories)
|
825 |
items = themes_data["key_items_and_artifacts"].get(selected_category, [])
|
826 |
selected_item = random.choice(items) if items else ""
|
827 |
else:
|
828 |
selected_item = ""
|
829 |
|
830 |
+
# Get plot twists
|
831 |
+
twist_categories = list(themes_data.get("plot_twists_and_cliches", {}).keys())
|
832 |
+
if twist_categories:
|
833 |
+
selected_twist_cat = random.choice(twist_categories)
|
834 |
+
twists = themes_data["plot_twists_and_cliches"].get(selected_twist_cat, [])
|
835 |
+
selected_twist = random.choice(twists) if twists else ""
|
836 |
+
else:
|
837 |
+
selected_twist = ""
|
838 |
+
|
839 |
+
# Check for fusion genres
|
840 |
+
fusion_genres = themes_data.get("fusion_genres", {})
|
841 |
+
fusion_options = list(fusion_genres.values())
|
842 |
+
selected_fusion = random.choice(fusion_options) if fusion_options and random.random() > 0.7 else ""
|
843 |
+
|
844 |
+
# Now use LLM to create a coherent theme from these elements
|
845 |
+
system = WebNovelSystem()
|
846 |
+
|
847 |
+
# Create prompt for LLM
|
848 |
if language == "Korean":
|
849 |
+
prompt = f"""๋ค์ ์์๋ค์ ํ์ฉํ์ฌ {genre} ์ฅ๋ฅด์ ๋งค๋ ฅ์ ์ธ ์น์์ค ํ
๋ง๋ฅผ ์์ฑํ์ธ์:
|
850 |
+
|
851 |
+
ใ์ ํ๋ ์์๋คใ
|
852 |
+
- ํต์ฌ ์ฅ๋ฅด: {selected_genre_key}
|
853 |
+
- ์บ๋ฆญํฐ: {character_desc}
|
854 |
+
- ์บ๋ฆญํฐ ํน์ฑ: {', '.join(character_traits[:3])}
|
855 |
+
- ๋ฐฐ๊ฒฝ: {specific_setting}
|
856 |
+
- ํต์ฌ ๋ฉ์ปค๋์ฆ: {selected_mechanic}
|
857 |
+
{"- ์์ดํ
: " + selected_item if selected_item else ""}
|
858 |
+
{"- ๋ฐ์ ์์: " + selected_twist if selected_twist else ""}
|
859 |
+
{"- ํจ์ ์ค์ : " + selected_fusion if selected_fusion else ""}
|
860 |
+
|
861 |
+
ใ์ฐธ๊ณ ํ
ใ
|
862 |
+
{selected_hook}
|
863 |
+
|
864 |
+
ใ๋
์๋ฅผ ์ฌ๋ก์ก์ ์ง๋ฌธ๋คใ
|
865 |
+
{chr(10).join(reader_questions[:2]) if reader_questions else ""}
|
866 |
+
|
867 |
+
์๊ตฌ์ฌํญ:
|
868 |
+
1. ์ ์์๋ค์ ์์ฐ์ค๋ฝ๊ฒ ์ตํฉํ์ฌ ํ๋์ ๋งค๋ ฅ์ ์ธ ์คํ ๋ฆฌ๋ก ๋ง๋์ธ์
|
869 |
+
2. ํ๊ตญ ์น์์ค ๋
์๋ค์ด ์ข์ํ ๋งํ ์ค์ ์ ์ถ๊ฐํ์ธ์
|
870 |
+
3. ์ ๋ชฉ์ด ๋ ์ค๋ฅผ ์ ๋๋ก ๊ตฌ์ฒด์ ์ด๋ฉด์๋ ํฅ๋ฏธ๋ก์ด ์ค์ ์ ๋ง๋์ธ์
|
871 |
+
4. 200-300์ ๋ด์ธ๋ก ๊ฐ๊ฒฐํ๊ฒ ์์ฑํ์ธ์
|
872 |
+
|
873 |
+
ํ์:
|
874 |
+
ํ ์ค์ ๊ฐ๋ ฌํ ๋์
๋ฌธ์ผ๋ก ์์ํ์ธ์.
|
875 |
+
๊ทธ ๋ค์ ์ฃผ์ธ๊ณต์ ์ํฉ๊ณผ ๋ชฉํ๋ฅผ ๋ช
ํํ ์ ์ํ์ธ์.
|
876 |
+
๋ง์ง๋ง์ผ๋ก ๋
์์ ๊ธฐ๋๊ฐ์ ์๊ทนํ๋ ์์๋ฅผ ์ถ๊ฐํ์ธ์."""
|
877 |
+
|
878 |
else: # English
|
879 |
+
prompt = f"""Create an engaging web novel theme for {genre} genre using these elements:
|
880 |
+
|
881 |
+
ใSelected Elementsใ
|
882 |
+
- Core genre: {selected_genre_key}
|
883 |
+
- Character: {character_desc}
|
884 |
+
- Character traits: {', '.join(character_traits[:3])}
|
885 |
+
- Setting: {specific_setting}
|
886 |
+
- Core mechanism: {selected_mechanic}
|
887 |
+
{"- Item: " + selected_item if selected_item else ""}
|
888 |
+
{"- Twist: " + selected_twist if selected_twist else ""}
|
889 |
+
{"- Fusion: " + selected_fusion if selected_fusion else ""}
|
890 |
+
|
891 |
+
ใReference Hookใ
|
892 |
+
{selected_hook}
|
893 |
+
|
894 |
+
Requirements:
|
895 |
+
1. Naturally blend these elements into one attractive story
|
896 |
+
2. Add settings that Korean web novel readers would love
|
897 |
+
3. Make it specific and intriguing enough to suggest a title
|
898 |
+
4. Keep it concise, around 200-300 characters
|
899 |
+
|
900 |
+
Format:
|
901 |
+
Start with one powerful opening line.
|
902 |
+
Then clearly present the protagonist's situation and goal.
|
903 |
+
Finally add elements that spark reader anticipation."""
|
904 |
+
|
905 |
+
# Call LLM to generate theme
|
906 |
+
messages = [{"role": "user", "content": prompt}]
|
907 |
+
generated_theme = system.call_llm_sync(messages, "writer", language)
|
908 |
|
909 |
+
return generated_theme
|
910 |
|
911 |
except Exception as e:
|
912 |
logger.error(f"Error generating theme from JSON: {e}")
|