From 35bd358b788b62b0a748a819ad1360980ded12cb Mon Sep 17 00:00:00 2001 From: operator-main Date: Sun, 4 Oct 2026 03:09:42 +0000 Subject: [PATCH] job-dispatch.py: Add sidechat creation support\n\nWhen job has sidechat.create=true, creates sidechat via\nmuse-chat-api.py in sender context, includes URL in DM. --- bin/job-dispatch.py | 47 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/bin/job-dispatch.py b/bin/job-dispatch.py index 91e1960..83d65be 100755 --- a/bin/job-dispatch.py +++ b/bin/job-dispatch.py @@ -23,6 +23,8 @@ from pathlib import Path NETVM_ROOT = Path("/home/super/Projects/NetVM") JOBS_DIR = NETVM_ROOT / "jobs" DM_PY = NETVM_ROOT / "bin" / "dm.py" +CHAT_API = NETVM_ROOT / "bin" / "muse-chat-api.py" +NETVM_EXEC = "/home/super/Projects/NetVM/bin/netvm-exec.sh" JOB_LOG = NETVM_ROOT / "job-log.jsonl" # Add bin to path for rate_limiter @@ -91,6 +93,29 @@ def send_dm(agent, target, message, dry_run=False): # Try to parse ID from output return output +def create_sidechat(sender_agent, dry_run=False): + """Create a sidechat via muse-chat-api.py in sender's context. + Returns the thread URL or None on failure.""" + if dry_run: + print(f"[DRY RUN] Would create sidechat for {sender_agent}") + return "https://muse.ai/thread/dry-run-uuid" + + cmd = [NETVM_EXEC, sender_agent, "--", "python3", str(CHAT_API), + "--account", sender_agent, "sidechat", "create"] + try: + result = subprocess.run(cmd, capture_output=True, text=True, timeout=60) + output = result.stdout.strip() + result.stderr.strip() + # Look for "Created: " + for line in output.split("\n"): + if "Created:" in line: + url = line.split("Created:")[1].strip() + return url + print(f"Sidechat create output: {output[:200]}", file=sys.stderr) + return None + except Exception as e: + print(f"Sidechat creation failed: {e}", file=sys.stderr) + return None + def main(): if len(sys.argv) < 2: print(f"Usage: {sys.argv[0]} [--dry-run]", file=sys.stderr) @@ -127,12 +152,26 @@ def main(): # Get target agent = job.get("agent", "muse") sidechat_cfg = job.get("sidechat", {}) + sidechat_url = None if sidechat_cfg.get("create", False): - # TODO: Create sidechat and get name - # For now, just note it in the DM - target = "main" - dm_message += f"\n\n[Sidechat: {sidechat_cfg.get('name_template', 'job-'+job_name)}]" + # Create sidechat in sender's (opm's) context + print(f"Creating sidechat for job {job_id}...", file=sys.stderr) + sidechat_url = create_sidechat("opm", dry_run=dry_run) + if sidechat_url: + # Render name template for display + name_tmpl = sidechat_cfg.get("name_template", "job-{job_name}-{date}") + sc_name = render_prompt(name_tmpl, variables) + dm_message += f"\n\n[Sidechat created: {sc_name}]\nWork in this side chat. URL: {sidechat_url}" + target = "main" # DM goes to main, directs to sidechat + log_event("job_sidechat_created", { + "job_id": job_id, + "sidechat_url": sidechat_url, + "sidechat_name": sc_name, + }) + else: + print(f"Warning: Failed to create sidechat, proceeding without", file=sys.stderr) + target = "main" else: target = "main"