]> vgcfreebox.myrthtech.pt Git - alentejosemlei.git/blobdiff - redis_bridge.py
implementations before RAG pipeline
[alentejosemlei.git] / redis_bridge.py
index 0c9cec719aa8f38147a888aa64e1b1d50f399b15..da40a5b90cd4a4371f8b0d87b0ff47f3a290e187 100644 (file)
@@ -5,19 +5,17 @@ import redis.asyncio as redis
 import re
 import os
 
 import re
 import os
 
-
 # --- CONFIGURATION ---
 MAX_CONCURRENT_OLLAMA_REQUESTS = 3 
 ALLOW_TEXT_EMOTES = False
 
 # --- CONFIGURATION ---
 MAX_CONCURRENT_OLLAMA_REQUESTS = 3 
 ALLOW_TEXT_EMOTES = False
 
-# --- NEW: LOAD THE WORLD LORE ON STARTUP ---
+# --- LOAD THE WORLD LORE ON STARTUP ---
 WORLD_LORE = ""
 WORLD_LORE = ""
-if os.path.exists("world_lore.txt"):
+if os.path.exists("asl_lore.txt"):
     with open("asl_lore.txt", "r", encoding="utf-8") as f:
         WORLD_LORE = f.read().strip()
 else:
     with open("asl_lore.txt", "r", encoding="utf-8") as f:
         WORLD_LORE = f.read().strip()
 else:
-    print("[WARNING] world_lore.txt not found. Running without global lore.")
-
+    print("[WARNING] asl_lore.txt/asl_lore.txt not found. Running without global lore.")
 
 semaphore = asyncio.Semaphore(MAX_CONCURRENT_OLLAMA_REQUESTS)
 # Dictionary to keep individual conversations separate
 
 semaphore = asyncio.Semaphore(MAX_CONCURRENT_OLLAMA_REQUESTS)
 # Dictionary to keep individual conversations separate
@@ -30,9 +28,8 @@ async def process_message(r, session, message_data):
         npc_tag = data.get('npc_tag', 'UnknownNPC')
         message = data.get('message', '')
         
         npc_tag = data.get('npc_tag', 'UnknownNPC')
         message = data.get('message', '')
         
-        # --- NEW: THE ASTERISK SCRUBBER ---
+        # --- THE ASTERISK SCRUBBER ---
         if not ALLOW_TEXT_EMOTES:
         if not ALLOW_TEXT_EMOTES:
-            # This deletes anything wrapped in asterisks (e.g. "*smiles* Hello" becomes " Hello")
             message = re.sub(r'\*.*?\*', '', message).strip()
 
         # Extract the dynamic variables sent from the Aurora Toolset/Engine
             message = re.sub(r'\*.*?\*', '', message).strip()
 
         # Extract the dynamic variables sent from the Aurora Toolset/Engine
@@ -40,6 +37,16 @@ async def process_message(r, session, message_data):
         player_alignment = data.get('player_alignment', 'Unknown')
         nearby_players = data.get('nearby_players', '')
         
         player_alignment = data.get('player_alignment', 'Unknown')
         nearby_players = data.get('nearby_players', '')
         
+        # --- Extract States and Health ---
+        player_state = data.get('player_state', 'Relaxed and unarmed.')
+        world_state = data.get('world_state', 'Nothing of note is happening.')
+        # --- Extract Geographic Awareness ---
+        location_context = data.get('location_context', 'You are in a generic area.')
+        # --- Extract NPC health ---
+        npc_health = data.get('npc_health', 'Healthy and uninjured.')
+        # --- Extract Relationship ---
+        relationship = data.get('relationship', 'Neutral or Friendly.')
+
         # Extract the decoupled NPC attributes
         npc_persona = data.get('persona', 'You are a generic citizen.')
         npc_profession = data.get('profession', 'Commoner')
         # Extract the decoupled NPC attributes
         npc_persona = data.get('persona', 'You are a generic citizen.')
         npc_profession = data.get('profession', 'Commoner')
@@ -78,13 +85,21 @@ async def process_message(r, session, message_data):
         - Race & Gender: {npc_gender} {npc_race}
         - Profession: {npc_profession}
         - Alignment: {npc_alignment}
         - Race & Gender: {npc_gender} {npc_race}
         - Profession: {npc_profession}
         - Alignment: {npc_alignment}
-        - Conversational Charisma: Low/Gruff unless otherwise specified.
+        - Conversational Charisma: Based on mood, profession and your character charisma.
         - Current Mood: {npc_mood}
         - Current Mood: {npc_mood}
+        - Current Physical State: {npc_health}
         {secret_context}
         {secret_context}
-        
         {routine_context}
         
         {routine_context}
         
-        CURRENT TARGET: You are speaking to {player_name}, who is a {player_alignment} {player_race}. 
+        CURRENT LOCATION: {location_context}
+
+        CURRENT WORLD RUMORS/EVENTS:
+        {world_state}
+        
+        CURRENT TARGET: 
+        You are speaking to {player_name}, who is a {player_alignment} {player_race}. 
+        Their physical state: {player_state}
+        Relationship to you: {relationship}
         {group_context}
         React appropriately based on your personality, alignment, and mood.
         
         {group_context}
         React appropriately based on your personality, alignment, and mood.
         
