Files
aiagent/backend/app/services/feishu_card_builder.py
renjianbo beff3fac8d fix: delete agent 500 error + dynamic personality + deployment guide
- Fix delete agent 500: clean up FK records (agent_llm_logs, permissions,
  schedules, executions, team_members) and unbind goals/tasks before delete
- Remove hardcoded personality templates in Android, replace with dynamic
  system prompt generation from name + description
- Set promptSectionsEnabled=false to bypass PromptComposer for personality
- Add Tencent Cloud Linux deployment guide (Docker Compose)
- Accumulated backend service updates, frontend UI fixes, Android app changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-29 01:17:21 +08:00

136 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
飞书消息卡片构建器 — 统一的交互卡片生成,含反馈按钮
所有飞书 App Service 和 WS Handler 共用此模块构建回复卡片。
"""
from __future__ import annotations
import json
import logging
from typing import Any, Dict, List, Optional
logger = logging.getLogger(__name__)
# 反馈按钮 action tag 标识
ACTION_FEEDBACK_THUMBS_UP = "feedback_thumbs_up"
ACTION_FEEDBACK_THUMBS_DOWN = "feedback_thumbs_down"
ACTION_FEEDBACK_REGENERATE = "feedback_regenerate"
def build_reply_card(
title: str,
content: str,
*,
execution_log_id: Optional[str] = None,
agent_name: Optional[str] = None,
status: str = "info",
detail_link: Optional[str] = None,
include_feedback: bool = True,
) -> Dict[str, Any]:
"""构建 Agent 回复消息卡片。
Args:
title: 卡片标题
content: 卡片正文Markdown 格式)
execution_log_id: 关联的执行日志 ID用于反馈追踪
agent_name: Agent 名称
status: info / success / failed
detail_link: 详情链接(可选)
include_feedback: 是否包含反馈按钮
Returns:
飞书交互卡片 JSON
"""
color_map = {"success": "green", "failed": "red", "info": "blue"}
color = color_map.get(status, "blue")
elements: List[Dict[str, Any]] = [
{"tag": "markdown", "content": content},
]
# 反馈按钮行
if include_feedback and execution_log_id:
feedback_value = {
"execution_log_id": execution_log_id,
"agent_name": agent_name or "",
"card_title": title,
}
elements.append({
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "👍 有用"},
"type": "primary",
"value": json.dumps({**feedback_value, "action": ACTION_FEEDBACK_THUMBS_UP}),
},
{
"tag": "button",
"text": {"tag": "plain_text", "content": "👎 无用"},
"type": "default",
"value": json.dumps({**feedback_value, "action": ACTION_FEEDBACK_THUMBS_DOWN}),
},
{
"tag": "button",
"text": {"tag": "plain_text", "content": "🔄 重试"},
"type": "default",
"value": json.dumps({**feedback_value, "action": ACTION_FEEDBACK_REGENERATE}),
},
],
})
# 详情链接
if detail_link:
elements.append({
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "查看详情"},
"url": detail_link,
"type": "default",
}
],
})
return {
"config": {"wide_screen_mode": True},
"header": {
"title": {"tag": "plain_text", "content": title},
"template": color,
},
"elements": elements,
}
def build_feedback_response_card(
original_title: str,
original_content: str,
action: str,
*,
detail_link: Optional[str] = None,
) -> Dict[str, Any]:
"""构建反馈确认卡片(替换原有卡片)。
当用户点击反馈按钮后,替换原卡片为去反馈按钮的确认卡片。
"""
if action == ACTION_FEEDBACK_THUMBS_UP:
note = "✅ 已收到你的反馈:**有用**,感谢支持!"
color = "green"
elif action == ACTION_FEEDBACK_THUMBS_DOWN:
note = "💡 已收到你的反馈:**无用**,我们会持续改进。"
color = "red"
else:
note = "🔄 正在为你重新生成回复..."
color = "blue"
content = f"{note}\n\n---\n{original_content}"
return build_reply_card(
title=original_title,
content=content,
status="info",
detail_link=detail_link,
include_feedback=False,
)