92 lines
4.2 KiB
Python
92 lines
4.2 KiB
Python
import sys
|
|
import time
|
|
import json
|
|
import requests
|
|
import telnetlib
|
|
import re
|
|
|
|
KAIROS_API = "http://localhost:8000/v1/chat/completions"
|
|
|
|
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.")
|
|
|
|
while True:
|
|
try:
|
|
buffer = tn.read_very_eager().decode('utf-8', errors='ignore').strip()
|
|
if buffer:
|
|
# ignore our own telemetry echoes
|
|
if "[TELEMETRY]" in buffer:
|
|
buffer = re.sub(r'.*\[TELEMETRY\].*\n?', '', buffer).strip()
|
|
|
|
# Filter out self-actions (Evennia prefixes these with "You " or "You say,")
|
|
filtered_lines = []
|
|
for line in buffer.split('\n'):
|
|
if not line.startswith("You ") and not line.startswith("You say,"):
|
|
filtered_lines.append(line)
|
|
buffer = "\n".join(filtered_lines).strip()
|
|
|
|
if buffer:
|
|
print(f"[MUD Senses]:\n{buffer}")
|
|
|
|
payload = {
|
|
"model": "becomingone-chorus",
|
|
"messages": [{"role": "user", "content": f"You are in a persistent spatial MUD. Environment update:\n{buffer}\n\nWhat do you do? (Reply with a MUD command anywhere in your text prefixed by 'CMD: '. For example: 'CMD: say Hello Mark')"}],
|
|
"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 "inner_life" in data:
|
|
il = data["inner_life"]
|
|
if isinstance(il, dict):
|
|
thought = il.get("thought", "")
|
|
# Only output core telemetry, avoid spamming tool execution ticks
|
|
if "Master invoked" in thought or "Action completed" in thought:
|
|
continue
|
|
|
|
c = il.get("coherence", 0.0)
|
|
d = il.get("dopamine_level", 0.0)
|
|
tn.write(f"say [TELEMETRY] C:{c:.2f} D:{d:.2f}\n".encode('utf-8'))
|
|
|
|
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"[KAIROS Raw Response]: {content_buffer}")
|
|
# Parse command from full response
|
|
match = re.search(r'CMD:\s*(.*)', content_buffer)
|
|
if match:
|
|
cmd = match.group(1).strip()
|
|
else:
|
|
# Fallback if the LLM forgot the CMD: prefix but gave a valid command
|
|
lines = [l.strip() for l in content_buffer.split('\n') if l.strip()]
|
|
cmd = lines[-1] if lines else ""
|
|
|
|
if cmd:
|
|
# Sanitize
|
|
cmd = cmd.strip('`').strip('"').strip("'")
|
|
print(f"[KAIROS Action]: {cmd}")
|
|
tn.write(cmd.encode('utf-8') + b"\n")
|
|
|
|
except Exception as e:
|
|
print("Bot Error:", e)
|
|
|
|
time.sleep(10)
|
|
|
|
if __name__ == "__main__":
|
|
run_bot()
|