Revert "feat: Implement user timeout functionality and enhance conversation context with user IDs"
This reverts commit 7eb0180dce6e74f5dd3026bd1abc86496ea88070.
This commit is contained in:
parent
be15146667
commit
e285ad6ce2
178
cogs/teto_cog.py
178
cogs/teto_cog.py
@ -24,45 +24,6 @@ class TetoCog(commands.Cog):
|
||||
self._api_endpoint = "https://openrouter.ai/api/v1/chat/completions" # Default endpoint
|
||||
self._ai_model = "google/gemini-2.5-flash-preview" # Default model
|
||||
|
||||
self.tools = [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "timeout_user",
|
||||
"description": "Times out a user in the Discord server.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user_id": {
|
||||
"type": "string",
|
||||
"description": "The ID of the user to time out."
|
||||
},
|
||||
"duration_seconds": {
|
||||
"type": "integer",
|
||||
"description": "The duration of the timeout in seconds."
|
||||
}
|
||||
},
|
||||
"required": ["user_id", "duration_seconds"]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
async def timeout_user(self, user_id: str, duration_seconds: int):
|
||||
"""Times out a user."""
|
||||
try:
|
||||
guild = self.bot.get_guild(1234567890) # Replace with actual guild ID or find dynamically
|
||||
if not guild:
|
||||
return f"Error: Could not find the guild."
|
||||
member = guild.get_member(int(user_id))
|
||||
if not member:
|
||||
return f"Error: Could not find user with ID {user_id} in the guild."
|
||||
await member.timeout(discord.utils.utcnow() + discord.timedelta(seconds=duration_seconds))
|
||||
return f"Successfully timed out user {member.display_name} for {duration_seconds} seconds."
|
||||
except Exception as e:
|
||||
return f"Error timing out user: {e}"
|
||||
|
||||
|
||||
async def _teto_reply_ai_with_messages(self, messages, system_mode="reply"):
|
||||
"""
|
||||
Use OpenRouter AI to generate a Kasane Teto-style response.
|
||||
@ -90,56 +51,6 @@ class TetoCog(commands.Cog):
|
||||
"When expressing emotions, prefer using text-based emoticons like :) and ;) as well as Japanese-style emoticons like >~<, ^~^, and OwO over emojis. \n"
|
||||
"Reply to the user in a short, conversational manner, staying in character."
|
||||
)
|
||||
|
||||
# Collect unique user IDs from the conversation history
|
||||
user_ids_in_convo = set()
|
||||
for message_entry in messages:
|
||||
if message_entry["role"] == "user":
|
||||
# Assuming user messages in history have a way to identify the author,
|
||||
# this might need adjustment based on how history is stored.
|
||||
# For now, let's assume the message object itself is available or can be retrieved.
|
||||
# This part needs refinement based on actual message history structure.
|
||||
# As a placeholder, let's assume we can get user ID from the message object.
|
||||
# In the on_message listener, we have the message object, but here we only have the history.
|
||||
# A better approach is to store user ID with the message in history.
|
||||
|
||||
# For now, let's try to extract user IDs from the text content if available
|
||||
if isinstance(message_entry["content"], list):
|
||||
for item in message_entry["content"]:
|
||||
if item["type"] == "text":
|
||||
# Simple regex to find potential user IDs in the text
|
||||
id_matches = re.findall(r"\(ID: (\d+)\)", item["text"])
|
||||
for user_id in id_matches:
|
||||
user_ids_in_convo.add(user_id)
|
||||
elif isinstance(message_entry["content"], str):
|
||||
id_matches = re.findall(r"\(ID: (\d+)\)", message_entry["content"])
|
||||
for user_id in id_matches:
|
||||
user_ids_in_convo.add(user_id)
|
||||
|
||||
|
||||
# Add list of users from conversation to the system prompt
|
||||
if user_ids_in_convo:
|
||||
user_list_text = "Users in this conversation:\n"
|
||||
for user_id in user_ids_in_convo:
|
||||
try:
|
||||
# Attempt to fetch member to get display name
|
||||
guild = self.bot.get_guild(1234567890) # Replace with actual guild ID or find dynamically
|
||||
if guild:
|
||||
member = guild.get_member(int(user_id))
|
||||
if member:
|
||||
user_list_text += f"- {member.display_name} (ID: {user_id})\n"
|
||||
else:
|
||||
user_list_text += f"- Unknown User (ID: {user_id})\n"
|
||||
else:
|
||||
user_list_text += f"- Unknown User (ID: {user_id}) (Could not find guild)\n"
|
||||
except ValueError:
|
||||
user_list_text += f"- Invalid User ID format: {user_id}\n"
|
||||
|
||||
system_prompt += f"\n\n{user_list_text}"
|
||||
else:
|
||||
system_prompt += "\n\nNo specific users identified in the conversation history."
|
||||
|
||||
|
||||
payload = {
|
||||
"model": self._ai_model,
|
||||
"messages": [{"role": "system", "content": system_prompt}] + messages,
|
||||
@ -155,75 +66,7 @@ class TetoCog(commands.Cog):
|
||||
data = await resp.json()
|
||||
if "choices" not in data or not data["choices"]:
|
||||
raise RuntimeError(f"OpenRouter API returned unexpected response format: {data}")
|
||||
|
||||
ai_response_message = data["choices"][0]["message"]
|
||||
|
||||
# Handle tool calls
|
||||
if "tool_calls" in ai_response_message and ai_response_message["tool_calls"]:
|
||||
tool_calls = ai_response_message["tool_calls"]
|
||||
tool_responses = []
|
||||
for tool_call in tool_calls:
|
||||
tool_name = tool_call["function"]["name"]
|
||||
tool_args = tool_call["function"]["arguments"] # This is a string
|
||||
try:
|
||||
tool_args_dict = json.loads(tool_args)
|
||||
if tool_name == "timeout_user":
|
||||
user_id = tool_args_dict.get("user_id")
|
||||
duration_seconds = tool_args_dict.get("duration_seconds")
|
||||
if user_id and duration_seconds is not None:
|
||||
tool_result = await self.timeout_user(user_id, duration_seconds)
|
||||
tool_responses.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call["id"],
|
||||
"name": tool_name,
|
||||
"content": tool_result,
|
||||
})
|
||||
else:
|
||||
tool_responses.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call["id"],
|
||||
"name": tool_name,
|
||||
"content": f"Error: Missing user_id or duration_seconds for timeout_user tool.",
|
||||
})
|
||||
else:
|
||||
tool_responses.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call["id"],
|
||||
"name": tool_name,
|
||||
"content": f"Error: Unknown tool {tool_name}.",
|
||||
})
|
||||
except json.JSONDecodeError:
|
||||
tool_responses.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call["id"],
|
||||
"name": tool_name,
|
||||
"content": f"Error: Invalid JSON arguments for tool {tool_name}: {tool_args}",
|
||||
})
|
||||
except Exception as e:
|
||||
tool_responses.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call["id"],
|
||||
"name": tool_name,
|
||||
"content": f"Error executing tool {tool_name}: {e}",
|
||||
})
|
||||
|
||||
# Append tool responses and call AI again
|
||||
messages.extend(tool_responses)
|
||||
payload["messages"] = [{"role": "system", "content": system_prompt}] + messages
|
||||
async with aiohttp.ClientSession() as session_followup:
|
||||
async with session_followup.post(url, headers=headers, json=payload) as resp_followup:
|
||||
if resp_followup.status != 200:
|
||||
text = await resp_followup.text()
|
||||
raise RuntimeError(f"OpenRouter API returned error status {resp_followup.status} during tool response follow-up: {text[:500]}")
|
||||
data_followup = await resp_followup.json()
|
||||
if "choices" not in data_followup or not data_followup["choices"]:
|
||||
raise RuntimeError(f"OpenRouter API returned unexpected response format during tool response follow-up: {data_followup}")
|
||||
return data_followup["choices"][0]["message"]["content"]
|
||||
|
||||
else:
|
||||
# No tool calls, return the AI's text response
|
||||
return ai_response_message["content"]
|
||||
|
||||
return data["choices"][0]["message"]["content"]
|
||||
else:
|
||||
text = await resp.text()
|
||||
raise RuntimeError(f"OpenRouter API returned non-JSON response (status {resp.status}): {text[:500]}")
|
||||
@ -289,14 +132,6 @@ class TetoCog(commands.Cog):
|
||||
# Only keep track of actual AI interactions in memory
|
||||
if trigger:
|
||||
user_content = []
|
||||
# Include user mentions with IDs for the AI
|
||||
mentioned_users_info = []
|
||||
for mention in message.mentions:
|
||||
if isinstance(mention, discord.Member):
|
||||
mentioned_users_info.append(f"{mention.display_name} (ID: {mention.id})")
|
||||
if mentioned_users_info:
|
||||
user_content.append({"type": "text", "text": "Mentioned users: " + ", ".join(mentioned_users_info)})
|
||||
|
||||
if message.content:
|
||||
user_content.append({"type": "text", "text": message.content})
|
||||
|
||||
@ -347,16 +182,7 @@ class TetoCog(commands.Cog):
|
||||
log.info("[TETO DEBUG] Message triggered AI but contained no supported content (text, image, sticker, emoji).")
|
||||
return # Don't send empty messages to the AI
|
||||
|
||||
# Prepend user's display name to the message content
|
||||
formatted_user_content = []
|
||||
author_display_name = message.author.display_name
|
||||
for item in user_content:
|
||||
if item["type"] == "text":
|
||||
formatted_user_content.append({"type": "text", "text": f"{author_display_name}: {item['text']}"})
|
||||
else:
|
||||
formatted_user_content.append(item) # Keep other types as they are
|
||||
|
||||
convo.append({"role": "user", "content": formatted_user_content})
|
||||
convo.append({"role": "user", "content": user_content})
|
||||
|
||||
try:
|
||||
async with channel.typing():
|
||||
|
Loading…
x
Reference in New Issue
Block a user