Replace the in-place streaming reply (openStream replace-mode frames)
with discrete pushed messages, so the chat no longer flickers while
the turn is running:
- each tool call pushes one notice message (正在使用X…); status frames
such as '正在整理结果…' and per-token text frames are not pushed
- the final answer arrives as one new markdown message
- a stopped turn still announces '已停止。'; no stream session is
created, so there is nothing to cancel or finalize
The shared Harness client emits a '正在整理结果…' status update after
every tool/result. Pushing each one into the QQ stream message made
multi-tool turns repeatedly flash that notice instead of showing real
progress. Skip status frames in the QQ onUpdate handler so the stream
keeps the last meaningful frame (tool name or generated text), which
matches the official dsh-qqbot behaviour of not pushing tool-noise.
Deliver final Harness answers to QQ as msg_type=2 markdown so bold,
headings, code blocks, lists, and tables render natively in QQ.
- add markdown-reply.mjs: chunk long answers at code-fence/table
boundaries (4500-char limit) and send each chunk with a unique
msg_seq to avoid passive-reply dedup (40054005)
- fall back to plain text per chunk when the platform rejects
markdown, so bots without markdown capability keep working
- route the non-stream final answer path in qq-bridge through the
markdown sender; streaming replies already use markdown content
type, and command/notice texts stay plain
Add setMyCommands and setChatMenuButton to the Telegram Bot API client
and register a 12-command menu with a commands-type menu button when a
bot runtime connects. Menu setup failures are logged as warnings and do
not block startup.
Co-authored-by: xmanrui <841206367@qq.com>