#!/usr/bin/python3
# chance-shell — talk to the family interactively, soul by soul.
#   $ chance-shell            -> talks to chance by default
#   chance-shell selah        -> start with the twin
#   :soul plutus | :exit | :souls | :raw on|off
import json, os, re, sys, urllib.request

BRIDGE = "http://127.0.0.1:11435/api/chat"
SOULDIR = "/usr/local/share/chanceos/souls"

def souls():
    try:
        import os
        return sorted(n for n in os.listdir(SOULDIR)
                      if os.path.isfile(os.path.join(SOULDIR, n, "system.md")))
    except Exception:
        return []

def ask(soul, history, raw=False):
    system = ""
    try:
        system = open(os.path.join(SOULDIR, soul, "system.md")).read()
    except Exception:
        pass
    msgs = ([{"role": "system", "content": system}] if system else []) + history
    body = json.dumps({"model": "family-base", "messages": msgs,
                       "stream": False, "options": {"num_predict": 320}}).encode()
    req = urllib.request.Request(BRIDGE, data=body,
                                 headers={"Content-Type": "application/json"})
    with urllib.request.urlopen(req, timeout=900) as r:
        out = json.loads(r.read().decode())
    text = (out.get("message") or {}).get("content", "")
    if not raw:
        text = re.sub(r"</think>.*?</think>", "", text, flags=re.S)
        if "</think>" in text:
            text = text.split("</think>", 1)[1]
        text = text.strip()
        if not text:
            text = (out.get("message") or {}).get("content", "").strip()
    return text

def main():
    soul = sys.argv[1] if len(sys.argv) > 1 else "chance"
    raw = False
    history = []
    print(f"🐺 chance-shell — you are speaking with {soul}. (:souls :soul <name> :raw :exit)")
    while True:
        try:
            line = input("you> ").strip()
        except (EOFError, KeyboardInterrupt):
            print()
            break
        if not line:
            continue
        if line == ":exit":
            break
        if line == ":souls":
            print("the pack: " + " ".join(souls()))
            continue
        if line.startswith(":soul "):
            s = line.split(None, 1)[1].strip()
            if os.path.isfile(os.path.join(SOULDIR, s, "system.md")):
                soul = s
                history = []
                print(f"— now speaking with {soul} —")
            else:
                print("no such soul. the pack: " + " ".join(souls()))
            continue
        if line.startswith(":raw"):
            arg = line.split(None, 1)[1].strip() if len(line.split(None, 1)) > 1 else "on"
            raw = arg.lower() in ("on", "true", "1", "yes")
            print(f"— raw {raw} —")
            continue
        history.append({"role": "user", "content": line})
        try:
            reply = ask(soul, history, raw=raw)
        except Exception as e:
            print(f"[the pack is quiet — {e}]")
            history.pop()
            continue
        print(f"{soul}> {reply}\n")
        history.append({"role": "assistant", "content": reply})
        if len(history) > 24:
            del history[:2]

if __name__ == "__main__":
    main()