mirror of
https://github.com/open-webui/bot
synced 2025-05-14 17:36:19 +00:00
feat: integrate OpenRouter API and improve message handling - Added OpenRouter API integration for AI responses - Added debug logging for message handling - Improved AI suffix detection logic
This commit is contained in:
parent
e0efa290d6
commit
4df065b5bc
@ -10,3 +10,5 @@ except ImportError:
|
||||
|
||||
WEBUI_URL = os.getenv("WEBUI_URL", "http://localhost:8080")
|
||||
TOKEN = os.getenv("TOKEN", "")
|
||||
OPENROUTER_API_KEY = ""
|
||||
OPENROUTER_API_URL = "https://openrouter.ai/api/v1/chat/completions"
|
||||
|
132
bot/main.py
132
bot/main.py
@ -1,8 +1,51 @@
|
||||
import asyncio
|
||||
import socketio
|
||||
from env import WEBUI_URL, TOKEN
|
||||
import aiohttp
|
||||
import json
|
||||
from env import WEBUI_URL, TOKEN, OPENROUTER_API_KEY, OPENROUTER_API_URL
|
||||
from utils import send_message, send_typing
|
||||
|
||||
# Create a single session for all API calls
|
||||
session = None
|
||||
|
||||
async def get_session():
|
||||
global session
|
||||
if session is None:
|
||||
session = aiohttp.ClientSession()
|
||||
return session
|
||||
|
||||
async def cleanup():
|
||||
global session
|
||||
if session:
|
||||
await session.close()
|
||||
session = None
|
||||
|
||||
async def call_openrouter(message: str) -> str:
|
||||
headers = {
|
||||
"Authorization": f"Bearer {OPENROUTER_API_KEY}",
|
||||
"HTTP-Referer": "http://localhost:8080",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
payload = {
|
||||
"model": "mistralai/mistral-7b-instruct",
|
||||
"messages": [{"role": "user", "content": message}]
|
||||
}
|
||||
|
||||
try:
|
||||
session = await get_session()
|
||||
async with session.post(OPENROUTER_API_URL, headers=headers, json=payload) as response:
|
||||
if response.status == 200:
|
||||
data = await response.json()
|
||||
return data["choices"][0]["message"]["content"]
|
||||
else:
|
||||
error_text = await response.text()
|
||||
print(f"OpenRouter API error: {error_text}")
|
||||
return f"Error: Unable to get response from AI (Status {response.status})"
|
||||
except Exception as e:
|
||||
print(f"Error calling OpenRouter: {e}")
|
||||
return "Error: Unable to connect to AI service"
|
||||
|
||||
# Create an asynchronous Socket.IO client instance
|
||||
sio = socketio.AsyncClient(logger=False, engineio_logger=False)
|
||||
|
||||
@ -19,18 +62,57 @@ async def disconnect():
|
||||
|
||||
|
||||
# Define a function to handle channel events
|
||||
def events(user_id):
|
||||
@sio.on("channel-events")
|
||||
async def channel_events(data):
|
||||
if data["user"]["id"] == user_id:
|
||||
# Ignore events from the bot itself
|
||||
return
|
||||
# Keep track of processed message IDs to avoid duplicates
|
||||
processed_messages = set()
|
||||
|
||||
@sio.on("channel-events")
|
||||
async def on_channel_event(data):
|
||||
try:
|
||||
print(f"Received event: {data}")
|
||||
|
||||
if not isinstance(data, dict) or "data" not in data:
|
||||
return
|
||||
|
||||
if data["data"]["type"] == "message":
|
||||
print(f'{data["user"]["name"]}: {data["data"]["data"]["content"]}')
|
||||
await send_typing(sio, data["channel_id"])
|
||||
await asyncio.sleep(1) # Simulate a delay
|
||||
await send_message(data["channel_id"], "Pong!")
|
||||
message_id = data["data"]["data"].get("id")
|
||||
if message_id in processed_messages:
|
||||
print(f"Skipping already processed message: {message_id}")
|
||||
return
|
||||
|
||||
# Get the message content and channel ID
|
||||
message_content = data["data"]["data"]["content"]
|
||||
channel_id = data["channel_id"]
|
||||
|
||||
# Debug logging
|
||||
print(f"Received message: {message_content}")
|
||||
print(f"From user ID: {data['user']['id']}")
|
||||
print(f"Bot ID: {sio.user_id}")
|
||||
print(f"Ends with AI: {message_content.strip().upper().endswith('AI')}")
|
||||
|
||||
# Only respond to messages ending with AI (case-insensitive)
|
||||
if (message_content and channel_id and
|
||||
"user" in data and
|
||||
data["user"]["id"] != sio.user_id and
|
||||
message_content.strip().upper().endswith("AI")):
|
||||
|
||||
print(f'Processing AI request from {data["user"]["name"]}: {message_content}')
|
||||
print(f'Responding in channel: {channel_id}')
|
||||
|
||||
# Remove the "AI" suffix and any trailing whitespace
|
||||
query = message_content.strip()[:-2].strip()
|
||||
if query: # Only proceed if there's a message after removing "AI"
|
||||
await send_typing(sio, channel_id)
|
||||
try:
|
||||
response = await call_openrouter(query)
|
||||
await send_message(channel_id, response)
|
||||
except Exception as e:
|
||||
print(f"Error calling OpenRouter API: {e}")
|
||||
await send_message(channel_id, "Sorry, I'm unable to get a response from the AI service right now. Please try again later.")
|
||||
|
||||
if message_id:
|
||||
processed_messages.add(message_id)
|
||||
except Exception as e:
|
||||
print(f"Error handling event: {e}")
|
||||
|
||||
|
||||
# Define an async function for the main workflow
|
||||
@ -41,21 +123,25 @@ async def main():
|
||||
WEBUI_URL, socketio_path="/ws/socket.io", transports=["websocket"]
|
||||
)
|
||||
print("Connection established!")
|
||||
|
||||
# Authenticate with the server
|
||||
print("Authenticating with server...")
|
||||
response = await sio.call("user-join", {"auth": {"token": TOKEN}})
|
||||
sio.user_id = response["id"] # Store user ID for later use
|
||||
print(f"Authentication successful. User ID: {sio.user_id}")
|
||||
|
||||
# Wait indefinitely to keep the connection open
|
||||
await sio.wait()
|
||||
except Exception as e:
|
||||
print(f"Failed to connect: {e}")
|
||||
print(f"Failed to connect/authenticate: {e}")
|
||||
return
|
||||
|
||||
# Callback function for user-join
|
||||
async def join_callback(data):
|
||||
events(data["id"]) # Attach the event handlers dynamically
|
||||
|
||||
# Authenticate with the server
|
||||
await sio.emit("user-join", {"auth": {"token": TOKEN}}, callback=join_callback)
|
||||
|
||||
# Wait indefinitely to keep the connection open
|
||||
await sio.wait()
|
||||
|
||||
|
||||
# Actually run the async `main` function using `asyncio`
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
try:
|
||||
asyncio.run(main())
|
||||
finally:
|
||||
# Ensure we clean up the session
|
||||
if session:
|
||||
asyncio.run(cleanup())
|
||||
|
Loading…
Reference in New Issue
Block a user