comms(atlasbot): respond to @atlas mentions and keep context
This commit is contained in:
parent
f18f1df1ce
commit
2d8540907a
@ -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():
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user