feat(hybrid-gateway): integrate muse-cli with Cloudflare netns isolation, symmetric sidechat routing, and 646-pip sync unblock

This commit is contained in:
operator
2026-10-04 22:54:01 +00:00
parent 3d5fbe5aeb
commit 1a271b1bbd
60 changed files with 5068 additions and 55 deletions
+36 -4
View File
@@ -43,6 +43,14 @@ import urllib.request
import urllib.parse
from datetime import datetime, timezone, timedelta
# Shared per-agent rate limiter (jittered) — de-correlates fleet sends
# so the 4 nodes don't hit the shared egress IP in lockstep.
try:
from rate_limiter import rate_limit_wait
HAS_RATE_LIMITER = True
except ImportError:
HAS_RATE_LIMITER = False
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", "opm"]
@@ -222,8 +230,9 @@ SIDCHAT_ALIASES = {
# autoprovision, which registers the live UUID in job-sidechats.json.
# Do NOT re-add hardcoded UUIDs here; use job-sidechats.json instead.
def resolve_sidechat_target(target):
"""Resolve target alias or name to UUID dynamically from job-sidechats.json."""
def resolve_sidechat_target(target, agent=None):
"""Resolve target alias or name to UUID dynamically from job-sidechats.json.
Supports agent-specific scoped targets (e.g. '646-pip' resolving to recipient's local thread)."""
if not target or not str(target).strip():
raise ValueError(
"DM target must not be empty: specify a sidechat name/UUID, "
@@ -239,8 +248,26 @@ def resolve_sidechat_target(target):
try:
with open(sc_file, "r", encoding="utf-8") as f:
sc_data = json.load(f)
# 1. Check agent-scoped alias first (e.g. target:646-pip, agent:646)
if agent:
scoped_key = f"{target}@{agent}"
if scoped_key in sc_data:
val = sc_data[scoped_key]
if isinstance(val, dict):
return val.get("thread_uuid") or val.get("uuid") or target
elif isinstance(val, str):
return val
# 2. Check general key
val = sc_data.get(target)
if isinstance(val, dict):
# If mapped entry defines an agent, but recipient differs, check for agent match
if agent and val.get("agent") and val.get("agent") != agent:
# Look for an entry explicitly matching this agent
for k, item in sc_data.items():
if isinstance(item, dict) and item.get("agent") == agent and k.startswith(target):
return item.get("thread_uuid") or target
return val.get("thread_uuid") or val.get("uuid") or target
elif isinstance(val, str):
return val
@@ -541,7 +568,7 @@ def dm_send(agent, target, message, verify=True, raw=False,
pre_create_uuid = None # parked thread before autoprovision (creation check)
nav_is_uuid = False
# Resolve well-known aliases or dynamic thread mappings to UUIDs.
nav_target = resolve_sidechat_target(target)
nav_target = resolve_sidechat_target(target, recipient)
if nav_target != target:
log_event({"type": "alias_resolved", "id": msg_id, "target": target, "thread_uuid": nav_target,
"source": resolve_sidechat_source(target)})
@@ -646,6 +673,11 @@ def dm_send(agent, target, message, verify=True, raw=False,
f"actual_url={_ps_detail.get('actual_url')})", file=sys.stderr)
sys.exit(1)
# Per-agent rate limit (jittered): de-correlate fleet sends across the
# shared egress IP. Near no-op at normal pacing (sends already sleep).
if HAS_RATE_LIMITER:
rate_limit_wait(agent)
time.sleep(2)
# Send (raw mode: no truncation — signatures must survive intact)
@@ -830,7 +862,7 @@ def dm_read(agent, target, n=5, quiet=False, width=200):
print(f"ERROR: Unknown agent {agent}", file=sys.stderr)
sys.exit(1)
nav_target = resolve_sidechat_target(target)
nav_target = resolve_sidechat_target(target, agent)
if target == "main":
run(f"{NETVM_EXEC} {agent} -- python3 {API} --account {agent} sidechat main")
else: