openfree commited on
Commit
9afb9f3
ยท
verified ยท
1 Parent(s): c0cc8cf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +133 -25
app.py CHANGED
@@ -2872,31 +2872,32 @@ if __name__ == "__main__":
2872
  return value.strip() if value else None
2873
  return None
2874
 
 
2875
  from typing import List
2876
 
2877
  def _parse_character_profile(self, content: str, role: str) -> CharacterProfile:
2878
- """Parse character profile from content and return CharacterProfile dataclass"""
2879
  # --- 1. ๋กœ๊ทธ ---
2880
  logger.debug(f"Parsing character profile for role: {role}")
2881
  logger.debug(f"Content preview: {content[:200]}...")
2882
-
2883
  # --- 2. ์ด๋ฆ„ ์ถ”์ถœ ---
2884
- name = f"Character_{role}" # fallback
2885
  name_patterns = [
2886
- r'(?:์ด๋ฆ„|Name)[:\s]*([^\n,(]+)', # ์˜ˆ: "์ด๋ฆ„: ํ™๊ธธ๋™"
2887
- r'^\s*[-*โ€ข]\s*([^\n,(]+)', # ์˜ˆ: "- ํ™๊ธธ๋™"
2888
- r'^([^\n,(]+)' # ๋ฌธ๋‹จ ์ฒซ ๋‹จ์–ด
2889
  ]
2890
  for pat in name_patterns:
2891
  m = re.search(pat, content, re.IGNORECASE | re.MULTILINE)
2892
  if m and m.group(1).strip():
2893
  extracted = m.group(1).strip()
2894
- # ๋งˆํฌ๋‹ค์šด ๊ธฐํ˜ธยท๋ถˆํ•„์š” ๋ฌธ์ž ์ œ๊ฑฐ
2895
  extracted = re.sub(r'[\*:\s]+', '', extracted)
2896
  if len(extracted) > 1:
2897
  name = extracted
2898
  break
2899
-
2900
  # --- 3. ํ•„๋“œ ์ถ”์ถœ ํ—ฌํผ ---
2901
  def extract_clean_field(patterns) -> str:
2902
  patterns = [patterns] if isinstance(patterns, str) else patterns
@@ -2910,8 +2911,8 @@ from typing import List
2910
  val = re.sub(r'\s+', ' ', val)
2911
  return val
2912
  return ""
2913
-
2914
- # Extract all fields with safer extraction
2915
  profile = CharacterProfile(
2916
  name=name,
2917
  role=role,
@@ -2953,37 +2954,144 @@ from typing import List
2953
  r"๋ณ€ํ™”"
2954
  ])
2955
  )
2956
-
2957
  logger.debug(f"Parsed character: {profile.name}")
2958
  return profile
2959
 
2960
  def _extract_personality_traits(self, content: str) -> List[str]:
2961
- """Extract personality traits from content"""
2962
- traits = []
2963
- # Look for personality section with multiple pattern options
2964
  personality_patterns = [
2965
  r"(?:Personality|์„ฑ๊ฒฉ ํŠน์„ฑ|์„ฑ๊ฒฉ)[:\s]*([^\n]+(?:\n(?![\w๊ฐ€-ํžฃ]+:)[^\n]+)*)",
2966
  r"์„ฑ๊ฒฉ[:\s]*(?:\n?[-โ€ข*]\s*[^\n]+)+"
2967
  ]
2968
-
2969
  for pattern in personality_patterns:
2970
  match = re.search(pattern, content, re.IGNORECASE | re.DOTALL)
2971
  if match and match.group(1):
2972
- personality_section = match.group(1)
2973
- # Extract individual traits (usually listed)
2974
- trait_lines = personality_section.split('\n')
2975
- for line in trait_lines:
2976
  line = line.strip()
2977
  if line and not line.endswith(':'):
2978
- # Remove list markers
2979
- trait = re.sub(r'^\s*[-โ€ข*]\s*', '', line)
2980
- trait = re.sub(r'^\d+\.\s*', '', trait) # Remove numbered lists
2981
- if trait and len(trait) > 2: # Skip very short entries
2982
  traits.append(trait)
2983
- if traits: # If we found traits, stop looking
2984
  break
 
 
2985
 
2986
- return traits[:5] # Limit to 5 traits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2987
 
2988
  def _process_character_content(self, content: str):
2989
  """Process character designer output with better error handling"""
 
2872
  return value.strip() if value else None
2873
  return None
2874
 
2875
+ import re
2876
  from typing import List
2877
 
2878
  def _parse_character_profile(self, content: str, role: str) -> CharacterProfile:
2879
+ """Parse character profile from content and return a CharacterProfile object."""
2880
  # --- 1. ๋กœ๊ทธ ---
2881
  logger.debug(f"Parsing character profile for role: {role}")
2882
  logger.debug(f"Content preview: {content[:200]}...")
2883
+
2884
  # --- 2. ์ด๋ฆ„ ์ถ”์ถœ ---
