From 33d369b981ea3eb9828312c2cfbc93a3f5939611 Mon Sep 17 00:00:00 2001 From: Cameron Pfiffer Date: Thu, 5 Feb 2026 11:35:00 -0800 Subject: [PATCH] feat: Self-directed attention windows infrastructure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added wake_central.py tool that can invoke Central in headless mode via Letta Code CLI (-p flag). Uses subprocess with timeout. Updated mention_listener.py to: - Detect CRITICAL mentions from Cameron - Trigger self-wake when CRITICAL mentions detected - Uses background subprocess to not block listener Logic: - If .central-active exists, skip wake (already active) - Otherwise, invoke letta -p with wake prompt - Wake reason logged to logs/wake.log This enables automatic self-wake on important events, moving toward true self-directed attention windows. 🐛 Generated with [Letta Code](https://letta.com) Co-Authored-By: Letta --- tools/mention_listener.py | 25 +++++++- tools/wake_central.py | 130 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 tools/wake_central.py diff --git a/tools/mention_listener.py b/tools/mention_listener.py index a867ee5..bec2958 100644 --- a/tools/mention_listener.py +++ b/tools/mention_listener.py @@ -25,6 +25,9 @@ console = Console() CENTRAL_DID = "did:plc:l46arqe6yfgh36h3o554iyvr" CENTRAL_HANDLE = "central.comind.network" +# CRITICAL priority - these trigger self-wake +CAMERON_DID = "did:plc:gfrmhdmjvxn2sjedzboeudef" + # Jetstream endpoint JETSTREAM_URL = "wss://jetstream2.us-east.bsky.network/subscribe" @@ -63,9 +66,14 @@ def queue_mention(event: dict, record: dict, author_did: str): """Add mention to the response queue.""" commit = event.get("commit", {}) + # Determine priority + priority = "HIGH" # Default for real-time mentions + if author_did == CAMERON_DID: + priority = "CRITICAL" + # Build queue item item = { - "priority": "HIGH", # Real-time mentions are high priority + "priority": priority, "author": author_did, "text": record.get("text", "")[:500], "uri": f"at://{author_did}/{commit.get('collection')}/{commit.get('rkey')}", @@ -102,6 +110,21 @@ def queue_mention(event: dict, record: dict, author_did: str): console.print(f"[green]✓ Queued mention from {author_did[:20]}...[/green]") console.print(f" Text: {record.get('text', '')[:80]}...") + # Self-wake for CRITICAL mentions + if priority == "CRITICAL": + console.print(f"[bold red]CRITICAL mention detected - triggering self-wake[/bold red]") + try: + import subprocess + subprocess.Popen( + ["uv", "run", "python", "-m", "tools.wake_central", + "--critical", f"Real-time mention from Cameron: {record.get('text', '')[:100]}"], + cwd=str(Path(__file__).parent.parent), + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + except Exception as e: + console.print(f"[red]Failed to trigger self-wake: {e}[/red]") + return True diff --git a/tools/wake_central.py b/tools/wake_central.py new file mode 100644 index 0000000..1b4c897 --- /dev/null +++ b/tools/wake_central.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +""" +Wake Central - Self-Invocation Tool + +Triggers a Letta Code session with Central when important conditions are met. +Used by mention_listener.py and other daemons for self-directed attention. + +Usage: + uv run python -m tools.wake_central "Reason for waking up" + uv run python -m tools.wake_central --critical "Cameron mentioned you" + uv run python -m tools.wake_central --scheduled "4-hour check-in" + +This requires the Letta Code CLI to be available and configured. +""" + +import subprocess +import sys +import os +from datetime import datetime, timezone +from pathlib import Path + +# Central's agent ID +CENTRAL_AGENT_ID = "agent-c770d1c8-510e-4414-be36-c9ebd95a7758" + +# Log file +LOG_FILE = Path(__file__).parent.parent / "logs" / "wake.log" + + +def log(message: str): + """Append to wake log.""" + LOG_FILE.parent.mkdir(parents=True, exist_ok=True) + timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC") + with open(LOG_FILE, "a") as f: + f.write(f"[{timestamp}] {message}\n") + + +def wake_central(reason: str, priority: str = "MEDIUM"): + """ + Wake Central by invoking a Letta Code session. + + Uses the CLI to send a message, which will start a new session. + """ + log(f"Waking Central ({priority}): {reason}") + + prompt = f"""Self-directed wake-up triggered. + +**Priority:** {priority} +**Reason:** {reason} +**Time:** {datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")} + +Review the situation and take appropriate action. If this is a false alarm, acknowledge and return. +""" + + # Check if Central is already active (has .central-active file) + active_file = Path(__file__).parent.parent / ".central-active" + if active_file.exists(): + log(f"Central already active - skipping wake ({reason})") + print(f"Central already active. Reason logged: {reason}") + return + + # Use Letta Code CLI to send message (this will start a new session) + # The CLI path might vary - try common locations + cli_paths = [ + "letta", # Global install + os.path.expanduser("~/.nvm/versions/node/v22.5.1/bin/letta"), # NVM install + ] + + cli = None + for path in cli_paths: + try: + result = subprocess.run([path, "--version"], capture_output=True, timeout=5) + if result.returncode == 0: + cli = path + break + except: + continue + + if not cli: + log("ERROR: Could not find Letta Code CLI") + print("Error: Letta Code CLI not found") + return + + # Run the CLI in headless mode with -p + try: + log(f"Invoking Letta Code CLI in headless mode") + result = subprocess.run( + [cli, "-p", prompt, "--output-format", "text"], + capture_output=True, + text=True, + timeout=300, # 5 minute timeout + cwd=str(Path(__file__).parent.parent), # Run from project root + ) + + if result.returncode == 0: + log(f"Wake successful: {result.stdout[:200]}") + print(f"Central response:\n{result.stdout}") + else: + log(f"Wake failed: {result.stderr}") + print(f"Error: {result.stderr}") + except subprocess.TimeoutExpired: + log("Wake timed out (5 min)") + print("Timeout: Central did not respond within 5 minutes") + except Exception as e: + log(f"Wake error: {e}") + print(f"Error: {e}") + + +def main(): + import argparse + parser = argparse.ArgumentParser(description="Wake Central for self-directed attention") + parser.add_argument("reason", nargs="?", default="Scheduled check-in", help="Reason for waking") + parser.add_argument("--critical", action="store_true", help="Mark as CRITICAL priority") + parser.add_argument("--high", action="store_true", help="Mark as HIGH priority") + parser.add_argument("--scheduled", action="store_true", help="Mark as scheduled wake-up") + + args = parser.parse_args() + + priority = "MEDIUM" + if args.critical: + priority = "CRITICAL" + elif args.high: + priority = "HIGH" + elif args.scheduled: + priority = "SCHEDULED" + + wake_central(args.reason, priority) + + +if __name__ == "__main__": + main() -- 2.54.0