Skip to content

fix: restore immediate bot activity indicators#1956

Merged
yottahmd merged 1 commit intomainfrom
fix/bot-activity-indicator-timing
Apr 2, 2026
Merged

fix: restore immediate bot activity indicators#1956
yottahmd merged 1 commit intomainfrom
fix/bot-activity-indicator-timing

Conversation

@yottahmd
Copy link
Copy Markdown
Collaborator

@yottahmd yottahmd commented Apr 2, 2026

Summary

  • restore immediate Telegram typing and Slack thinking indicators when inbound messages are enqueued
  • keep inbound batching intact while clearing pre-flush indicators on cancel, reset, and local submission failures
  • add regression coverage for immediate indicator visibility, batching dedupe, and cleanup paths

Root Cause

The inbound batching refactor delayed the first visible activity indicator until after the debounce flush. That created dead air on new messages and could make the indicator effectively invisible for fast responses.

Testing

  • go test ./internal/service/telegram ./internal/service/slack

Summary by CodeRabbit

Release Notes

  • New Features

    • Added persistent "thinking" status indicators in Slack that display when the bot is processing messages
  • Bug Fixes

    • Fixed cleanup of visual indicators when cancel commands are issued or operations fail
    • Improved timing of typing indicators in Telegram to start immediately upon message receipt

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 2, 2026

📝 Walkthrough

Walkthrough

Enhanced Slack and Telegram bot implementations to manage "thinking" and "typing" indicators throughout the message lifecycle, including ensuring indicators appear on message arrival, clearing them on errors, and clearing them during session cancellation.

Changes

Cohort / File(s) Summary
Slack Bot Implementation
internal/service/slack/bot.go
Added ensureThinkingIndicator() calls before message enqueue/flush operations; extended cancel flows and error paths to clear pending indicators via clearPendingIndicators(); unified thinking-message deletion in resetChat() to use the new clear method.
Slack Bot Tests
internal/service/slack/bot_test.go
Extended fakeSlackAgentService mock with createErr, cancelErr, and enqueueErr fields; updated mock methods to return configured errors; adjusted batching test to verify single thinking-indicator post with reuse on subsequent messages; added three new tests validating thinking-indicator lifecycle on cancel, create-session failure, and enqueue failure.
Telegram Bot Implementation
internal/service/telegram/bot.go
Refactored handleCommand() to retrieve chat session once at function entry; added early stopTypingLoop() call before checking active session on /cancel command; moved typing-loop start in enqueueIncomingMessage() to occur before message enqueue.
Telegram Bot Tests
internal/service/telegram/bot_test.go
Extended fakeTelegramAgentService mock with createErr and cancelErr fields; updated mock methods to return configured errors; enhanced batching test to verify typing-loop starts immediately on first message and reuses on subsequent batched messages; added new test validating typing-loop cleanup on cancel without active session.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Slack/Telegram Client
    participant Bot as Bot Service
    participant Agent as Agent Service
    participant Chat as Chat Platform

    rect rgba(100, 200, 100, 0.5)
    Note over Client,Chat: New Message Flow (with thinking indicator)
    Client->>Bot: Incoming message
    Bot->>Chat: Ensure/start thinking indicator
    Bot->>Agent: Enqueue chat message
    Agent-->>Bot: Enqueue result
    end

    rect rgba(200, 100, 100, 0.5)
    Note over Client,Chat: Error Recovery Flow
    Bot->>Agent: Create session / Enqueue message (fails)
    Agent-->>Bot: Error response
    Bot->>Chat: Clear pending indicator
    Bot-->>Client: Send error reply
    end

    rect rgba(100, 100, 200, 0.5)
    Note over Client,Chat: Cancel Flow (pre-session)
    Client->>Bot: Cancel command
    Bot->>Chat: Clear pending indicator
    Bot->>Agent: Cancel session (if exists)
    Agent-->>Bot: Cancel result
    Bot-->>Client: Acknowledgement
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: restore immediate bot activity indicators' directly summarizes the main change: restoring immediate activity indicators (Telegram typing and Slack thinking) that were delayed by a batching refactor.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/bot-activity-indicator-timing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
internal/service/telegram/bot.go (1)

191-206: Duplicate stopTypingLoop call after CancelSession.

Line 193 stops the typing loop immediately after clearing pending messages. Line 205 calls stopTypingLoop again after CancelSession. Since stopTypingLoop is idempotent (sets typingCancel/typingDone to nil under lock), the second call is a harmless no-op but redundant—nothing between lines 193 and 205 restarts the loop.

🔧 Optional: Remove the redundant call
 	case "cancel":
 		b.clearPendingMessages(cs)
 		b.stopTypingLoop(cs)
 		sid, ownerUID := cs.ActiveSession()

 		if sid == "" {
 			b.sendText(chatID, "No active session.")
 			return
 		}

 		if err := b.agentAPI.CancelSession(ctx, sid, ownerUID); err != nil {
 			b.sendText(chatID, "Failed to cancel session: "+err.Error())
 			return
 		}
