feat: Fetch Slack thread history for agent context#5582
Conversation
…#1) When a user replies in a Slack thread where the bot has an active conversation session, the bot now processes the message even without an explicit @mention. This improves UX for ongoing threaded discussions. Changes: - Added set_session_store() to BasePlatformAdapter for adapters to check active sessions - Modified SlackAdapter to detect thread replies and check if a session exists for that thread before requiring @mentions - Updated GatewayRunner to inject the session store into adapters - Added comprehensive tests for the new behavior Fixes: Thread replies without @jarvis are now processed if there is an active session, matching user expectations for conversation flow Co-authored-by: eizus <hello@cdr.xyz>
The edit_message method was sending raw content directly to Slack's chat_update API without converting standard markdown to Slack's mrkdwn format. This caused broken formatting and malformed URLs (e.g., trailing ** from bold syntax became part of clickable links → 404 errors). The send() method already calls format_message() to handle this conversion, but edit_message() was bypassing it. This change ensures edited messages receive the same markdown → mrkdwn transformation as new messages. Closes: PR NousResearch#5558 formatting issue where links had trailing markdown syntax. Co-authored-by: eizus <hello@cdr.xyz>
… $299) - Replace 4-tier structure (Free/Writer/Pro/Agency) with 3-tier - Basic: $1/mo = 1 site, 10 quotes, 1 social - Starter: $10/mo = 3 sites, 1k quotes, 10 social - Agency: $299/mo = 100 sites, 100k quotes, 500 social - Update blog post pricing section - Adjust grid layout from 4 to 3 columns
Adds thread context injection to Slack messages: - _fetch_thread_history(): Fetches thread messages via Slack API - _format_thread_context(): Formats history as readable context block - Caches thread history (60s TTL) to avoid repeated API calls - Configurable via gateway.slack.include_thread_context (default: true) - Thread context is prepended to user messages before agent processing Enables agents to see full conversation history in Slack threads, matching behavior of systems like OpenClaw.
|
The mrkdwn fix and thread replies from this PR were already covered by #5568 and #5579 (both merged via #5733). The unique thread history feature (commit 9ef341c) was reviewed but not included — the duplicate context risk (thread messages appearing in both session history and prepended context) needs design iteration. Leaving open for now if you'd like to address that. |
|
Closing — the mrkdwn fix and thread reply handling from this PR were already merged via #5733 (from your cleaner standalone PRs #5568 and #5579). The unique thread history feature (commit 9ef341c) was reviewed but has design issues that need addressing before it could land:
The feature itself is valuable — agents seeing thread context is a real need. If you want to iterate on it, the key fix would be deduplicating against the session history so messages aren't seen twice. Thanks @jarvisxyz! |
- Add deduplication: context only fetched on first contact when no active session exists; comment clarifies messages are not duplicated in subsequent turns - Add rate limit handling: exponential backoff for Tier-3 conversations.replies (1s, 2s delays on 429) - Replace fragile list-based cache with typed _ThreadContextCache dataclass Addresses feedback from NousResearch#5582 (teknium1).
Fork PR: jarvisxyz#3
Summary:
Enables Hermes agents to see full conversation history in Slack threads by fetching prior messages via the Slack API.
Problem:
Currently, when users reply in a Slack thread, the agent only sees that single message — not the prior conversation context. This forces users to manually paste history or lose continuity. Systems like OpenClaw handle this automatically.
Solution:
conversations.replieswhen processing thread messagesgateway.slack.include_thread_context(default: true)Changes:
_fetch_thread_history(): Fetches messages from Slack API_format_thread_context(): Formats with[user]: messagepattern_handle_slack_message()Configuration: