feat: cancel button, regenerate AI replies, custom reply hints

- Reply prompt now has an inline '取消回复' button instead of typing text
- AI reply selection adds '换一批' button: passes all previous suggestions
  to AI to generate different replies
- '我想说:' button: lets user type a hint/tone instruction, AI tailors
  suggestions accordingly
- Cancel button also works on prompt/hint messages (deletes them)
- Extract _show_ai_suggestions helper for reuse
This commit is contained in:
2026-07-02 20:45:40 +08:00
parent 18db9caa8b
commit 09d11a6c03
2 changed files with 145 additions and 33 deletions

View File

@@ -49,6 +49,43 @@ def summarize_email(ai_cfg: AIConfig, recipient: str, subject: str, sender: str,
return _call_deepseek(ai_cfg, payload)
MORE_REPLIES_PROMPT = """你是一个邮件回复助手。根据以下邮件内容生成3个完全不同的建议回复。
以下是一些已经生成过的回复,请生成全新的回复,不要与已有回复重复。
返回 JSON:
{
"suggestions": [
{"text": "回复内容"},
{"text": "回复内容"},
{"text": "回复内容"}
]
}
每条回复控制在 50 字以内。
只返回 JSON不要包含任何其他文字。"""
@retry()
def generate_more_replies(ai_cfg: AIConfig, sender: str, subject: str, body: str,
previous_suggestions: list[dict], user_hint: str = "") -> list[dict]:
content = f"发件人: {sender}\n主题: {subject}\n正文:\n{body[:4000]}\n\n已生成过的回复:\n"
for i, s in enumerate(previous_suggestions, 1):
content += f"{i}. {s['text']}\n"
if user_hint:
content += f"\n用户要求: {user_hint}"
payload = {
"model": ai_cfg.model,
"messages": [
{"role": "system", "content": MORE_REPLIES_PROMPT},
{"role": "user", "content": content},
],
"response_format": {"type": "json_object"},
}
result = _call_deepseek(ai_cfg, payload)
return result.get("suggestions", [])
def _call_deepseek(ai_cfg: AIConfig, payload: dict) -> dict:
headers = {
"Authorization": f"Bearer {ai_cfg.api_key}",