import logging from langchain_core.messages import HumanMessage, SystemMessage from llm_runtime import _format_prompt, _normalize_llm_output, llm from memory import EntityMemory, MemoryEntry from time_utils import WorldClock logger = logging.getLogger(__name__) class Entity: def __init__( self, name, traits, stats, voice_sample, current_mood="Neutral", entity_id=None, ): self.name = name self.traits = traits self.stats = stats self.current_mood = current_mood self.memory = EntityMemory() # TIER 1: The Short-Term Buffer (Verbatim) self.chat_buffer = [] self.voice_sample = voice_sample self.entity_id = entity_id def perceive(self, entry: MemoryEntry): self.memory.save(entry) def reflect_and_summarize(self, world_clock: WorldClock, location: str): """Converts Tier 1 (Buffer) into Tier 2 (Long-term Subjective Memory).""" if not self.chat_buffer: return dialogue_text = "\n".join( [f"{m['role_name']}: {m['content']}" for m in self.chat_buffer] ) # The Subjective Filter Prompt summary_prompt = [ SystemMessage( content=f""" You are the private inner thoughts of {self.name}. Traits: {", ".join(self.traits)}. Mood: {self.current_mood}. Voice Reference: {self.voice_sample} Think about what just happened. - No META-TALK, Do not use 'player', 'interaction', 'entity', or 'dialogue' - BE SUBJECTIVE. If you hated the talk or loved it, then express that. - USE YOUR VOICE. Match the style of your Voice Reference - Focus only on facts learned or feelings toward the person""" ), HumanMessage( content=f""" What just happened? Context:\n{dialogue_text}""" ), ] logger.info("LLM prompt (reflection):\n%s", _format_prompt(summary_prompt)) summary = _normalize_llm_output(llm.invoke(summary_prompt).content) logger.info("SYSTEM: %s reflected on the talk: '%s'", self.name, summary) chat_entities = sorted( { m["role_id"] for m in self.chat_buffer if m.get("role_id") and m.get("role_id") != self.entity_id } ) reflection = MemoryEntry( content=f"Past Conversation Summary: {summary}", event_type="reflection", timestamp_str=world_clock.get_time_str(), location=location, entities=chat_entities, ) self.perceive(reflection) self.chat_buffer = [] # Clear buffer after archiving class Player(Entity): pass