dc12257d0a
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>
50 lines
2.0 KiB
Python
Executable File
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()
|