Skip to content

Commit 2ef9552

Browse files
committed
fix: Disable spinner animation to stay within rate limits (v1.6.4)
CRITICAL FIX: Animated spinner was causing excessive API calls. ## Problem Each editMessageText() counts as 1 API call toward Telegram's 20 msgs/min per-chat limit. The spinner animation updated every 1 second, which means: - 5 tools × 10 seconds = 50 seconds execution - Spinner updates: 50 calls - Tool status changes: 10 calls - Text updates: ~5 calls - Total: ~65 calls/min → EXCEEDS 20/min limit! Even at 3-second intervals: - Spinner: ~16 calls - Other: ~15 calls - Total: ~31 calls/min → Still exceeds limit! ## Solution **Disable spinner animation entirely.** The tool overview now only updates when tool status actually changes (start/done), not on a timer. Updates per minute: - Tool status changes: ~10 calls - Text updates: ~5 calls - Done message: 1 call - Total: ~16 calls/min ✅ Within 18/min limit ## Impact **Before (with spinner):** - Tool overview updates ~50 times/min - Risk of hitting rate limit - Could cause 429 errors **After (no spinner):** - Tool overview updates only on status change (~10 times) - Well within rate limits - No 429 risk ## User Experience Still responsive because: - Tool status changes update IMMEDIATELY - Counter updates in real-time (0/4 → 1/4 → 2/4) - No perceived delay since updates happen on meaningful events - Users see progress, just not cosmetic spinner animation ## Key Insight Telegram counts EVERY API call: - sendMessage = 1 call - editMessageText = 1 call ⭐️ - deleteMessage = 1 call There's no "free" edit operation. Even simple cosmetic updates consume the rate limit budget. ## Files Changed - src/telegram-message-queue.ts: Disable spinner, update only on status change - doc/rate-limiting.md: Document why spinner is disabled Prevents rate limit exhaustion from cosmetic updates.
1 parent cac8f09 commit 2ef9552

3 files changed

Lines changed: 16 additions & 28 deletions

File tree

doc/rate-limiting.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,14 @@ Intelligently batches and merges messages by priority:
6060

6161
**After:**
6262
```
63-
⚙️ Tools
63+
🔧 Tools
6464
🔧 Reading file.ts...
6565
📝 Editing config.json...
6666
🔍 Grepping pattern...
6767
✓ Writing output.txt
6868
2/4 complete
6969
```
70-
1 merged message with animated spinner (⚙️ → 🔧 → ⚡ → 💫), updated immediately when status changes
70+
1 merged message, updated immediately when tool status changes (no spinner to avoid rate limits)
7171

7272
### 3. Integration in `streaming.ts`
7373

@@ -218,13 +218,15 @@ To test with heavy tool usage:
218218

219219
## Responsiveness Optimizations
220220

221-
To prevent "stuck" feeling:
221+
To prevent "stuck" feeling while staying within rate limits:
222222

223223
1. **Tool updates are immediate** - Not batched, updated as soon as status changes
224-
2. **Animated spinner** - Cycles through emoji (⚙️ → 🔧 → ⚡ → 💫) every 1s to show activity
224+
2. **No animated spinner** - Removed to avoid excessive API calls (each edit = 1 API call)
225225
3. **Shorter delays** - Text batching uses 1.5s instead of 3s
226226
4. **Smart rate limiting** - Only delays when actually approaching limits
227227

228+
**Why no spinner?** Each `editMessageText()` counts as 1 API call toward the 20 msgs/min limit. Updating a spinner every 1-3 seconds would quickly exhaust the limit. Instead, the overview updates immediately when tool status changes (start/done), providing real-time feedback without excessive API calls.
229+
228230
## Future Improvements
229231

230232
Potential enhancements:

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ctb",
3-
"version": "1.6.3",
3+
"version": "1.6.4",
44
"description": "Control Claude Code from Telegram - run multiple bot instances per project",
55
"type": "module",
66
"bin": {

src/telegram-message-queue.ts

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -294,34 +294,20 @@ export class TelegramMessageQueue {
294294

295295
/**
296296
* Start spinner animation for tool overview.
297+
*
298+
* IMPORTANT: Spinner updates are DISABLED to avoid rate limiting.
299+
* Each editMessageText counts as an API call, and updating every few
300+
* seconds would quickly exhaust the 18 msgs/min per-chat limit.
301+
*
302+
* Instead, we only update when tool status actually changes.
297303
*/
298304
private startToolSpinner(ctx: Context, chatId: number): void {
299305
// Stop existing spinner if any
300306
this.stopToolSpinner(chatId);
301307

302-
const spinnerFrames = ["⚙️", "🔧", "⚡", "💫"];
303-
let frameIndex = 0;
304-
305-
const interval = setInterval(async () => {
306-
const tools = this.activeTools.get(chatId);
307-
if (!tools || tools.filter((t) => t.status === "running").length === 0) {
308-
this.stopToolSpinner(chatId);
309-
return;
310-
}
311-
312-
frameIndex = (frameIndex + 1) % spinnerFrames.length;
313-
await this.updateToolOverviewMessage(
314-
ctx,
315-
chatId,
316-
tools,
317-
spinnerFrames[frameIndex],
318-
).catch(() => {
319-
// Stop on error
320-
this.stopToolSpinner(chatId);
321-
});
322-
}, 1000); // Update spinner every 1 second
323-
324-
this.toolSpinners.set(chatId, interval);
308+
// Spinner animation is DISABLED - see comment above
309+
// We rely on tool status changes to update the overview message
310+
// This keeps us well within rate limits
325311
}
326312

327313
/**

0 commit comments

Comments
 (0)