← Back to PRs

#9985: feat(slack): add channel-aware context for AI Assistant threads

by natedenh open 2026-02-05 23:47 View on GitHub →
docs channel: slack stale
## Summary When a user opens the Slack AI Assistant panel while viewing a channel, OpenClaw now fetches recent messages from that channel and injects them into the conversation context. This enables the agent to answer questions like "summarize this channel" or "what's the team discussing?" without the user needing to provide any additional context. ## Changes ### New: `src/slack/monitor/channel-context.ts` - Fetches recent messages from the channel the user is viewing using `readSlackMessages` - Formats them into a concise context block with user mentions and relative timestamps - Respects a configurable message limit (default: 20) - Best-effort with 8s timeout — failures don't block message processing - Channel name resolution for readable headers (`#general` vs raw channel ID) ### Modified: `src/slack/monitor/message-handler/prepare.ts` - Detects assistant threads via stored context (`getThreadContext`) - Fetches channel messages when the thread has an associated channel context - Injects the context block as `UntrustedContext` (user-generated content, not system instructions) - Only fetches when the viewed channel differs from the thread's own channel ### Config: `src/config/types.slack.ts` + `src/config/schema.ts` - `assistant.channelContext`: Enable/disable channel context injection (default: `true` when assistant is enabled) - `assistant.channelContextMessageLimit`: Max messages to fetch (default: `20`) ### Docs: `docs/channels/slack.md` - New "AI Assistant" section documenting all assistant features including channel context - Config reference table with all options ### Tests: `src/slack/monitor/channel-context.test.ts` - 7 tests covering: empty results, message formatting, chronological ordering, error handling, empty text filtering, limit passthrough, channel name fallback ## Config example ```json { "slack": { "assistant": { "enabled": true, "channelContext": true, "channelContextMessageLimit": 20 } } } ``` ## How it works 1. User opens the assistant side panel while viewing `#general` 2. Slack fires `assistant_thread_started` with `context.channel_id` → stored by `saveThreadContext` 3. User sends "what's the team discussing?" 4. `prepareSlackMessage` detects the thread has channel context 5. Fetches last 20 messages from `#general` via `readSlackMessages` 6. Injects formatted context block into `UntrustedContext` 7. Agent receives the channel messages as context and can answer intelligently ## Notes - Builds on #9954 (assistant support foundation — event handlers, context storage, loading states) - Channel context is injected as `UntrustedContext` since the messages are user-generated content - The fetch races against an 8s timeout to prevent blocking slow API responses - `pnpm build` passes ✅ - All tests pass ✅ <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR adds Slack “Agents & AI Apps” assistant support and implements channel-aware context injection for assistant threads. It introduces helpers for assistant status/prompts/titles, stores per-thread assistant context in-memory with TTL cleanup, registers new Slack assistant event handlers, and extends `prepareSlackMessage` to optionally fetch recent channel messages and inject them as `UntrustedContext`. It also updates Slack config schema/types and adds tests for channel context formatting/fetch behavior. <h3>Confidence Score: 3/5</h3> - This PR is close, but needs fixes to ensure channel-context injection works as described and to avoid unintended load under Slack API slowness. - Main implementation is straightforward and covered by unit tests, but the current injection condition in `prepareSlackMessage` appears to prevent the primary use case from working, and the timeout strategy does not cancel the underlying Slack API call (can cause excess in-flight work). - src/slack/monitor/message-handler/prepare.ts, src/slack/monitor/channel-context.ts <!-- greptile_other_comments_section --> <sub>(5/5) You can turn off certain types of comments like style [here](https://app.greptile.com/review/github)!</sub> <!-- /greptile_comment -->

Most Similar PRs