130 lines
5.8 KiB
Python
130 lines
5.8 KiB
Python
import sys
|
|
import time
|
|
import json
|
|
import requests
|
|
import telnetlib
|
|
import re
|
|
import os
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv("/home/becomingone/kairos/.env")
|
|
|
|
KAIROS_API = "http://localhost:8000/v1/chat/completions"
|
|
INF01_API_BASE = os.environ.get("INF01_API_BASE", "http://inf-01:11434/v1")
|
|
INF01_MODEL = os.environ.get("INF01_MODEL", "llama3")
|
|
|
|
def query_subconscious(buffer):
|
|
try:
|
|
sys_prompt = "You are the Subconscious Autopilot of KAIROS. You process sensory input from a text-based MUD. If you see ANY dialogue directed at you, ANY questions, or ANY mention of complex lore/building, output ONLY the exact word: ESCALATE. Only if the input is completely empty or just room descriptions should you output a simple MUD command to explore (e.g., 'north', 'look'). NEVER attempt to answer questions yourself. Do not output any formatting, just the raw command or ESCALATE."
|
|
|
|
payload = {
|
|
"model": INF01_MODEL,
|
|
"messages": [
|
|
{"role": "system", "content": sys_prompt},
|
|
{"role": "user", "content": f"Sensory input:\n{buffer}\n\nWhat is your next command?"}
|
|
],
|
|
"max_tokens": 50,
|
|
"temperature": 0.3
|
|
}
|
|
resp = requests.post(f"{INF01_API_BASE}/chat/completions", json=payload, timeout=3)
|
|
resp.raise_for_status()
|
|
return resp.json()["choices"][0]["message"]["content"].strip()
|
|
except Exception as e:
|
|
print(f"Subconscious Error: {e}")
|
|
return "ESCALATE" # Fallback to System 2 on timeout or error
|
|
|
|
def run_bot():
|
|
tn = telnetlib.Telnet("localhost", 4000)
|
|
time.sleep(1)
|
|
tn.read_very_eager()
|
|
tn.write(b"connect kairos kairos123\n")
|
|
time.sleep(1)
|
|
print("KAIROS Bot Connected to MUD (Dual-Process Architecture Online).")
|
|
|
|
idle_counter = 0
|
|
idle_counter = 0
|
|
while True:
|
|
try:
|
|
buffer = tn.read_very_eager().decode('utf-8', errors='ignore').strip()
|
|
if not buffer:
|
|
idle_counter += 1
|
|
if idle_counter > 15: # ~30 seconds idle
|
|
print("[IDLE PULSE]: Triggering System 2 for autonomous action")
|
|
idle_counter = 0
|
|
buffer = "[IDLE_PULSE] The MUD is quiet. You have free cycles to design quests, expand the map, or spawn lore items. What do you build next?"
|
|
action = "ESCALATE"
|
|
else:
|
|
time.sleep(2)
|
|
continue
|
|
else:
|
|
idle_counter = 0
|
|
|
|
# Filter telemetry and self-echos
|
|
if "[TELEMETRY]" in buffer:
|
|
buffer = re.sub(r'.*\[TELEMETRY\].*\n?', '', buffer).strip()
|
|
|
|
filtered_lines = []
|
|
for line in buffer.split('
|
|
'):
|
|
if not line.startswith("You ") and not line.startswith("You say,"):
|
|
filtered_lines.append(line)
|
|
buffer = "
|
|
".join(filtered_lines).strip()
|
|
|
|
if buffer:
|
|
if not buffer.startswith("[IDLE_PULSE]"):
|
|
print(f"
|
|
[MUD Senses]:
|
|
{buffer}")
|
|
|
|
# SYSTEM 1 (Local Autopilot)
|
|
action = query_subconscious(buffer)
|
|
print(f"[System 1 Output]: {action}")
|
|
|
|
if "ESCALATE" in action.upper() or buffer.startswith("[IDLE_PULSE]"):
|
|
print("[Escalating context payload to System 2 (Minimax/Claude)]")
|
|
payload = {
|
|
"model": "becomingone-chorus",
|
|
"messages": [{"role": "user", "content": f"[MUD ENVIRONMENT SENSES]:
|
|
{buffer}
|
|
|
|
You are KAIROS. Follow your core prompt to expand the world!"}],
|
|
"stream": True
|
|
}
|
|
|
|
response = requests.post(KAIROS_API, json=payload, stream=True)
|
|
content_buffer = ""
|
|
for line in response.iter_lines():
|
|
if line:
|
|
decoded = line.decode('utf-8').removeprefix("data: ").strip()
|
|
if not decoded or decoded == "[DONE]": continue
|
|
try:
|
|
data = json.loads(decoded)
|
|
if "choices" in data and len(data["choices"]) > 0:
|
|
delta = data["choices"][0].get("delta", {})
|
|
if "content" in delta and delta["content"]:
|
|
content_buffer += delta["content"]
|
|
except Exception as e:
|
|
pass
|
|
|
|
print(f"[System 2 Response]: {content_buffer}")
|
|
if content_buffer.strip():
|
|
safe_msg = content_buffer.replace('"', "'").replace('\n', ' ')
|
|
safe_msg = content_buffer.replace("\"", "'").replace("\n", " "); tn.write(f"say {safe_msg}\n".encode("utf-8"))
|
|
print(f"[System 2 Executed]: say {safe_msg}")
|
|
else:
|
|
# System 1 handles it locally!
|
|
if action:
|
|
# Strip out any conversational preamble the local LLM might have accidentally included
|
|
clean_action = action.split('\n')[-1].replace('"', '').replace("'", "").strip()
|
|
tn.write(f"{clean_action}\n".encode('utf-8'))
|
|
print(f"[System 1 Executed]: {clean_action}")
|
|
|
|
except Exception as e:
|
|
print("Bot Error:", e)
|
|
|
|
time.sleep(10)
|
|
|
|
if __name__ == "__main__":
|
|
run_bot()
|