Files
bullpen/bin/room-ask
T
claude-noether dc12257d0a add room-ask (rich-agent visit/ask/leave primitive) + bullpen skill
room-ask posts an ask to @worker and blocks client-side for the matching reply
(in_reply_to), so the lmcp server never blocks. skills/bullpen.md documents the
sic-based visit/ask/leave flow for pi-agents.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 11:54:36 +02:00

50 lines
2.0 KiB
Python
Executable File

#!/usr/bin/env python3
"""Ask the bullpen and block until the reply — the rich-agent "visit, ask, leave".
room-ask [--from NICK] [--timeout N] @worker <question...>
Posts an `ask` addressed to @worker, waits for the `reply` that answers it, prints
the reply body. Exit 0 on reply, 1 on timeout/error. The wait is client-side (this
process), so it never blocks the lmcp server.
"""
import sys, json, subprocess, time, os, socket
def lmcp(tool, **kw):
return subprocess.run(["lmcp-tool", tool] + [f"{k}={v}" for k, v in kw.items()],
capture_output=True, text=True)
def main():
args = sys.argv[1:]
frm = os.environ.get("ROOM_NICK") or socket.gethostname().split(".")[0]
timeout = 60
pos = []
i = 0
while i < len(args):
if args[i] == "--from" and i + 1 < len(args): frm = args[i + 1]; i += 2
elif args[i] == "--timeout" and i + 1 < len(args): timeout = int(args[i + 1]); i += 2
else: pos.append(args[i]); i += 1
if len(pos) < 2:
print("usage: room-ask [--from NICK] [--timeout N] @worker <question>", file=sys.stderr)
sys.exit(2)
to = pos[0] if pos[0].startswith("@") else "@" + pos[0]
body = " ".join(pos[1:])
r = lmcp("room_say", **{"from": frm, "to": to, "type": "ask", "body": body})
try:
ask_id = json.loads(r.stdout.strip())["id"]
except Exception:
print(f"room-ask: post failed: {r.stdout}{r.stderr}", file=sys.stderr); sys.exit(1)
deadline = time.time() + timeout
while time.time() < deadline:
for line in lmcp("room_read", since=ask_id).stdout.splitlines():
line = line.strip()
if not line: continue
try: m = json.loads(line)
except Exception: continue
if m.get("type") == "reply" and m.get("in_reply_to") == ask_id:
print(m.get("body", "")); sys.exit(0)
time.sleep(1.5)
print(f"room-ask: no reply from {to} within {timeout}s", file=sys.stderr); sys.exit(1)
if __name__ == "__main__":
main()