diff --git a/gsd-openclaw/src/gsd_openclaw/response_formatter.py b/gsd-openclaw/src/gsd_openclaw/response_formatter.py index a7d7a9b..e4b75a1 100644 --- a/gsd-openclaw/src/gsd_openclaw/response_formatter.py +++ b/gsd-openclaw/src/gsd_openclaw/response_formatter.py @@ -23,3 +23,61 @@ class CardButton: text: str value: Dict[str, Any] button_type: str = "primary" # primary, default, danger + + +class FeishuResponseFormatter: + """Format responses as Feishu Card messages.""" + + def format_success(self, title: str, content: str, + buttons: Optional[List[CardButton]] = None) -> dict: + """Format a success response card with green theme.""" + return self._build_card(title, content, CardTheme.SUCCESS, buttons) + + def format_error(self, title: str, content: str, + buttons: Optional[List[CardButton]] = None) -> dict: + """Format an error response card with red theme.""" + return self._build_card(title, content, CardTheme.ERROR, buttons) + + def format_info(self, title: str, content: str, + buttons: Optional[List[CardButton]] = None) -> dict: + """Format an info response card with blue theme.""" + return self._build_card(title, content, CardTheme.INFO, buttons) + + def format_paginated(self, title: str, content: str, + page: int, total_pages: int) -> dict: + """Format a paginated response with [page/total] marker.""" + footer = f"\n\n---\n[{page}/{total_pages}]" + return self._build_card(title, content + footer, CardTheme.INFO) + + def _build_card(self, title: str, content: str, theme: CardTheme, + buttons: Optional[List[CardButton]] = None) -> dict: + """Build complete card JSON structure.""" + card = { + "schema": "2.0", + "config": {"wide_screen_mode": True}, + "header": { + "title": {"tag": "plain_text", "content": title}, + "template": theme.value + }, + "elements": [ + {"tag": "div", "text": {"tag": "lark_md", "content": content}} + ] + } + if buttons: + card["elements"].append(self._build_actions(buttons)) + return card + + def _build_actions(self, buttons: List[CardButton]) -> dict: + """Build actions element from button list.""" + return { + "tag": "action", + "actions": [ + { + "tag": "button", + "text": {"tag": "plain_text", "content": btn.text}, + "type": btn.button_type, + "value": btn.value + } + for btn in buttons + ] + }