Lets the bot quote-reply to a specific message via an optional replyTo
on sendSingleMessage, and reworks history serialization so the LLM can
address messages and stop confusing quoted content with the quoter.
- Serialize each history line with a short [n] id; consecutive messages
from the same sender continue under "[n] └". A per-subject ReplyIndex
maps [n] -> MessageRecord, kept alive with the context cache so ids
stay continuous across cached turns.
- Replace inlined quote text with a reference: "↩[k]" when the quoted
message is in-window, otherwise "↩(author:"snippet…")". This removes
the ambiguity where A quoting B looked like A's own speech.
- Collapse forwarded messages to "[转发消息·N条:title]".
- sendSingleMessage accepts replyTo (the [n]); it resolves the record via
MessageRecord.toMessageSource() and prepends a QuoteReply, falling back
to a plain send with a note if the source is gone. ids may be null, so
numbering still happens but such records can't be reply targets.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The firstChunkTimeout only wrapped the response-body read, but when the
upstream (e.g. DeepSeek under load) stalls before sending response
headers, httpClient.post() itself blocks and the withTimeout block is
never reached. Every slow request fell through to Ktor's
requestTimeoutMillis (120s) and was retried up to retryMax times,
causing multi-minute waits before any reply.
- Move post() inside withTimeout(firstChunkTimeout) so the entire
request-to-first-data-chunk window is bounded and fails fast.
- Apply withTimeout(firstChunkTimeout) to each streaming read so a
mid-stream stall is also caught quickly instead of waiting on the
socket/request backstop.
- Drop requestTimeoutMillis so legitimately long streams are no longer
killed at 120s; TTFT and inter-token gaps are now governed at the
application layer.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds an optional instructions parameter to sendVoiceMessage so the model
can describe tone, pace and emotion in natural language. Defaults the
TTS model to qwen3-tts-instruct-flash; Chelsie voice is unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Supports text-to-image, single-image edit and multi-image fusion (0-3
reference images) via a single tool. Renames imageEditModel config to
imageModel (default qwen-image-2.0) and adds imageWatermark toggle.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add /jgpt tokens [days] command for usage summary report
- Add /jgpt tokensUserDaily <userId> [days] for daily user stats
- Fix tokensDaily day calculation (was showing 4 days for 3-day query)
- Optimize tokens() from 5-6 passes to single pass (5-10x faster)
- Fix tokensUserDaily inefficient nickname lookup
- Add number formatting with thousand separators to all outputs
- Extract helper functions: calculateCutoffTimestamp, calculateTodayStartTimestamp
- Add parameter validation for days and limit
- Update README with new commands and formatted examples
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>