Spaces:
Sleeping
Sleeping
# NPC κ°μ κ΄κ³λ₯Ό κ°μ μνμ μνΈμμ©μ κΈ°λ°μΌλ‘ λμ νμ± λ° λ³ν | |
# portfolio/npc_social_network/npc/npc_relationship.py | |
from typing import List, Optional, TYPE_CHECKING | |
from .npc_manager import get_korean_postposition | |
if TYPE_CHECKING: | |
from .npc_memory import Memory | |
from .npc_base import NPC | |
from .npc_manager import NPCManager | |
class SocialProfile: | |
"""νΉμ λμκ³Όμ μ¬νμ κ΄κ³λ₯Ό μ’ ν©μ μΌλ‘ κ΄λ¦¬νλ ν΄λμ€""" | |
def __init__(self, target_name:str): | |
self.target_name = target_name | |
self.score: float = 0.0 # κ΄κ³ μ μ (-100 ~ 100) | |
self.type: str = "stranger" # κ΄κ³ μ ν (e.g., "friend", "rival", "colleague") | |
self.summary: str = f"{target_name}μ λν΄ μμ§ μ λͺ¨λ¦ λλ€." # LLMμ΄ μμ±ν κ΄κ³ μμ½ | |
self.key_memories: List["Memory"] = [] # κ΄κ³μ μν₯μ μ€ ν΅μ¬ κΈ°μ΅ | |
class RelationshipManager: | |
"""SocialProfile κ°μ²΄λ₯Ό μ¬μ©νμ¬ λͺ¨λ κ΄κ³λ₯Ό κ΄λ¦¬""" | |
def __init__(self, owner_npc: "NPC"): | |
self.owner_npc = owner_npc | |
# κ΄κ³ μ¬μ : {μλλ°© μ΄λ¦: SocialProfile κ°μ²΄} | |
self.relationships: dict[str, SocialProfile] = {} | |
def _get_or_create_profile(self, target_name: str) -> SocialProfile: | |
"""λμμ νλ‘νμ΄ μμΌλ©΄ μλ‘ μμ±νκ³ λ°ν""" | |
if target_name not in self.relationships: | |
self.relationships[target_name] = SocialProfile(target_name) | |
return self.relationships[target_name] | |
def update_relationship(self, target_name: str, emotion: str, strength: float=1.0, | |
memory: Optional["Memory"]=None): | |
""" | |
νΉμ κ°μ κΈ°λ°μΌλ‘ κ΄κ³ μμΉ μ‘°μ | |
- κΈμ /λΆμ λ§μ΄ μλλΌ κ°μ μ νμ λ°λ₯Έ μν₯ μ°¨λ³ν | |
- κ°μ , κ°λ, κ·Έλ¦¬κ³ κ΄λ ¨ κΈ°μ΅μ λ°νμΌλ‘ κ΄κ³ μ μ λ° νλ‘ν μ λ°μ΄νΈ | |
""" | |
from .emotion_config import EMOTION_RELATION_IMPACT | |
profile = self._get_or_create_profile(target_name) | |
impact = EMOTION_RELATION_IMPACT.get(emotion, 0.0) | |
delta = impact * strength | |
# κ΄κ³ μ μ μ λ°μ΄νΈ λ° ν΄λ¦¬ν | |
profile.score = max(-100, min(100, profile.score + delta)) | |
# κ΄κ³ μ ν μ λ°μ΄νΈ | |
self.update_relationship_type(profile) | |
# ν΅μ¬ κΈ°μ΅ μΆκ° | |
if memory and memory.importance >= 6: | |
if memory not in profile.key_memories: | |
profile.key_memories.append(memory) | |
profile.key_memories = profile.key_memories[-5:] # μ΅κ·Ό 5κ°λ§ μ μ§ | |
target_npc = self.owner_npc.manager.get_npc_by_name(target_name) | |
target_korean_name = target_npc.korean_name if target_npc else target_name | |
print(f"[{self.owner_npc.korean_name}] '{target_korean_name}'μμ μλ‘μ΄ ν΅μ¬ κΈ°μ΅ μΆκ°: {memory.content[:30]}...") | |
def update_relationship_type(self, profile:SocialProfile): | |
""" | |
μ μμ λ°λΌ κ΄κ³ μ νμ μ λ°μ΄νΈ | |
- κ΄κ³ μ ν μ μ | |
""" | |
if profile.score > 70: profile.type = "best friend" | |
elif profile.score > 30: profile.type = "friend" | |
elif profile.score > 5: profile.type = "acquaintance" | |
elif profile.score < -5: profile.type = "nuisance" | |
elif profile.score < -30: profile.type = "rival" | |
elif profile.score < -70: profile.type = "enemy" | |
else: profile.type = "stranger" | |
def get_relationship_score(self, target_name:str) -> float: | |
"""νμ¬ κ΄κ³ μ μλ₯Ό λ°ν""" | |
profile = self._get_or_create_profile(target_name) | |
return profile.score | |
def get_relationship_summary(self, target_name: str) -> str: | |
"""LLMμ΄ μμ±ν κ΄κ³ μμ½ λ°ν""" | |
profile = self._get_or_create_profile(target_name) | |
return profile.summary | |
def set_relationship(self, target_name: str, relationship_type: str): | |
"""νλ μ΄μ΄ κ°μ λ±μΌλ‘ κ΄κ³ μ νκ³Ό μ μλ₯Ό μ§μ μ€μ """ | |
from .. import simulation_core | |
profile = self._get_or_create_profile(target_name) | |
# μ€μ λ νμ μ λ°λΌ μ μλ₯Ό λΆμ¬ (κ° μ‘°μ κ°λ₯) | |
score_map = { | |
"best friend": 80.0, | |
"friend": 50.0, | |
"acquaintance": 10.0, | |
"stranger": 0.0, | |
"nuisance": -10.0, | |
"rival": -50.0, | |
"enemy": -80.0 | |
} | |
profile.type = relationship_type | |
profile.score = score_map.get(relationship_type, 0.0) | |
target_npc = self.owner_npc.manager.get_npc_by_korean_name(target_name) | |
target_korean_name = target_npc.korean_name if target_npc else target_name | |
self_postposition = get_korean_postposition(self.owner_npc.korean_name, "μ", "λ") | |
target_postposition = get_korean_postposition(target_korean_name, "κ³Ό", "μ") | |
# κ΄κ³ μμ½λ κ°λ¨νκ² μ λ°μ΄νΈ | |
profile.summary = f"{target_korean_name}{target_postposition} {self.owner_npc.korean_name}{self_postposition} {relationship_type} κ΄κ³μ΄λ€." | |
simulation_core.add_log(f"[κ΄κ³ μ€μ ] {self.owner_npc.korean_name} -> {target_korean_name} κ΄κ³κ° '{relationship_type}'(μΌ)λ‘ μ€μ λμμ΅λλ€.") | |
def summarize_relationship(self, target_name: str, npc_manager: "NPCManager"): | |
""" LLMμ μ¬μ©νμ¬ νΉμ λμκ³Όμ κ΄κ³λ₯Ό μ£ΌκΈ°μ μΌλ‘ μμ½νκ³ μ λ°μ΄νΈ""" | |
from ..models.llm_helper import query_llm_with_prompt | |
from .. import simulation_core | |
profile = self._get_or_create_profile(target_name) | |
if not profile.key_memories: | |
return # μμ½ν κΈ°μ΅μ΄ μμΌλ©΄ μ€ν μν¨ | |
target_npc = npc_manager.get_npc_by_name(target_name) | |
target_korean_name = target_npc.korean_name if target_npc else target_name | |
memory_details = "\n".join([f"- {mem.content} (κ°μ : {mem.emotion})" for mem in profile.key_memories]) | |
prompt = f""" | |
# μ§μμ¬ν | |
λμ '{self.owner_npc.korean_name}'μ λλ€. λμ κΈ°μ΅μ λ°νμΌλ‘ '{target_korean_name}'μ λν λμ μκ°κ³Ό κ°μ μ νλ λ¬Έμ₯μΌλ‘ μμ§νκ² μμ½ν΄μ£ΌμΈμ. | |
# '{target_korean_name}'μ(κ³Ό)μ ν΅μ¬ κΈ°μ΅λ€ | |
{memory_details} | |
β '{target_korean_name}'μ λν {self.owner_npc.korean_name}μ μκ°: | |
""" | |
summary = query_llm_with_prompt(prompt).replace("'", "").strip() | |
if summary and "[LLM Error]" not in summary: | |
profile.summary = summary | |
simulation_core.add_log(f"[{self.owner_npc.korean_name}μ κ΄κ³ μμ½ μ λ°μ΄νΈ] {profile.summary}") | |