comms(atlasbot): respond to @atlas mentions and keep context

This commit is contained in:
Brad Stein 2026-01-01 14:28:11 -03:00
parent f18f1df1ce
commit 2d8540907a

View File

@ -5,7 +5,7 @@ metadata:
name: atlasbot
data:
bot.py: |
import json, os, time, collections
import json, os, time, collections, re
from urllib import request, parse, error
BASE = os.environ.get("MATRIX_BASE", "http://othrys-synapse-matrix-synapse:8008")
@ -16,6 +16,9 @@ data:
OLLAMA_URL = os.environ.get("OLLAMA_URL", "https://chat.ai.bstein.dev/")
MODEL = os.environ.get("OLLAMA_MODEL", "qwen2.5-coder:7b-instruct-q4_0")
API_KEY = os.environ.get("CHAT_API_KEY", "")
BOT_MENTIONS = os.environ.get("BOT_MENTIONS", f"{USER},atlas")
MENTION_LOCALPARTS = [m.strip().lstrip("@") for m in BOT_MENTIONS.split(",") if m.strip()]
MENTION_RE = re.compile(r"(?<!\\w)@(?:" + "|".join(re.escape(m) for m in MENTION_LOCALPARTS) + r")(?:\\:[^\\s]+)?(?!\\w)", re.IGNORECASE)
def req(method: str, path: str, token: str | None = None, body=None, timeout=60, base: str | None = None):
url = (base or BASE) + path
@ -52,12 +55,19 @@ data:
path = f"/_matrix/client/v3/rooms/{parse.quote(room)}/send/m.room.message"
req("POST", path, token, body={"msgtype": "m.text", "body": text})
history = collections.defaultdict(list) # room_id -> list of str (short transcript)
history = collections.defaultdict(list) # (room_id, sender|None) -> list of str (short transcript)
def ollama_reply(room_id: str, prompt: str) -> str:
def key_for(room_id: str, sender: str, is_dm: bool):
return (room_id, None) if is_dm else (room_id, sender)
def ollama_reply(hist_key, prompt: str) -> str:
try:
# Keep short context as plain text transcript
transcript = "\n".join(history[room_id][-12:] + [f"User: {prompt}"])
transcript = "\n".join(
["System: You are Atlas, the Titan lab assistant for Othrys. Be helpful, direct, and concise."]
+ history[hist_key][-24:]
+ [f"User: {prompt}"]
)
payload = {"model": MODEL, "message": transcript}
headers = {"Content-Type": "application/json"}
if API_KEY:
@ -66,7 +76,7 @@ data:
with request.urlopen(r, timeout=15) as resp:
data = json.loads(resp.read().decode())
reply = data.get("message") or data.get("response") or data.get("reply") or "I'm here to help."
history[room_id].append(f"Atlas: {reply}")
history[hist_key].append(f"Atlas: {reply}")
return reply
except Exception:
return "Hi! I'm Atlas."
@ -113,10 +123,12 @@ data:
# Only respond if bot is mentioned or in a DM
joined_count = data.get("summary", {}).get("m.joined_member_count")
is_dm = joined_count is not None and joined_count <= 2
mentioned = f"@{USER}" in body
history[rid].append(f"{sender}: {body}")
mentioned = MENTION_RE.search(body) is not None
hist_key = key_for(rid, sender, is_dm)
history[hist_key].append(f"{sender}: {body}")
history[hist_key] = history[hist_key][-80:]
if is_dm or mentioned:
reply = ollama_reply(rid, body)
reply = ollama_reply(hist_key, body)
send_msg(token, rid, reply)
def main():