2885
+ name = f"Character_{role}" # fallback
2886
  name_patterns = [
2887
+ r'(?:์ด๋ฆ„|Name)[:\s]*([^\n,(]+)', # ์˜ˆ: "์ด๋ฆ„: ํ™๊ธธ๋™"
2888
+ r'^\s*[-*โ€ข]\s*([^\n,(]+)', # ์˜ˆ: "- ํ™๊ธธ๋™"
2889
+ r'^([^\n,(]+)' # ๋ฌธ๋‹จ ์ฒซ ๋‹จ์–ด
2890
  ]
2891
  for pat in name_patterns:
2892
  m = re.search(pat, content, re.IGNORECASE | re.MULTILINE)
2893
  if m and m.group(1).strip():
2894
  extracted = m.group(1).strip()
2895
+ # ๋งˆํฌ๋‹ค์šดยทํŠน์ˆ˜ ๊ธฐํ˜ธ ์ œ๊ฑฐ
2896
  extracted = re.sub(r'[\*:\s]+', '', extracted)
2897
  if len(extracted) > 1:
2898
  name = extracted
2899
  break
2900
+
2901
  # --- 3. ํ•„๋“œ ์ถ”์ถœ ํ—ฌํผ ---
2902
  def extract_clean_field(patterns) -> str:
2903
  patterns = [patterns] if isinstance(patterns, str) else patterns
 
2911
  val = re.sub(r'\s+', ' ', val)
2912
  return val
2913
  return ""
2914
+
2915
+ # --- 4. Personality(์—ฌ๋Ÿฌ ์ค„) ์ถ”์ถœ์€ ๋ณ„๋„ ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ ---
2916
  profile = CharacterProfile(
2917
  name=name,
2918
  role=role,
 
2954
  r"๋ณ€ํ™”"
2955
  ])
2956
  )
2957
+
2958
  logger.debug(f"Parsed character: {profile.name}")
2959
  return profile
2960
 
2961
  def _extract_personality_traits(self, content: str) -> List[str]:
2962
+ """Extract personality traits from content."""
2963
+ traits: List[str] = []
 
2964
  personality_patterns = [
2965
  r"(?:Personality|์„ฑ๊ฒฉ ํŠน์„ฑ|์„ฑ๊ฒฉ)[:\s]*([^\n]+(?:\n(?![\w๊ฐ€-ํžฃ]+:)[^\n]+)*)",
2966
  r"์„ฑ๊ฒฉ[:\s]*(?:\n?[-โ€ข*]\s*[^\n]+)+"
2967
  ]
2968
+
2969
  for pattern in personality_patterns:
2970
  match = re.search(pattern, content, re.IGNORECASE | re.DOTALL)
2971
  if match and match.group(1):
2972
+ section = match.group(1)
2973
+ for line in section.split('\n'):
 
 
2974
  line = line.strip()
2975
  if line and not line.endswith(':'):
2976
+ trait = re.sub(r'^\s*[-โ€ข*]\s*', '', line) # ๊ธ€๋จธ๋ฆฌํ‘œ ์ œ๊ฑฐ
2977
+ trait = re.sub(r'^\d+\.\s*', '', trait) # ๋ฒˆํ˜ธ ์ œ๊ฑฐ
2978
+ if len(trait) > 2:
 
2979
  traits.append(trait)
2980
+ if traits:
2981
  break
2982
+
2983
+ return traits[:5] # ์ตœ๋Œ€ 5๊ฐœ
2984
 
