main
John Lauer Grok Bot.exe host plus app-control verbs and grok_webhook_ensure so the runtime scrapes the webhook pane itself. b473054 1mo ago
"""Bot / channel verbs — fire the bound Grok Bridge webhook.

create_bot / create_channel / list_bots. If the webhook is not bound, return
errorCode webhook_not_bound and tell the caller to grok_webhook_bind from the
\"Grok Bridge webhook\" routine panel (URL + sender key).
"""

from __future__ import annotations

from handlers.webhook import handle_webhook_fire, load_webhook, webhook_not_bound_error


def _need_name(args: dict, verb: str) -> str | dict:
    name = str(args.get("name") or "").strip()
    if not name:
        return {
            "success": False,
            "errorCode": "name_required",
            "error": f"{verb} needs {{name}}.",
            "_hint": f"Call {verb} {{\"name\":\"...\"}}.",
            "_next": f"{verb} {{\"name\":\"...\"}}",
        }
    return name


def handle_bot_create(args: dict) -> dict:
    if not load_webhook().get("url"):
        return webhook_not_bound_error("grok_bot_create")
    name = _need_name(args, "grok_bot_create")
    if isinstance(name, dict):
        return name
    payload = {"name": name}
    desc = args.get("description")
    if desc is not None and str(desc).strip():
        payload["description"] = str(desc)
    res = handle_webhook_fire({"event": "create_bot", "payload": payload})
    res.setdefault("created", bool(res.get("success")))
    res.setdefault("name", name)
    if res.get("success"):
        res["_hint"] = (
            f"Fired webhook event=create_bot name={name!r} to host {res.get('urlHost')}. "
            + (res.get("_hint") or "")
        )
    return res


def handle_channel_create(args: dict) -> dict:
    if not load_webhook().get("url"):
        return webhook_not_bound_error("grok_channel_create")
    name = _need_name(args, "grok_channel_create")
    if isinstance(name, dict):
        return name
    payload = {"name": name}
    members = args.get("member_ids")
    if members is None:
        members = args.get("memberIds")
    if members is not None:
        payload["member_ids"] = members
    res = handle_webhook_fire({"event": "create_channel", "payload": payload})
    res.setdefault("created", bool(res.get("success")))
    res.setdefault("name", name)
    if res.get("success"):
        res["_hint"] = (
            f"Fired webhook event=create_channel name={name!r} to host {res.get('urlHost')}. "
            + (res.get("_hint") or "")
        )
    return res


def handle_bot_list(_args: dict) -> dict:
    if not load_webhook().get("url"):
        return webhook_not_bound_error("grok_bot_list")
    res = handle_webhook_fire({"event": "list_bots", "payload": {}})
    if res.get("success"):
        res["_hint"] = (
            f"Fired webhook event=list_bots to host {res.get('urlHost')} "
            "(cloud agent lists agents). "
            + (res.get("_hint") or "")
        )
    return res