feat(webui): render ask_user choices

Made-with: Cursor
This commit is contained in:
Xubin Ren
2026-04-25 15:46:47 +00:00
parent 403ce23d22
commit a58d9fd357
10 changed files with 274 additions and 6 deletions
+2 -2
View File
@@ -6,7 +6,7 @@ from typing import Any
from nanobot.agent.tools.base import Tool, tool_parameters
from nanobot.agent.tools.schema import ArraySchema, StringSchema, tool_parameters_schema
BUTTON_CHANNELS = frozenset({"telegram"})
STRUCTURED_BUTTON_CHANNELS = frozenset({"telegram", "websocket"})
class AskUserInterrupt(BaseException):
@@ -130,7 +130,7 @@ def ask_user_outbound(
) -> tuple[str | None, list[list[str]]]:
if not options:
return content, []
if channel in BUTTON_CHANNELS:
if channel in STRUCTURED_BUTTON_CHANNELS:
return content, [options]
option_text = "\n".join(f"{index}. {option}" for index, option in enumerate(options, 1))
return f"{content}\n\n{option_text}" if content else option_text, []
+15 -1
View File
@@ -54,6 +54,14 @@ def _normalize_config_path(path: str) -> str:
return _strip_trailing_slash(path)
def _append_buttons_as_text(text: str, buttons: list[list[str]]) -> str:
labels = [label for row in buttons for label in row if label]
if not labels:
return text
fallback = "\n".join(f"{index}. {label}" for index, label in enumerate(labels, 1))
return f"{text}\n\n{fallback}" if text else fallback
class WebSocketConfig(Base):
"""WebSocket server channel configuration.
@@ -1146,11 +1154,17 @@ class WebSocketChannel(BaseChannel):
if not conns:
logger.warning("websocket: no active subscribers for chat_id={}", msg.chat_id)
return
text = msg.content
if msg.buttons:
text = _append_buttons_as_text(text, msg.buttons)
payload: dict[str, Any] = {
"event": "message",
"chat_id": msg.chat_id,
"text": msg.content,
"text": text,
}
if msg.buttons:
payload["buttons"] = msg.buttons
payload["button_prompt"] = msg.content
if msg.media:
payload["media"] = msg.media
urls: list[dict[str, str]] = []