Commit graph

18 commits

Author SHA1 Message Date
Jiayuan Zhang
d1570698ac fix(telegram): fix tool narration detection and typing indicator during tool execution
- Detect both "tool_use" (Anthropic) and "toolCall" (Hub) content types
- Re-send typing indicator after sending/editing status message since
  Telegram clears typing state on any message send/edit
- Remove debug file logging (appendFileSync to /tmp)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 03:14:48 +08:00
Jiayuan Zhang
4c1365ff75 fix(telegram): strip existing bold markers in table conversion to prevent overlapping HTML tags
Table cells already containing **bold** markers got double-wrapped,
creating ****text**** which produced overlapping <b><i> tags rejected
by Telegram's HTML parser.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 03:14:41 +08:00
Jiayuan Zhang
dde8cc542a feat(telegram): show editable status message during tool execution
Instead of silently discarding tool narration or spamming separate
messages, send a single editable Telegram message that updates in-place
as the agent works. First tool narration sends a reply; subsequent
narrations edit the same message. The final answer is sent as a new
message.

- Add replyTextEditable/editText to ChannelOutboundAdapter interface
- Implement editFormatted + editable methods in Telegram plugin
- Track statusMessageId in ChannelManager, clear on agent_end/error
- Add sendOrEditStatus to Gateway TelegramService with same behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 02:14:42 +08:00
Jiayuan Zhang
81998e6309 fix(telegram): skip tool narration messages, only send final answer
When the agent uses tools (web search, etc.), it generates intermediate
narration text like "Let me search..." before each tool call. These were
being sent as separate Telegram messages, causing message spam. Now we
detect tool_use blocks in the message content and skip sending those
intermediate messages — only the final answer reaches the user.

Applied to both Desktop channel plugin and Gateway Telegram service.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 02:04:17 +08:00
Jiayuan Zhang
8270762d66 feat(telegram): convert Markdown tables to vertical list format
Telegram doesn't support HTML tables, so pipe-delimited Markdown tables
were rendered as hard-to-read plain text on mobile. This converts tables
to a vertical "Header: Value" format with bold first column before
sending to Telegram.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 01:56:21 +08:00
Jiayuan Zhang
d6393c6718 fix(gateway): remove cleanupPendingRequests that rejects all concurrent users
cleanupPendingRequests() iterated the service-wide pendingRequests Map
and rejected every entry. Since it was called from connectUser's catch
block (a per-user error path), one user's connection failure would
spuriously reject other users' in-flight verify RPCs.

The call was also redundant: sendVerifyRpc already cleans up its own
entry in all failure paths (timeout, RPC error, route failure).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 01:31:33 +08:00
Jiayuan Zhang
088750326c fix(gateway): persist Telegram users to JSON file when no database
Replaces in-memory Map with file-backed store at
~/.super-multica/gateway/telegram-users.json so user bindings
survive gateway restarts during local development.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:48:17 +08:00
Jiayuan Zhang
24b70e6e25 fix(gateway): add in-memory fallback for TelegramUserStore when no database
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:45:05 +08:00
Jiayuan Zhang
a7629db01e fix(gateway): enable CORS for HTTP endpoints
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:42:29 +08:00
Jiayuan Zhang
d75a24714d feat(gateway): add Telegram QR deep link connection flow
Add short code store, bot commands (/start, /status, /help), and
POST /telegram/connect-code endpoint for Desktop to create QR codes.
Users scan a QR → Telegram opens → /start {code} → auto-connects.

- ShortCodeStore: in-memory Map with TTL for connection info
- Bot commands registered via setMyCommands
- Refactor handleConnectionLink into shared connectUser method
- Fetch bot username via getMe() for deep link URL

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:30:01 +08:00
Jiayuan Zhang
5010d87284 feat(gateway): add long-polling fallback for local Telegram development
When TELEGRAM_WEBHOOK_URL is not set, the bot automatically starts in
long-polling mode (bot.start()) instead of waiting for webhook calls.
This allows local development without ngrok or a public URL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:05:19 +08:00
Jiayuan Zhang
38181ab4db refactor(gateway): remove group chat support from Telegram bot
Group chats have unresolved issues in the Gateway context:
- Per-user deviceId causes context overwrites across groups
- Reply chains across users route to wrong Hubs
- Welcome messages are noisy in groups

Restrict to private chats only until a proper group model is designed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 22:12:26 +08:00
Jiayuan Zhang
9646b08306 feat(gateway): port Desktop Telegram channel features to Gateway webhook bot
Port all 7 features from the Desktop long-polling Telegram channel plugin
to the Gateway webhook-based Telegram bot:

- Markdown → Telegram HTML formatting with parse-error fallback
- Text chunking for messages >4096 chars (paragraph-boundary split)
- Reply-to original message + 👀 ack reaction lifecycle
- Group chat support (mention/reply filtering, @mention stripping)
- Per-chat message serialization (prevents race conditions)
- Inbound media handling (voice/audio/photo/video/document)
  with transcription (Whisper) and description (Vision API)
- Outbound file captions with HTML formatting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 22:06:43 +08:00
Naiyuan Qing
242be23876 feat(utils): unify encrypted Device ID across all platforms
- Add common generateEncryptedId() utility in @multica/utils
- All Device IDs now use same encryption algorithm (40 hex chars)
- Web: store encrypted format directly in localStorage
- Desktop: use shared utility, accept encrypted ID from Web
- Hub: use shared utility for hub-id generation
- Telegram: use shared utility for device ID generation
- Gateway hook: use encrypted format for client connections

Algorithm: sha256(sha256(uuid).slice(0,32)).slice(0,8) + sha256(uuid).slice(0,32)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 17:34:23 +08:00
Jiayuan Zhang
f5ac4b85e8 feat(gateway): handle send_file action in Telegram service
Add sendFileToTelegram method that decodes base64 file data and sends
it via grammy's InputFile API. Handle send_file RoutedMessage action
in the virtual device sendCallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 01:37:41 +08:00
yushen
f20143743b feat(gateway): add typing indicator for Telegram bot responses
Send "typing" chat action while LLM generates a response, with 5s
interval refresh and 60s safety timeout. Stop on message_end,
agent_error, or generic error events.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 13:27:41 +08:00
yushen
899a3d193c fix(gateway): rewrite Dockerfile to match current source layout
Gateway source moved out of src/ subdirectory but Dockerfile still
referenced old paths, breaking docker build. Rewrite to use tsx runtime
(no tsc/esbuild compile step), copy all workspace package.json for
lockfile compatibility, and filter install to gateway deps only (616 vs
1911 packages). Also update build-and-push script to tag latest.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 13:27:41 +08:00
Naiyuan Qing
6ef58a0cab refactor: restructure to monorepo architecture
- Move core agent engine to packages/core/
- Add packages/types/ for shared TypeScript types
- Add packages/utils/ for utility functions
- Add apps/cli/ for command-line interface
- Add apps/gateway/ for NestJS WebSocket gateway
- Add apps/server/ for REST API server
- Restructure desktop app (electron/ → src/main/, src/preload/)
- Update pnpm workspace configuration
- Remove legacy src/ directory

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-10 18:00:23 +08:00