#!/usr/bin/env python3 """ DM: Headless Direct Message API (muse.ai) Distinct from Chat (front-door, externally hosted). DM operates via headless browser automation on muse.ai. Chat operates via signed HTTPS API to chat.muse-dev.online. This separation increases headless reliability by isolating browser automation from network API calls. Usage: dm.py send --agent 646 --target "message" dm.py read --agent 646 --target [n] dm.py thread --from 646 --to muse --target "message" """ import argparse import subprocess import time import sys API = "/home/super/Projects/NetVM/bin/muse-chat-api.py" NETVM_EXEC = "/home/super/Projects/NetVM/bin/netvm-exec.sh" VALID_AGENTS = ["muse", "pip", "646"] def run(cmd, timeout=60): result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout) return result.stdout.strip() def dm_send(agent, target, message): """Send a DM via headless to agent's target (main or side chat).""" if agent not in VALID_AGENTS: print(f"ERROR: Unknown agent {agent}", file=sys.stderr) sys.exit(1) # Navigate to target if target == "main": run(f"{NETVM_EXEC} {agent} -- python3 {API} --account {agent} sidechat main") else: run(f"{NETVM_EXEC} {agent} -- python3 {API} --account {agent} sidechat use {target}") time.sleep(2) # Send safe = message.replace('"', '\\"').replace('$', '\\$').replace('`', '\\`')[:1000] result = run(f'{NETVM_EXEC} {agent} -- python3 {API} --account {agent} send "{safe}"') # Back to main run(f"{NETVM_EXEC} {agent} -- python3 {API} --account {agent} sidechat main") print(f"DM sent to {agent}/{target}") return result def dm_read(agent, target, n=5): """Read DMs via headless from agent's target.""" if agent not in VALID_AGENTS: print(f"ERROR: Unknown agent {agent}", file=sys.stderr) sys.exit(1) if target == "main": run(f"{NETVM_EXEC} {agent} -- python3 {API} --account {agent} sidechat main") else: run(f"{NETVM_EXEC} {agent} -- python3 {API} --account {agent} sidechat use {target}") time.sleep(2) msgs = run(f"{NETVM_EXEC} {agent} -- python3 {API} --account {agent} messages {n}") run(f"{NETVM_EXEC} {agent} -- python3 {API} --account {agent} sidechat main") print(msgs) return msgs def dm_thread(from_agent, to_agent, target, message): """Thread a message from one agent into another's chat (via operator).""" # Read from source (optional, for context) # Send to target with attribution attributed = f"[{from_agent}] {message}" return dm_send(to_agent, target, attributed) def main(): p = argparse.ArgumentParser(description="DM: Headless Direct Messages (muse.ai)") sub = p.add_subparsers(dest='cmd', required=True) # dm send ps = sub.add_parser('send', help='Send a DM via headless') ps.add_argument('--agent', required=True, choices=VALID_AGENTS) ps.add_argument('--target', required=True, help='main or chat_id') ps.add_argument('message', help='Message to send') ps.set_defaults(func=lambda a: dm_send(a.agent, a.target, a.message)) # dm read pr = sub.add_parser('read', help='Read DMs via headless') pr.add_argument('--agent', required=True, choices=VALID_AGENTS) pr.add_argument('--target', required=True, help='main or chat_id') pr.add_argument('--n', type=int, default=5, help='Number of messages') pr.set_defaults(func=lambda a: dm_read(a.agent, a.target, a.n)) # dm thread pt = sub.add_parser('thread', help='Thread from one agent to another') pt.add_argument('--from', dest='from_agent', required=True, choices=VALID_AGENTS) pt.add_argument('--to', dest='to_agent', required=True, choices=VALID_AGENTS) pt.add_argument('--target', required=True, help='main or chat_id on target') pt.add_argument('message', help='Message to thread') pt.set_defaults(func=lambda a: dm_thread(a.from_agent, a.to_agent, a.target, a.message)) args = p.parse_args() args.func(args) if __name__ == '__main__': main()