Update queue state and processed message count; adjust last processed time and processor ID

This commit is contained in:
pacnpal
2025-02-13 09:18:12 -05:00
parent 4fe1505d92
commit 4a52f5fa99
11 changed files with 180820 additions and 199134 deletions

View File

@@ -5,6 +5,7 @@ import re
import uuid
import asyncio
from typing import Dict, Any
from datetime import datetime
from discord import Message, RawReactionActionEvent
from ..config import (
@@ -145,13 +146,12 @@ class EventHandler:
" [BOT OWNER]" if is_owner else ""
)
# Build user metadata
user_metadata = {
"user_id": str(user.id),
"is_owner": int(user.id) == BOT_OWNER_ID,
"name": user.name,
"display_name": user.display_name,
}
# Get conversation history for context
history = await self.db_manager.get_conversation_history(
user_id=0,
channel_id=payload.channel_id,
)
logger.debug(f"Retrieved {len(history)} messages for context")
# Build the reaction context
reaction_context = (
@@ -162,89 +162,55 @@ class EventHandler:
"based on the emoji and your personality."
)
# Build context for the API call
messages = [
{
"role": "system",
"content": SYSTEM_PROMPT,
"metadata": {
"bot_owner_id": str(BOT_OWNER_ID),
"current_user": {
"user_id": str(user.id)
}
},
# Build context with history and user info
context = {
"history": history,
"bot_info": {
"name": self.bot.user.name,
"display_name": self.bot.user.display_name,
"id": str(self.bot.user.id),
},
{
"role": "user",
"content": reaction_context,
"metadata": user_metadata,
"context": {
"timeout_env": "GLHF_TIMEOUT" # Use primary API timeout for reactions
}
"user_info": {
"name": user.name,
"display_name": user.display_name,
"id": str(user.id),
"is_owner": is_owner,
},
]
"reaction": {
"emoji": emoji_str,
"message_id": str(message.id),
"message_content": message.content,
},
"timeout_env": "GLHF_TIMEOUT"
}
# Get response from API
response = await self.api_manager.get_completion(messages)
if not response:
return
# Parse tool calls and get processed response
tool_calls, final_response, mentioned_users = self.tool_handler.parse_tool_calls(
response, message_id=message.id, channel_id=channel.id
# Create a fake message object for queue processing
from types import SimpleNamespace
fake_message = SimpleNamespace(
id=str(uuid.uuid4()),
author=SimpleNamespace(
id=user.id,
name=user.name,
display_name=user.display_name,
bot=False,
discriminator=getattr(user, 'discriminator', '0000')
),
channel=channel,
guild=getattr(channel, 'guild', None),
content=reaction_context,
bot=False,
created_at=datetime.utcnow()
)
# Execute tool calls
for tool_name, args in tool_calls:
try:
if tool_name == "find_user":
# Check if we're trying to mention the user who reacted
if args["name"].lower() in [
user.name.lower(),
user.display_name.lower(),
]:
mention = f"<@{user.id}>"
else:
mention = await self.tool_handler.find_user_by_name(
args["name"],
message.guild.id if message.guild else None,
)
if mention:
final_response = self._clean_mentions(
final_response,
mention,
user.display_name,
args["name"]
)
elif tool_name == "add_reaction":
await self.tool_handler.add_reaction(
message.id, channel.id, args["emoji"]
)
elif tool_name == "create_embed":
await self.tool_handler.create_embed(
channel=channel, content=args["content"]
)
elif tool_name == "create_thread":
await self.tool_handler.create_thread(
channel.id, args["name"], message.id
)
except Exception as e:
logger.error(f"Error executing tool {tool_name}: {e}")
# If there's any text response left, send it
if final_response:
logger.info(
f"Bot response to {user.display_name} ({user.name}#{user.discriminator})"
f"{' [BOT OWNER]' if user.id == BOT_OWNER_ID else ''}'s reaction: {final_response}"
)
await self.message_handler.safe_send(
channel, final_response, reference=message
)
logger.info(f"Adding reaction response to queue from {user.display_name}")
# Queue the reaction like a regular message
await self.queue_manager.add_message(
channel=channel,
message=fake_message,
prompt=reaction_context,
context=context,
priority=1, # Higher priority for reactions
)
except Exception as e:
logger.error(f"Error handling reaction: {e}")
@@ -393,6 +359,12 @@ class EventHandler:
if not message_in_history:
# Only store if not already in history
source = "discord"
if item.context.get("reaction"):
source = "reaction"
elif item.message.author.id == 0:
source = "web"
message_metadata = {
**item.context,
"message_uuid": message_uuid,
@@ -400,6 +372,10 @@ class EventHandler:
"name": item.message.author.name,
"display_name": item.message.author.display_name,
"id": str(item.message.author.id)
},
"source": {
"type": source,
"timestamp": datetime.utcnow().isoformat()
}
}
await self.store_message(
@@ -521,8 +497,13 @@ class EventHandler:
f"({author.name}#{author.discriminator})"
f"{owner_tag}: {final_response}"
)
# For fake messages (web/reactions), don't use reference
reference = None
if hasattr(item.message, '_state'): # Check if it's a real Discord Message
reference = item.message
sent_message = await self.message_handler.safe_send(
item.channel, final_response, reference=item.message
item.channel, final_response, reference=reference
)
if sent_message:
@@ -556,6 +537,15 @@ class EventHandler:
f"Continuations: {[m.id for m in messages]}"
)
# Get source from original message metadata
source_info = item.context.get("source", {})
if not source_info and "reaction" in item.context:
source_info = {"type": "reaction"}
elif not source_info and item.message.author.id == 0:
source_info = {"type": "web"}
else:
source_info = {"type": "discord"}
response_metadata = {
"response_id": response_uuid,
"user_info": {
@@ -567,9 +557,21 @@ class EventHandler:
"discord_message_id": str(sent_message.id),
"continuation_messages": len(messages) > 0,
"message_count": len(messages) + 1,
"message_ids": [str(sent_message.id)] + [str(m.id) for m in messages]
"message_ids": [str(sent_message.id)] + [str(m.id) for m in messages],
"source": {
"type": source_info["type"],
"timestamp": datetime.utcnow().isoformat(),
"in_response_to": {
"type": source_info["type"],
"message_id": str(item.message.id)
}
}
}
# For reactions, include the original message context
if source_info["type"] == "reaction" and "reaction" in item.context:
response_metadata["source"]["reaction_data"] = item.context["reaction"]
# Store the complete response
await self.store_message(
user_id=item.message.author.id,
@@ -604,59 +606,60 @@ class EventHandler:
logger.error(f"Could not find channel {channel_id}")
return
# Build messages array with system prompt
messages = [
{
"role": "system",
"content": SYSTEM_PROMPT,
"metadata": {
"bot_owner_id": str(BOT_OWNER_ID),
"current_user": {
"user_id": "0" # System user
}
}
# Get conversation history for context
history = await self.db_manager.get_conversation_history(
user_id=0,
channel_id=channel_id,
)
logger.debug(f"Retrieved {len(history)} messages for context")
# Build context with history and bot info
context = {
"history": history,
"bot_info": {
"name": self.bot.user.name,
"display_name": self.bot.user.display_name,
"id": str(self.bot.user.id),
},
{
"role": "user",
"content": prompt,
"context": {
"timeout_env": "GLHF_TIMEOUT"
}
}
]
"user_info": {
"name": "web_user",
"display_name": "Web User",
"id": "0",
},
"timeout_env": "GLHF_TIMEOUT"
}
# Get response from API
response = await self.api_manager.get_completion(messages)
if not response:
logger.error("No response received from API")
return
# Parse tool calls and get processed response
tool_calls, final_response, mentioned_users = self.tool_handler.parse_tool_calls(
response, channel_id=channel.id
logger.info(f"Adding web prompt to queue: {prompt}")
# Create a fake message object for queue processing
from types import SimpleNamespace
fake_message = SimpleNamespace(
id=str(uuid.uuid4()),
author=SimpleNamespace(
id=0,
name="web_user",
display_name="Web User",
bot=False,
discriminator="0000"
),
channel=channel,
guild=getattr(channel, 'guild', None),
content=prompt,
bot=False,
reference=None,
created_at=datetime.utcnow()
)
# Execute tool calls
for tool_name, args in tool_calls:
try:
if tool_name == "create_embed":
await self.tool_handler.create_embed(
channel=channel, content=args["content"]
)
elif tool_name == "create_thread":
await self.tool_handler.create_thread(
channel.id, args["name"]
)
except Exception as e:
logger.error(f"Error executing tool {tool_name}: {e}")
# Send the response
if final_response:
logger.info(f"Bot response to backend prompt: {final_response}")
await self.message_handler.safe_send(channel, final_response)
# Queue the message like a regular Discord message
await self.queue_manager.add_message(
channel=channel,
message=fake_message,
prompt=prompt,
context=context,
priority=1, # Higher priority for web messages
)
except Exception as e:
logger.error(f"Error processing backend prompt: {e}")
logger.error(f"Error processing web prompt: {e}")
await self.report_error(
e,
{