51064e48aa
feat: AI reply suggestions show as copyable code block, user edits before sending - Click suggestion -> show text in backtick code block (tap to copy) - Enter awaiting_reply state so user can edit/send like normal reply - No direct email sending on selection anymore - Tests: 3/3 passing
ab2bf7facb
feat: AI reply modes - full (formal email) and short (concise) - Split 'AI回复' button into 'AI完整回复' and 'AI简洁回复' - Full mode: complete email format with greeting/signature, 300 char limit - Short mode: brief text message style, 50 char limit - Style persists in conversation state for regen/hint consistency - Tests: 6/6 passing
2a9be9896f
fix: restore links when returning to summary view _summary_keyboard was called without links param in VIEW_SUMM handler, causing extracted links to disappear after viewing original text.
2f29e03cec
fix: read Telegram caption field for media messages Telegram sends text in 'caption' field (not 'text') when message has media. Handle both cases: text or caption, with text taking priority.
d76a119190
feat: support attachments in manual reply (photo/video/document/voice) - Add _extract_media: extract media info from Telegram messages - Add _download_tg_file: download files from Telegram API - Modify _handle_message: accumulate attachments in awaiting_reply, send with text - Modify _handle_update: process messages without text (media-only) - Modify smtp_client.send_reply: support MIME multipart with attachments - Add comprehensive tests (11 tests, all passing)
d05277581c
fix: save_conversation in CALLBACK_HINT, move AI hint to thread pool
fe24a07d15
fix: parse_mode always MarkdownV2, add MEMORY.md with project rules
0abb7de5d3
fix: move regenerate to AI thread pool, fix parse_mode None error