dm.py: Headless DM function class, separate from Chat
This commit is contained in:
@@ -0,0 +1,109 @@
|
|||||||
|
#!/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 <chat_id|main> "message"
|
||||||
|
dm.py read --agent 646 --target <chat_id|main> [n]
|
||||||
|
dm.py thread --from 646 --to muse --target <chat_id|main> "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()
|
||||||
Reference in New Issue
Block a user