-		b.stopTypingLoop(cs)
 		b.sendText(chatID, "Session cancelled.")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/service/telegram/bot.go` around lines 191 - 206, The duplicate
stopTypingLoop call is redundant: remove the second stopTypingLoop invocation
after b.agentAPI.CancelSession to avoid unnecessary no-op; keep the initial
b.stopTypingLoop(cs) right after b.clearPendingMessages(cs) and leave the
CancelSession call and subsequent sendText/ActiveSession logic unchanged (look
for stopTypingLoop, clearPendingMessages, ActiveSession, CancelSession, and
sendText in this case "cancel" branch to locate the code).
internal/service/telegram/bot_test.go (1)

356-385: Test is valid but consider adding agentAPI for robustness.

The test omits agentAPI from the Bot struct. This works because the test relies on the early return at line 196-198 when no active session exists, never reaching b.agentAPI.CancelSession(...). However, if the /cancel logic is later modified to access agentAPI before checking ActiveSession(), this test would panic.

Consider adding the fake agent service for defensive test design:

🔧 Optional: Add agentAPI to test setup
 func TestBot_HandleCommand_CancelStopsPreFlushTypingWithoutSession(t *testing.T) {
 	t.Parallel()

 	api := &fakeTelegramAPI{}
 	logger := slog.New(slog.NewTextHandler(io.Discard, nil))
+	service := newFakeTelegramAgentService("ignored")
 	bot := &Bot{
+		agentAPI:     service,
 		botAPI:       api,
 		logger:       logger,
 		allowedChats: map[int64]struct{}{123: {}},
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/service/telegram/bot_test.go` around lines 356 - 385, The test
TestBot_HandleCommand_CancelStopsPreFlushTypingWithoutSession constructs a Bot
without populating bot.agentAPI which could cause a panic if /cancel logic
changes; update the test setup to assign a fake agent service to the Bot (e.g.,
create and set a fakeAgentAPI instance on bot.agentAPI) so bot.handleCommand has
a non-nil agentAPI during execution and the existing assertions around
getOrCreateChat, startTypingLoop, and assertTypingStops remain unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@internal/service/telegram/bot_test.go`:
- Around line 356-385: The test
TestBot_HandleCommand_CancelStopsPreFlushTypingWithoutSession constructs a Bot
without populating bot.agentAPI which could cause a panic if /cancel logic
changes; update the test setup to assign a fake agent service to the Bot (e.g.,
create and set a fakeAgentAPI instance on bot.agentAPI) so bot.handleCommand has
a non-nil agentAPI during execution and the existing assertions around
getOrCreateChat, startTypingLoop, and assertTypingStops remain unchanged.

In `@internal/service/telegram/bot.go`:
- Around line 191-206: The duplicate stopTypingLoop call is redundant: remove
the second stopTypingLoop invocation after b.agentAPI.CancelSession to avoid
unnecessary no-op; keep the initial b.stopTypingLoop(cs) right after
b.clearPendingMessages(cs) and leave the CancelSession call and subsequent
sendText/ActiveSession logic unchanged (look for stopTypingLoop,
clearPendingMessages, ActiveSession, CancelSession, and sendText in this case
"cancel" branch to locate the code).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 33f0ef6e-00c8-4b67-a0fc-027ec2d9b8eb

📥 Commits

Reviewing files that changed from the base of the PR and between 50d8a8b and 08cb8a6.

📒 Files selected for processing (4)
  • internal/service/slack/bot.go
  • internal/service/slack/bot_test.go
  • internal/service/telegram/bot.go
  • internal/service/telegram/bot_test.go

@yottahmd yottahmd merged commit 9022852 into main Apr 2, 2026
5 checks passed
@yottahmd yottahmd deleted the fix/bot-activity-indicator-timing branch April 2, 2026 15:54
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 2, 2026

Codecov Report

❌ Patch coverage is 77.77778% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.06%. Comparing base (01495ae) to head (08cb8a6).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
internal/service/slack/bot.go 66.66% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1956      +/-   ##
==========================================
+ Coverage   67.96%   68.06%   +0.09%     
==========================================
  Files         475      475              
  Lines       61304    61308       +4     
==========================================
+ Hits        41668    41729      +61     
+ Misses      15660    15610      -50     
+ Partials     3976     3969       -7     
Files with missing lines Coverage Δ
internal/service/telegram/bot.go 40.00% <100.00%> (+3.96%) ⬆️
internal/service/slack/bot.go 31.63% <66.66%> (+5.50%) ⬆️

... and 13 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 01495ae...08cb8a6. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant