Add AI-powered question answering with Perplexity API integration

- Integrate Perplexity AI API for intelligent question answering
- Add AIResponseHandler class with question detection and response generation
- Implement automatic question detection using regex patterns
- Add AI commands: /perplexity, /ai on/off for configuration
- Display AI responses in terminal before sending to Slack
- Update configuration management to store Perplexity API key
- Add comprehensive AI features documentation to README
- Update requirements.txt with OpenAI library dependency
- Fix Perplexity model name to use valid 'sonar' model
- Enhance interactive chat mode with AI-powered capabilities
- Maintain backward compatibility with existing CLI functionality
This commit is contained in:
reethu2703 2025-10-05 15:21:06 +05:30
parent a971d9366c
commit fd58016586
4 changed files with 210 additions and 13 deletions

View File

@ -1,4 +1,6 @@
SLACK_BOT_TOKEN=xoxb-9294326441810-9634538323301-TEDMBIwZqA5VJJU1yoRFX6NF SLACK_BOT_TOKEN=xoxb-9294326441810-9634538323301-TEDMBIwZqA5VJJU1yoRFX6NF
SLACK_CHANNEL_ID=C09JKHXS9L3 SLACK_CHANNEL_ID=C09JKHXS9L3
#https://bytelets.slack.com/archives/C09JKHXS9L3
# Perplexity AI API Key for intelligent question answering
# Get your API key from: https://www.perplexity.ai/
PERPLEXITY_API_KEY=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

View File

@ -1,6 +1,6 @@
# Slack Two-Way Chat CLI # Slack AI-Powered Two-Way Chat CLI
A powerful command-line tool for two-way communication with Slack channels. Send and receive messages in real-time with both CLI and interactive chat modes. A powerful command-line tool for AI-powered two-way communication with Slack channels. Send and receive messages in real-time with intelligent question-answering capabilities using Perplexity AI.
## Installation ## Installation
@ -11,9 +11,9 @@ pip install -r requirements.txt
## Usage ## Usage
### Interactive Two-Way Chat Mode (Recommended) ### Interactive AI-Powered Two-Way Chat Mode (Recommended)
Start an interactive chat session where you can send and receive messages: Start an interactive chat session where you can send and receive messages with AI-powered question answering:
```bash ```bash
python slack_poster.py --chat python slack_poster.py --chat
@ -22,10 +22,11 @@ python slack_poster.py -i
In chat mode, you can: In chat mode, you can:
- Type messages directly to send them to Slack - Type messages directly to send them to Slack
- Ask questions and get AI-powered answers automatically
- Use `/listen` to start receiving messages from others in real-time - Use `/listen` to start receiving messages from others in real-time
- View message history with `/history` - View message history with `/history`
- Use commands to manage your configuration - Use commands to manage your configuration
- Have your token and channel ID automatically saved for future sessions - Have your token, channel ID, and Perplexity API key automatically saved for future sessions
### Command Line Mode ### Command Line Mode
@ -71,14 +72,41 @@ When in chat mode, you can use the following commands:
- `/quit` or `/q` or `/exit` - Exit the chat - `/quit` or `/q` or `/exit` - Exit the chat
- `/token <token>` - Set or update your Slack token - `/token <token>` - Set or update your Slack token
- `/channel <id>` - Set or update the channel ID - `/channel <id>` - Set or update the channel ID
- `/status` - Show current configuration (token and channel) - `/perplexity <key>` - Set or update your Perplexity API key
- `/status` - Show current configuration (token, channel, and AI settings)
- `/clear` - Clear all saved configuration - `/clear` - Clear all saved configuration
- `/test` - Send a test message to verify your configuration - `/test` - Send a test message to verify your configuration
- `/listen` - Start listening for incoming messages in real-time - `/listen` - Start listening for incoming messages in real-time
- `/stop` - Stop listening for messages - `/stop` - Stop listening for messages
- `/history [n]` - Show recent message history (default: 10 messages) - `/history [n]` - Show recent message history (default: 10 messages)
- `/ai on/off` - Enable or disable AI responses
- `<message>` - Send any text as a message to the current channel - `<message>` - Send any text as a message to the current channel
## AI-Powered Question Answering Features
The tool now includes intelligent question-answering capabilities using Perplexity AI:
### Automatic Question Detection
- AI automatically detects when you ask questions
- Supports various question formats: "What is...?", "How do...?", "Why...?", etc.
- Responds with intelligent, accurate answers
### AI Response Examples
```
> What is the capital of India?
[14:30:15] You: What is the capital of India?
[OK] Message sent to #C09JKHXS9L3
[AI] Thinking...
[14:30:18] AI Bot: The capital of India is New Delhi.
[OK] AI response sent to #C09JKHXS9L3
```
### AI Configuration
- Use `/perplexity <your-api-key>` to set your Perplexity API key
- Use `/ai on` to enable automatic AI responses
- Use `/ai off` to disable AI responses
- AI responses are sent to the Slack channel with 🤖 AI: prefix
## Two-Way Communication Features ## Two-Way Communication Features
The tool now supports full two-way communication with Slack channels: The tool now supports full two-way communication with Slack channels:
@ -117,7 +145,9 @@ The tool handles various error scenarios:
- Network issues - Network issues
- Empty messages - Empty messages
## Getting Slack Credentials ## Getting API Credentials
### Slack Credentials
1. Go to https://api.slack.com/apps 1. Go to https://api.slack.com/apps
2. Create a new app or select existing one 2. Create a new app or select existing one
@ -132,6 +162,15 @@ The tool handles various error scenarios:
5. Install the app to your workspace 5. Install the app to your workspace
6. Copy the Bot User OAuth Token (starts with `xoxb-`) 6. Copy the Bot User OAuth Token (starts with `xoxb-`)
### Perplexity AI Credentials
1. Go to https://www.perplexity.ai/
2. Sign up for an account
3. Go to your account settings or API section
4. Generate an API key
5. Copy the API key (starts with `pplx-`)
6. Use `/perplexity <your-api-key>` in the chat to set it
## Channel ID ## Channel ID
To get a channel ID: To get a channel ID:

