#19816: feat(slack): add typingReaction config for DM typing indicator fallback
channel: slack
size: XS
Cluster:
Reaction Event Handling Enhancements
Adds a reaction-based typing indicator for Slack DMs that works without assistant mode. When `channels.slack.typingReaction` is set (e.g. "hourglass_flowing_sand"), the emoji is added to the user's message when processing starts and removed when the reply is sent.
Addresses #19809
## Summary
- **Problem:** Slack DMs show no typing indicator when `typingMode: "instant"` is configured. The only mechanism (`assistant.threads.setStatus`) requires Slack's "Agents & AI Apps" mode, which forces a thread-based UX.
- **Why it matters:** Users get zero feedback that the bot is processing their message in regular Slack DMs.
- **What changed:** Added `channels.slack.typingReaction` config option. When set, a reaction emoji is added to the user's message on processing start and removed when done — alongside the existing `setStatus` call.
- **What did NOT change:** No changes to `assistant.threads.setStatus` logic, shared `TypingController`, or ack reactions. Omitting the config preserves current behavior.
## Change Type (select all)
- [ ] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra
## Scope (select all touched areas)
- [ ] Gateway / orchestration
- [ ] Skills / tool execution
- [ ] Auth / tokens
- [ ] Memory / storage
- [x] Integrations
- [ ] API / contracts
- [ ] UI / DX
- [ ] CI/CD / infra
## Linked Issue/PR
- Closes #19809
- Related #7647
## User-visible / Behavior Changes
New opt-in config `channels.slack.typingReaction` (string, e.g. `"hourglass_flowing_sand"`). When set, adds a reaction to the user's message during processing and removes it after reply. No behavior change when omitted.
## Security Impact (required)
- New permissions/capabilities? No
- Secrets/tokens handling changed? No
- New/changed network calls? No (uses existing `reactions.add`/`reactions.remove` Slack API)
- Command/tool execution surface changed? No
- Data access scope changed? No
- If any Yes, explain risk + mitigation: N/A
## Repro + Verification
### Environment
- OS: macOS
- Runtime/container: Node 22
- Model/provider: N/A
- Integration/channel: Slack (socket mode)
- Relevant config: `{ "channels": { "slack": { "typingReaction": "hourglass_flowing_sand" } } }`
### Steps
1. Set `channels.slack.typingReaction` to `"hourglass_flowing_sand"` in config.
2. Send a DM to the Slack bot.
3. Observe reaction on your message while bot processes, removed after reply.
### Expected
Hourglass reaction appears during processing, removed when reply is sent.
### Actual
Matches expected (verified via build + tests; live Slack testing requires bot credentials).
## Evidence
- [x] Failing test/log before + passing after
- [ ] Trace/log snippets
- [ ] Screenshot/recording
- [ ] Perf numbers
## Human Verification (required)
- Verified: `pnpm build` passes, all 132 Slack monitor tests pass, no linter errors.
- Edge cases: omitted config = no change; empty string = no reaction; reaction add/remove failures silently caught.
- Not verified: live Slack bot DM (requires bot credentials and workspace).
## Compatibility / Migration
- Backward compatible? Yes
- Config/env changes? Yes (new optional field `channels.slack.typingReaction`)
- Migration needed? No
- If yes, exact upgrade steps: N/A
## Failure Recovery (if this breaks)
- Remove `typingReaction` from config or set to empty string. No restart required beyond config reload.
- Files: revert 5 files in this commit.
- Watch for: unexpected reactions left on messages (would mean the stop/remove path failed).
## Risks and Mitigations
- Risk: Bot lacks `reactions:write` scope, so reaction calls fail.
- Mitigation: Both `reactSlackMessage` and `removeSlackReaction` are wrapped in `.catch(() => {})` — failures are silent and don't block the reply flow.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds a new opt-in `channels.slack.typingReaction` config option that provides a reaction-based typing indicator for Slack DMs when assistant mode is not available. When configured (e.g., `"hourglass_flowing_sand"`), a reaction emoji is added to the user's message when processing starts and removed when the reply is sent. The implementation follows existing patterns (mirrors `ackReaction` in config/schema, uses existing `reactSlackMessage`/`removeSlackReaction` actions with silent `.catch(() => {})` error handling).
- The config, Zod schema, context, and dispatch changes are clean and well-integrated.
- **Type check breakage**: the new required `typingReaction: string` parameter on `createSlackMonitorContext` is not supplied by existing test helpers in `monitor.test.ts` and `prepare.test.ts`, which will cause `pnpm tsgo` / `pnpm check` to fail.
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge after fixing the missing test parameter; runtime behavior is correct and well-guarded.
- The feature implementation is clean, follows existing patterns, and has proper error handling. The only issue is a missing required parameter in two test files that will break type checking (pnpm tsgo). Runtime code is unaffected.
- src/slack/monitor/monitor.test.ts and src/slack/monitor/message-handler/prepare.test.ts need typingReaction added to their createSlackMonitorContext calls.
<sub>Last reviewed commit: 6137873</sub>
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#19917: feat(discord): allow disabling intermediate status reactions
by Gitjay11 · 2026-02-18
81.5%
#15768: feat(slack): Add queue position indicators for message queues
by haynzz · 2026-02-13
81.3%
#9520: fix: ignore slack already_reacted
by bolismauro · 2026-02-05
80.7%
#20860: feat(reactions): add configurable immediate reaction dispatch system
by davidrudduck · 2026-02-19
80.6%
#20406: fix(slack): respect replyToMode when computing statusThreadTs in DMs
by QuinnYates · 2026-02-18
78.6%
#16716: feat(feishu): add reaction event support (created/deleted)
by schumilin · 2026-02-15
78.3%
#21346: [AI-assisted] Telegram: add reaction state machine with fallback an...
by Archie818 · 2026-02-19
78.0%
#23320: fix(slack): respect replyToMode when incomingThreadTs is auto-created
by dorukardahan · 2026-02-22
77.9%
#6089: fix(slack): add reactionNotifications config check to reactions han...
by jontsai · 2026-02-01
77.8%
#19403: feat(slack): add dm.threadSession option for per-message thread ses...
by Vasiliy-Bondarenko · 2026-02-17
77.8%