Spaces:
Sleeping
Sleeping
File size: 6,801 Bytes
1a3c349 e80a3bc 2cd8c90 e80a3bc d57920f e80a3bc 9009e60 e80a3bc 1a3c349 e80a3bc ce3d575 e80a3bc 1a3c349 e80a3bc 146c098 9df6a7e e80a3bc 9df6a7e e80a3bc 9df6a7e e80a3bc 9df6a7e e80a3bc 9df6a7e e80a3bc 1a3c349 e80a3bc 146c098 b25a43f e80a3bc 9009e60 e80a3bc 1a3c349 2cd8c90 c08ff6f e80a3bc c08ff6f e80a3bc c08ff6f d57920f e80a3bc d28f7eb e80a3bc d57920f e80a3bc c08ff6f e80a3bc c08ff6f e80a3bc |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# 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}")
|