View File

@ -1,3 +1,4 @@
slack_sdk>=3.21.0 slack_sdk>=3.21.0
requests>=2.28.0 requests>=2.28.0
python-dotenv>=1.0.0 python-dotenv>=1.0.0
openai>=1.0.0

View File

@ -15,6 +15,7 @@ import time
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import Optional, Dict, Any, List from typing import Optional, Dict, Any, List
import re
try: try:
from slack_sdk import WebClient from slack_sdk import WebClient
@ -23,6 +24,12 @@ except ImportError:
print("Error: slack_sdk not installed. Run: pip install slack_sdk") print("Error: slack_sdk not installed. Run: pip install slack_sdk")
sys.exit(1) sys.exit(1)
try:
import openai
except ImportError:
print("Warning: openai not installed. AI features will be disabled. Run: pip install openai")
openai = None
# Try to load environment variables from .env file # Try to load environment variables from .env file
try: try:
from dotenv import load_dotenv from dotenv import load_dotenv
@ -32,6 +39,58 @@ except ImportError:
pass pass
class AIResponseHandler:
"""Handles AI-powered responses using Perplexity API."""
def __init__(self, api_key: str):
"""Initialize the AI response handler."""
if openai is None:
raise ImportError("OpenAI library not installed")
self.client = openai.OpenAI(
api_key=api_key,
base_url="https://api.perplexity.ai"
)
def is_question(self, text: str) -> bool:
"""Check if the text is a question."""
# Simple question detection patterns
question_patterns = [
r'\?$', # Ends with question mark
r'^(what|where|when|why|how|who|which|can|could|would|should|is|are|was|were|do|does|did)\b', # Starts with question words
r'\b(what|where|when|why|how|who|which|can|could|would|should|is|are|was|were|do|does|did)\b', # Contains question words
]
text_lower = text.lower().strip()
for pattern in question_patterns:
if re.search(pattern, text_lower):
return True
return False
def get_ai_response(self, question: str) -> str:
"""Get AI response for a question."""
try:
response = self.client.chat.completions.create(
model="sonar",
messages=[
{
"role": "system",
"content": "You are a helpful assistant. Provide concise, accurate answers to questions. Keep responses brief and informative."
},
{
"role": "user",
"content": question
}
],
max_tokens=200,
temperature=0.7
)
return response.choices[0].message.content.strip()
except Exception as e:
return f"[AI Error] Failed to get response: {str(e)}"
class ConfigManager: class ConfigManager:
"""Manages persistent configuration storage.""" """Manages persistent configuration storage."""
@ -67,6 +126,10 @@ class ConfigManager:
"""Get stored channel ID.""" """Get stored channel ID."""
return self.config.get('channel') return self.config.get('channel')
def get_perplexity_key(self) -> Optional[str]:
"""Get stored Perplexity API key."""
return self.config.get('perplexity_key')
def set_token(self, token: str) -> None: def set_token(self, token: str) -> None:
"""Set and save Slack token.""" """Set and save Slack token."""
self.config['token'] = token self.config['token'] = token
@ -77,6 +140,11 @@ class ConfigManager:
self.config['channel'] = channel self.config['channel'] = channel
self.save_config() self.save_config()
def set_perplexity_key(self, api_key: str) -> None:
"""Set and save Perplexity API key."""
self.config['perplexity_key'] = api_key
self.save_config()
def clear_config(self) -> None: def clear_config(self) -> None:
"""Clear all stored configuration.""" """Clear all stored configuration."""
self.config = {} self.config = {}
@ -322,20 +390,28 @@ def validate_channel(channel: str) -> bool:
def print_help(): def print_help():
"""Print help information for interactive mode.""" """Print help information for interactive mode."""
print("\n" + "="*70) print("\n" + "="*70)
print("SLACK TWO-WAY CHAT MODE - Available Commands:") print("SLACK AI-POWERED TWO-WAY CHAT MODE - Available Commands:")
print("="*70) print("="*70)
print(" /help, /h - Show this help message") print(" /help, /h - Show this help message")
print(" /quit, /q, /exit - Exit the chat") print(" /quit, /q, /exit - Exit the chat")
print(" /token <token> - Set/update Slack token") print(" /token <token> - Set/update Slack token")
print(" /channel <id> - Set/update channel ID") print(" /channel <id> - Set/update channel ID")
print(" /perplexity <key> - Set/update Perplexity API key")
print(" /status - Show current configuration") print(" /status - Show current configuration")
print(" /clear - Clear saved configuration") print(" /clear - Clear saved configuration")
print(" /test - Test current configuration") print(" /test - Test current configuration")
print(" /listen - Start listening for incoming messages") print(" /listen - Start listening for incoming messages")
print(" /stop - Stop listening for messages") print(" /stop - Stop listening for messages")
print(" /history [n] - Show recent message history (default: 10)") print(" /history [n] - Show recent message history (default: 10)")
print(" /ai on/off - Enable/disable AI responses")
print(" <message> - Send message to current channel") print(" <message> - Send message to current channel")
print("="*70) print("="*70)
print("AI FEATURES:")
print(" - Ask questions and get AI-powered answers automatically")
print(" - AI detects questions and responds with intelligent answers")
print(" - Use /perplexity <key> to set your Perplexity API key")
print(" - Use /ai on to enable automatic AI responses")
print("="*70)
print("TWO-WAY FEATURES:") print("TWO-WAY FEATURES:")
print(" - Messages sent by others will appear automatically when listening") print(" - Messages sent by others will appear automatically when listening")
print(" - Use /listen to start receiving messages in real-time") print(" - Use /listen to start receiving messages in real-time")
@ -345,13 +421,15 @@ def print_help():
def interactive_chat_mode(config_manager: ConfigManager): def interactive_chat_mode(config_manager: ConfigManager):
"""Run interactive chat mode.""" """Run interactive chat mode."""
print("\n[CHAT] Welcome to Slack Two-Way Interactive Chat Mode!") print("\n[CHAT] Welcome to Slack AI-Powered Two-Way Interactive Chat Mode!")
print("Type your messages to send them to Slack.") print("Type your messages to send them to Slack.")
print("Ask questions and get AI-powered answers automatically!")
print("Use /help for available commands.\n") print("Use /help for available commands.\n")
# Check if we have stored configuration (try environment variables first, then config file) # Check if we have stored configuration (try environment variables first, then config file)
token = os.getenv('SLACK_BOT_TOKEN') or config_manager.get_token() token = os.getenv('SLACK_BOT_TOKEN') or config_manager.get_token()
channel = os.getenv('SLACK_CHANNEL_ID') or config_manager.get_channel() channel = os.getenv('SLACK_CHANNEL_ID') or config_manager.get_channel()
perplexity_key = os.getenv('PERPLEXITY_API_KEY') or config_manager.get_perplexity_key()
if not token: if not token:
print("No Slack token found. Please set one using /token <your-token>") print("No Slack token found. Please set one using /token <your-token>")
@ -361,12 +439,19 @@ def interactive_chat_mode(config_manager: ConfigManager):
print(f"[OK] Using configuration:") print(f"[OK] Using configuration:")
print(f" Channel: {channel}") print(f" Channel: {channel}")
print(f" Token: {token[:10]}...") print(f" Token: {token[:10]}...")
if perplexity_key:
print(f" Perplexity API: {perplexity_key[:10]}...")
else:
print(" Perplexity API: Not set (use /perplexity <key>)")
print("\nReady to chat! Type your message or use /help for commands.") print("\nReady to chat! Type your message or use /help for commands.")
print("Use /listen to start receiving messages from others.\n") print("Use /listen to start receiving messages from others.")
print("Ask questions like 'What is the capital of India?' for AI answers!\n")
poster = None poster = None
message_receiver = None message_receiver = None
ai_handler = None
ai_enabled = False
while True: while True:
try: try:
@ -422,6 +507,9 @@ def interactive_chat_mode(config_manager: ConfigManager):
print(f"\n[STATUS] Current Configuration:") print(f"\n[STATUS] Current Configuration:")
print(f" Token: {token[:10] + '...' if token else 'Not set'}") print(f" Token: {token[:10] + '...' if token else 'Not set'}")
print(f" Channel: {channel if channel else 'Not set'}") print(f" Channel: {channel if channel else 'Not set'}")
print(f" Perplexity API: {perplexity_key[:10] + '...' if perplexity_key else 'Not set'}")
print(f" AI Responses: {'Enabled' if ai_enabled else 'Disabled'}")
print(f" AI Handler: {'Ready' if ai_handler else 'Not initialized'}")
continue continue
elif command == '/clear': elif command == '/clear':
@ -516,6 +604,56 @@ def interactive_chat_mode(config_manager: ConfigManager):
print(f"[ERROR] Failed to get message history: {e}") print(f"[ERROR] Failed to get message history: {e}")
continue continue
elif command == '/perplexity':
parts = user_input.split(' ', 1)
if len(parts) < 2:
print("[ERROR] Usage: /perplexity <your-perplexity-api-key>")
continue
new_key = parts[1].strip()
config_manager.set_perplexity_key(new_key)
perplexity_key = new_key
# Initialize AI handler
try:
ai_handler = AIResponseHandler(perplexity_key)
print("[OK] Perplexity API key updated and AI handler initialized!")
except ImportError:
print("[ERROR] OpenAI library not installed. Run: pip install openai")
except Exception as e:
print(f"[ERROR] Failed to initialize AI handler: {e}")
continue
elif command == '/ai':
parts = user_input.split()
if len(parts) < 2:
print(f"[INFO] AI responses are currently {'enabled' if ai_enabled else 'disabled'}")
print("[USAGE] /ai on - Enable AI responses")
print("[USAGE] /ai off - Disable AI responses")
continue
action = parts[1].lower()
if action == 'on':
if not perplexity_key:
print("[ERROR] Please set Perplexity API key first using /perplexity <key>")
continue
if not ai_handler:
try:
ai_handler = AIResponseHandler(perplexity_key)
except Exception as e:
print(f"[ERROR] Failed to initialize AI handler: {e}")
continue
ai_enabled = True
print("[OK] AI responses enabled! Ask questions to get AI answers.")
elif action == 'off':
ai_enabled = False
print("[OK] AI responses disabled.")
else:
print("[ERROR] Usage: /ai on or /ai off")
continue
else: else:
print(f"[ERROR] Unknown command: {command}. Use /help for available commands.") print(f"[ERROR] Unknown command: {command}. Use /help for available commands.")
continue continue
@ -544,6 +682,23 @@ def interactive_chat_mode(config_manager: ConfigManager):
print(f"[{formatted_time}] You: {user_input}") print(f"[{formatted_time}] You: {user_input}")
print(f"[OK] Message sent to #{channel}") print(f"[OK] Message sent to #{channel}")
# Check if AI should respond to this message
if ai_enabled and ai_handler and ai_handler.is_question(user_input):
try:
print("[AI] Thinking...")
ai_response = ai_handler.get_ai_response(user_input)
# Display AI response in terminal first
ai_timestamp = datetime.now().strftime('%H:%M:%S')
print(f"[{ai_timestamp}] AI Bot: {ai_response}")
# Then send AI response to Slack
poster.post_message(channel, f"🤖 AI: {ai_response}")
print(f"[OK] AI response sent to #{channel}")
except Exception as e:
print(f"[AI ERROR] Failed to generate AI response: {e}")
except SlackApiError as e: except SlackApiError as e:
error_msg = str(e) error_msg = str(e)
if "invalid_auth" in error_msg.lower(): if "invalid_auth" in error_msg.lower():