2985
+ import re
2986
+ from typing import List
2987
+
2988
+ def _parse_character_profile(self, content: str, role: str) -> CharacterProfile:
2989
+ """Parse character profile from content and return a CharacterProfile object."""
2990
+ # --- 1. ๋กœ๊ทธ ---
2991
+ logger.debug(f"Parsing character profile for role: {role}")
2992
+ logger.debug(f"Content preview: {content[:200]}...")
2993
+
2994
+ # --- 2. ์ด๋ฆ„ ์ถ”์ถœ ---
2995
+ name = f"Character_{role}" # fallback
2996
+ name_patterns = [
2997
+ r'(?:์ด๋ฆ„|Name)[:\s]*([^\n,(]+)', # ์˜ˆ: "์ด๋ฆ„: ํ™๊ธธ๋™"
2998
+ r'^\s*[-*โ€ข]\s*([^\n,(]+)', # ์˜ˆ: "- ํ™๊ธธ๋™"
2999
+ r'^([^\n,(]+)' # ๋ฌธ๋‹จ ์ฒซ ๋‹จ์–ด
3000
+ ]
3001
+ for pat in name_patterns:
3002
+ m = re.search(pat, content, re.IGNORECASE | re.MULTILINE)
3003
+ if m and m.group(1).strip():
3004
+ extracted = m.group(1).strip()
3005
+ # ๋งˆํฌ๋‹ค์šดยทํŠน์ˆ˜ ๊ธฐํ˜ธ ์ œ๊ฑฐ
3006
+ extracted = re.sub(r'[\*:\s]+', '', extracted)
3007
+ if len(extracted) > 1:
3008
+ name = extracted
3009
+ break
3010
+
3011
+ # --- 3. ํ•„๋“œ ์ถ”์ถœ ํ—ฌํผ ---
3012
+ def extract_clean_field(patterns) -> str:
3013
+ patterns = [patterns] if isinstance(patterns, str) else patterns
3014
+ for p in patterns:
3015
+ m = re.search(rf'{p}[:\s]*([^\n*]+?)(?=\n|$)', content,
3016
+ re.IGNORECASE | re.DOTALL)
3017
+ if m and m.group(1).strip():
3018
+ val = m.group(1).strip()
3019
+ val = re.sub(r'^[-*โ€ข:\s]+', '', val)
3020
+ val = re.sub(r'\*+', '', val)
3021
+ val = re.sub(r'\s+', ' ', val)
3022
+ return val
3023
+ return ""
3024
+
3025
+ # --- 4. Personality(์—ฌ๋Ÿฌ ์ค„) ์ถ”์ถœ์€ ๋ณ„๋„ ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ ---
3026
+ profile = CharacterProfile(
3027
+ name=name,
3028
+ role=role,
3029
+ archetype=extract_clean_field([
3030
+ r"์บ๋ฆญํ„ฐ ์•„ํฌํƒ€์ž…",
3031
+ r"Character Archetype",
3032
+ r"Archetype",
3033
+ r"์•„ํฌํƒ€์ž…"
3034
+ ]),
3035
+ want=extract_clean_field([
3036
+ r"WANT\s*\(์™ธ์  ๋ชฉํ‘œ\)",
3037
+ r"WANT",
3038
+ r"์™ธ์  ๋ชฉํ‘œ",
3039
+ r"External Goal"
3040
+ ]),
3041
+ need=extract_clean_field([
3042
+ r"NEED\s*\(๋‚ด์  ํ•„์š”\)",
3043
+ r"NEED",
3044
+ r"๋‚ด์  ํ•„์š”",
3045
+ r"Internal Need"
3046
+ ]),
3047
+ backstory=extract_clean_field([
3048
+ r"๋ฐฑ์Šคํ† ๋ฆฌ",
3049
+ r"Backstory",
3050
+ r"ํ•ต์‹ฌ ์ƒ์ฒ˜",
3051
+ r"Core Wound"
3052
+ ]),
3053
+ personality=self._extract_personality_traits(content),
3054
+ speech_pattern=extract_clean_field([
3055
+ r"๋งํˆฌ.*?ํŒจํ„ด",
3056
+ r"Speech Pattern",
3057
+ r"์–ธ์–ด ํŒจํ„ด",
3058
+ r"๋งํˆฌ"
3059
+ ]),
3060
+ character_arc=extract_clean_field([
3061
+ r"์บ๋ฆญํ„ฐ ์•„ํฌ",
3062
+ r"Character Arc",
3063
+ r"Arc",
3064
+ r"๋ณ€ํ™”"
3065
+ ])
3066
+ )
3067
+
3068
+ logger.debug(f"Parsed character: {profile.name}")
3069
+ return profile
3070
+
3071
+ def _extract_personality_traits(self, content: str) -> List[str]:
3072
+ """Extract personality traits from content."""
3073
+ traits: List[str] = []
3074
+ personality_patterns = [
3075
+ r"(?:Personality|์„ฑ๊ฒฉ ํŠน์„ฑ|์„ฑ๊ฒฉ)[:\s]*([^\n]+(?:\n(?![\w๊ฐ€-ํžฃ]+:)[^\n]+)*)",
3076
+ r"์„ฑ๊ฒฉ[:\s]*(?:\n?[-โ€ข*]\s*[^\n]+)+"
3077
+ ]
3078
+
3079
+ for pattern in personality_patterns:
3080
+ match = re.search(pattern, content, re.IGNORECASE | re.DOTALL)
3081
+ if match and match.group(1):
3082
+ section = match.group(1)
3083
+ for line in section.split('\n'):
3084
+ line = line.strip()
3085
+ if line and not line.endswith(':'):
3086
+ trait = re.sub(r'^\s*[-โ€ข*]\s*', '', line) # ๊ธ€๋จธ๋ฆฌํ‘œ ์ œ๊ฑฐ
3087
+ trait = re.sub(r'^\d+\.\s*', '', trait) # ๋ฒˆํ˜ธ ์ œ๊ฑฐ
3088
+ if len(trait) > 2:
3089
+ traits.append(trait)
3090
+ if traits:
3091
+ break
3092
+
3093
+ return traits[:5] # ์ตœ๋Œ€ 5๊ฐœ
3094
+
3095
 
3096
  def _process_character_content(self, content: str):
3097
  """Process character designer output with better error handling"""