mirror of
https://github.com/andrewyng/openworker.git
synced 2026-09-13 07:40:18 +00:00
OpenWorker: initial import
Imported from andrewyng/aisuite@1b4bbf303e (contents of its platform/ directory, hoisted to the repo root). Development history prior to this commit lives in that repository. Co-authored-by: Devika <devikaverma11@gmail.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
"""Interactive prompts over messaging — buttons instead of free-text replies.
|
||||
|
||||
When an Inbox item is mirrored to a channel, discrete choices (approve/deny, an ask_user option)
|
||||
render as **buttons**. The item id rides in each button's value, so a click resolves the exact
|
||||
item — no `[ocw:id]`-in-reply fragility, no thread tracking. Free-text answers aren't offered over
|
||||
messaging (the user opens the app for those).
|
||||
|
||||
Provider-agnostic: a `Button` is `(label, value)`; each adapter renders it natively (Slack Block
|
||||
Kit, Telegram inline keyboard, …). The value is opaque to the adapter — `encode`/`decode` here own
|
||||
its meaning: `(item_id, resolution)`.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
|
||||
from .inbox import KIND_APPROVAL, KIND_QUESTION
|
||||
|
||||
|
||||
@dataclass
|
||||
class Button:
|
||||
label: str
|
||||
value: str # opaque to the adapter; encode()/decode() own its meaning
|
||||
|
||||
|
||||
def encode(item_id: str, resolution: str) -> str:
|
||||
return json.dumps({"id": item_id, "r": resolution})
|
||||
|
||||
|
||||
def decode(value: str) -> Optional[tuple[str, str]]:
|
||||
"""`(item_id, resolution)` from a button value, or None if it isn't ours."""
|
||||
try:
|
||||
d = json.loads(value)
|
||||
if isinstance(d, dict) and d.get("id"):
|
||||
return str(d["id"]), str(d.get("r", ""))
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def buttons_for(item) -> list[Button]:
|
||||
"""The discrete-choice buttons for an Inbox item, or [] if it has none (free-text question,
|
||||
notification, …) — the caller then sends plain text with an "open the app" hint."""
|
||||
if item.kind == KIND_APPROVAL:
|
||||
return [
|
||||
Button("Approve", encode(item.id, "allow")),
|
||||
Button("Deny", encode(item.id, "deny")),
|
||||
]
|
||||
if item.kind == KIND_QUESTION and getattr(item, "options", None):
|
||||
# One button per option; the resolution IS the chosen option text (what the agent gets).
|
||||
return [Button(opt, encode(item.id, opt)) for opt in item.options]
|
||||
return []
|
||||
Reference in New Issue
Block a user