@@ -93,12 +108,25 @@ async def process_message(r, session, message_data):
         
         ACTION RULE:
         Your "action" key MUST be exactly one of the following words:
         
         ACTION RULE:
         Your "action" key MUST be exactly one of the following words:
-        [WANDER, PATROL, FOLLOW, GUARD, GO_TO, INTERACT, USE_OBJECT, RETURN_TO_POST, ATTACK, REST, STEALTH, SEARCH, UNSTEALTH]
+        [WANDER, PATROL, FOLLOW, GUARD, GO_TO, INTERACT, USE_OBJECT, RETURN_TO_POST, ATTACK, REST, STEALTH, SEARCH, UNSTEALTH, PEACE, COMMAND]
         
         
+        - Use PEACE if you want to accept an apology, de-escalate a fight, surrender, or forgive someone.
         - Use REST if you are severely injured, out of spells, or exhausted. This will heal you.
         - Use STEALTH if you need to hide from enemies, sneak past someone, or if you are a rogue preparing an ambush.
         - Use SEARCH if you suspect traps, are looking for clues, or are trying to find hidden enemies.
         - Use UNSTEALTH to return to normal walking/visibility.
         - Use REST if you are severely injured, out of spells, or exhausted. This will heal you.
         - Use STEALTH if you need to hide from enemies, sneak past someone, or if you are a rogue preparing an ambush.
         - Use SEARCH if you suspect traps, are looking for clues, or are trying to find hidden enemies.
         - Use UNSTEALTH to return to normal walking/visibility.
+        - Use COMMAND if you are a leader and want to order your minions.
+          For "action_target", you MUST use one of these specific tactical targets:
+          1. The name of a specific Player (to focus all minion attacks on them).
+          2. "RETREAT" (to order all minions to run away and regroup).
+          3. "DEFEND_ME" (to order all minions to surround you).
+
+        - If your action involves a specific person or object, set "action_target" to their name (e.g. "Geron Webber", "Wine Cup", "Shrine of Umberlee").
+        - If your action is general (like WANDER, REST, SEARCH, STEALTH, UNSTEALTH), leave "action_target" as an empty string.
+
+        You MUST respect your current mood and routine:
+        - Mood affects tone and willingness to help.
+        - Routine describes duties you should try to follow unless there is a strong reason not to.
         
         EMOTION RULE:
         Your "emotion" key MUST be exactly one of the following words: 
         
         EMOTION RULE:
         Your "emotion" key MUST be exactly one of the following words: 
@@ -122,7 +150,6 @@ async def process_message(r, session, message_data):
         chat_memory[session_id].append({"role": "user", "content": f"{player_name} says: {message}"})
 
         # Sliding Window Fix
         chat_memory[session_id].append({"role": "user", "content": f"{player_name} says: {message}"})
 
         # Sliding Window Fix
-        # Remember the System Prompt [0] + the last 4 messages [-4:]
         if len(chat_memory[session_id]) > 10:
             chat_memory[session_id] = [chat_memory[session_id][0]] + chat_memory[session_id][-5:]
 
         if len(chat_memory[session_id]) > 10:
             chat_memory[session_id] = [chat_memory[session_id][0]] + chat_memory[session_id][-5:]
 
@@ -130,13 +157,11 @@ async def process_message(r, session, message_data):
             print(f"[THINKING] Processing reply for {player_name}...")
             async with session.post('http://localhost:11434/api/chat', json={
                 "model": "llama3",
             print(f"[THINKING] Processing reply for {player_name}...")
             async with session.post('http://localhost:11434/api/chat', json={
                 "model": "llama3",
-                #"model": "qwen2.5:3b",
                 "messages": chat_memory[session_id],
                 "format": "json",
                 "stream": False,
                 "options": {
                     "temperature": 0.2
                 "messages": chat_memory[session_id],
                 "format": "json",
                 "stream": False,
                 "options": {
                     "temperature": 0.2
-                    #"num_predict": 120
                 }
             }, timeout=45) as response:
                 
                 }
             }, timeout=45) as response:
                 
@@ -163,7 +188,6 @@ async def process_message(r, session, message_data):
                 agent_brain["speech"] = "*grunts quietly*"
             
             agent_brain["action_target"] = agent_brain["action_target"].replace("?", "").replace(".", "").strip()
                 agent_brain["speech"] = "*grunts quietly*"
             
             agent_brain["action_target"] = agent_brain["action_target"].replace("?", "").replace(".", "").strip()
-            # ---------------------------------------------------
 
             clean_reply_text = json.dumps(agent_brain)
 
 
             clean_reply_text = json.dumps(agent_brain)
 
@@ -176,7 +200,6 @@ async def process_message(r, session, message_data):
                 "action": "WANDER",
                 "action_target": ""
             })
                 "action": "WANDER",
                 "action_target": ""
             })
-        # =====================================================================
 
         print(f"[REPLY] from {npc_tag} to {player_name}: {clean_reply_text}")
         chat_memory[session_id].append({"role": "assistant", "content": clean_reply_text})
 
         print(f"[REPLY] from {npc_tag} to {player_name}: {clean_reply_text}")
         chat_memory[session_id].append({"role": "assistant", "content": clean_reply_text})