feat: add conversational replies and stable output
Some checks failed
tamq-ci / test (push) Failing after 6s
Some checks failed
tamq-ci / test (push) Failing after 6s
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a03397-4d51-7fd1-8ff2-946eb22ea2bc
This commit is contained in:
parent
704eeea5c1
commit
a4ba6e32e5
17 changed files with 363 additions and 59 deletions
|
|
@ -31,7 +31,7 @@ from .terminal import format_comment
|
|||
|
||||
|
||||
SUBCOMMANDS = frozenset(
|
||||
"start attach serve stop status ping inbox history inspect ack send export replay purge completion db-version config tap".split()
|
||||
"start attach serve stop status ping inbox history inspect ack send reply export replay purge completion db-version config tap".split()
|
||||
)
|
||||
START_OPTIONS = frozenset({"--command", "--cmd", "--tap", "--detach", "--no-service", "--no-display"})
|
||||
GLOBAL_FLAGS = frozenset({"--orwell", "--verbose"})
|
||||
|
|
@ -162,6 +162,7 @@ def build_parser() -> argparse.ArgumentParser:
|
|||
|
||||
manual messaging from a managed shell:
|
||||
@TARGET: MESSAGE...
|
||||
@ MESSAGE... reply to the latest sender for this window
|
||||
tamq inbox [--filter COMMAND]
|
||||
""",
|
||||
)
|
||||
|
|
@ -206,6 +207,8 @@ manual messaging from a managed shell:
|
|||
send.add_argument("body", nargs="*", help="message body when address is a repo slug")
|
||||
send.add_argument("--endpoint-id")
|
||||
send.add_argument("--from", dest="sender_repo", help="sender repository (default: TAMQ_REPO or local)")
|
||||
reply = subparsers.add_parser("reply", help="reply to the latest sender for the current repository")
|
||||
reply.add_argument("body", nargs="+", help="message body")
|
||||
export = subparsers.add_parser("export", help="export history as JSONL")
|
||||
export.add_argument("--output", required=True)
|
||||
export.add_argument("--repo", dest="target_repo")
|
||||
|
|
@ -371,15 +374,31 @@ def main(argv: list[str] | None = None) -> int:
|
|||
store = Store(db_path())
|
||||
try:
|
||||
advisory = history_advisory(store)
|
||||
if advisory and args.command in {"start", "serve", "status", "history", "inbox", "send"}:
|
||||
if advisory and args.command in {"start", "serve", "status", "history", "inbox", "send", "reply"}:
|
||||
print(advisory, file=sys.stderr)
|
||||
if args.command == "send":
|
||||
text = " ".join([args.address, *args.body]).strip()
|
||||
if not text.startswith("@") or ":" not in text:
|
||||
print("tamq send expects @repo: message", file=sys.stderr); return 2
|
||||
target, body = text[1:].split(":", 1); body = body.strip()
|
||||
if not target or not body: print("tamq send requires a target and body", file=sys.stderr); return 2
|
||||
sender = args.sender_repo or os.environ.get("TAMQ_REPO") or "local"
|
||||
if args.command in {"send", "reply"}:
|
||||
endpoint_id = None
|
||||
if args.command == "reply":
|
||||
sender = os.environ.get("TAMQ_REPO")
|
||||
if not sender:
|
||||
print("tamq reply requires a managed window with TAMQ_REPO", file=sys.stderr)
|
||||
return 2
|
||||
body = " ".join(args.body).strip()
|
||||
target = store.latest_counterparty(sender)
|
||||
if target is None:
|
||||
print(f"tamq: no counterparty has sent a message to {sender}", file=sys.stderr)
|
||||
return 2
|
||||
else:
|
||||
text = " ".join([args.address, *args.body]).strip()
|
||||
if not text.startswith("@") or ":" not in text:
|
||||
print("tamq send expects @repo: message", file=sys.stderr); return 2
|
||||
target, body = text[1:].split(":", 1); body = body.strip()
|
||||
if not target or not body: print("tamq send requires a target and body", file=sys.stderr); return 2
|
||||
sender = args.sender_repo or os.environ.get("TAMQ_REPO") or "local"
|
||||
endpoint_id = args.endpoint_id
|
||||
if not body:
|
||||
print("tamq reply requires a message body", file=sys.stderr)
|
||||
return 2
|
||||
try:
|
||||
validate_targets([target])
|
||||
if sender != "local":
|
||||
|
|
@ -388,13 +407,13 @@ def main(argv: list[str] | None = None) -> int:
|
|||
print(f"tamq: {exc}", file=sys.stderr); return 2
|
||||
if asyncio.run(ping()):
|
||||
payload = {"op": "send", "sender_repo": sender, "target_repo": target, "body": body}
|
||||
if args.endpoint_id:
|
||||
payload["endpoint_id"] = args.endpoint_id
|
||||
if endpoint_id:
|
||||
payload["endpoint_id"] = endpoint_id
|
||||
response = asyncio.run(request(payload))
|
||||
if not response.get("ok"):
|
||||
print(f"tamq: {response.get('error', 'send failed')}", file=sys.stderr); return 1
|
||||
print(response["message_id"]); return 0
|
||||
if args.endpoint_id:
|
||||
if endpoint_id:
|
||||
print("tamq: service is not running", file=sys.stderr); return 1
|
||||
try:
|
||||
print(store.add(sender, target, body))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue