Huanzhi (Hans) Mao
init
4d1746c
raw
history blame
12.6 kB
import random
from copy import deepcopy
from typing import Dict, List, Optional, Union
DEFAULT_STATE = {
"generated_ids": set(),
"user_count": 4,
"user_map": {
"Alice": "USR001",
"Bob": "USR002",
"Catherine": "USR003",
"Daniel": "USR004",
},
"inbox": [
{
"USR002": "My name is Alice. I want to connect.",
},
{
"USR003": "Could you upload the file?",
},
{
"USR004": "Could you upload the file?",
},
],
"message_count": 3,
"current_user": None,
}
class MessageAPI:
"""
A class representing a Message API for managing user interactions in a workspace.
This class provides methods for user management, messaging, and message retrieval
within a specific workspace. It maintains user information, sent messages, and
received messages for each user.
Attributes:
user_map (Dict[str, str]): A mapping of user names to user IDs.
inbox (Dict[int, Dict[str, Union[str, int]]]): A dictionary storing all messages.
message_count (int): The total count of messages in the workspace.
current_user (Optional[str]): The ID of the currently logged-in user.
Methods:
generate_id(): Generate a unique ID for a message.
list_users(): List all users in the workspace.
get_user_id(user: str): Get the user ID for a given username.
login(user_id: str): Log in a user.
send_message(receiver_id: str, message: str): Send a message to another user.
view_messages_sent(): View messages sent by the current user.
delete_message(receiver_id: str, message_index: int): Delete a sent message.
add_contact(name: str, user_id: str): Add a new contact to the workspace.
search_messages(keyword: str): Search for messages containing a keyword.
get_message_stats(): Get messaging statistics for the current user.
"""
def __init__(self):
"""
Initialize the MessageAPI with a workspace ID.
"""
self.generated_ids: set
self.user_count: int
self.user_map: Dict[str, str]
self.inbox: List[Dict[str, str]]
self.message_count: int
self.current_user: Optional[str]
self._api_description = "This tool belongs to the Message API, which is used to manage user interactions in a workspace."
def _load_scenario(self, scenario: dict, long_context=False) -> None:
"""
Load a scenario into the MessageAPI.
Args:
scenario (Dict): A dictionary containing message data.
"""
DEFAULT_STATE_COPY = deepcopy(DEFAULT_STATE)
self._random = random.Random((scenario.get("random_seed", 200191)))
self.generated_ids = scenario.get(
"generated_ids", DEFAULT_STATE_COPY["generated_ids"]
)
self.user_count = scenario.get("user_count", DEFAULT_STATE_COPY["user_count"])
self.user_map = scenario.get("user_map", DEFAULT_STATE_COPY["user_map"])
self.inbox = scenario.get("inbox", DEFAULT_STATE_COPY["inbox"])
self.message_count = scenario.get(
"message_count", DEFAULT_STATE_COPY["message_count"]
)
self.current_user = scenario.get("current_user", DEFAULT_STATE_COPY["current_user"])
def __eq__(self, value: object) -> bool:
if not isinstance(value, MessageAPI):
return False
for attr_name in vars(self):
if attr_name.startswith("_"):
continue
model_attr = getattr(self, attr_name)
ground_truth_attr = getattr(value, attr_name)
if model_attr != ground_truth_attr:
return False
return True
def _generate_id(self):
"""
Generate a unique ID for a message.
Returns:
new_id (int): A unique ID for a message.
"""
new_id = self._random.randint(
10000, 99999
) # first 5 mapped by initial configuration.
while new_id in self.generated_ids:
new_id = self._random.randint(10000, 99999)
self.generated_ids.add(new_id)
return {"new_id": new_id}
def list_users(self) -> Dict[str, List[str]]:
"""
List all users in the workspace.
Returns:
user_list (List[str]): List of all users in the workspace.
"""
return {"user_list": list(self.user_map.keys())}
def get_user_id(self, user: str) -> Dict[str, Optional[str]]:
"""
Get user ID from user name.
Args:
user (str): User name of the user.
Returns:
user_id (str): User ID of the user
"""
if user not in self.user_map:
return {"error": f"User '{user}' not found in the workspace."}
return {"user_id": self.user_map.get(user)}
def message_login(self, user_id: str) -> Dict[str, Union[str, bool]]:
"""
Log in a user with the given user ID to messeage application.
Args:
user_id (str): User ID of the user to log in.
Returns:
login_status (bool): True if login was successful, False otherwise.
message (str): A message describing the result of the login attempt.
"""
if user_id not in [id for id in self.user_map.values()]:
return {"login_status": False, "message": f"User ID '{user_id}' not found."}
self.current_user = user_id
return {
"login_status": True,
"message": f"User '{user_id}' logged in successfully.",
}
def message_get_login_status(self) -> Dict[str, bool]:
"""
Get the login status of the current user.
Returns:
login_status (bool): True if the current user is logged in, False otherwise.
"""
return {"login_status": bool(self.current_user)}
def send_message(self, receiver_id: str, message: str) -> Dict[str, Union[str, bool]]:
"""
Send a message to a user.
Args:
receiver_id (str): User ID of the user to send the message to.
message (str): Message to be sent.
Returns:
sent_status (bool): True if the message was sent successfully, False otherwise.
message_id (int): ID of the sent message.
message (str): A message describing the result of the send attempt.
"""
# Check if there is a current user logged in
if not self.current_user:
return {"error": "No user is currently logged in."}
# Validate receiver existence
if receiver_id not in self.user_map.values():
return {"error": f"Receiver ID '{receiver_id}' not found."}
# Generate a unique message ID
message_id = self._generate_id()
# Store the message in the inbox
self.inbox.append({receiver_id: message})
self.message_count += 1
return {
"sent_status": True,
"message_id": message_id,
"message": f"Message sent to '{receiver_id}' successfully.",
}
def delete_message(self, receiver_id: str) -> Dict[str, Union[bool, str]]:
"""
Delete the latest message sent to a receiver.
Args:
receiver_id (str): User ID of the user to send the message to.
message_id (int): ID of the message to be deleted.
Returns:
deleted_status (bool): True if the message was deleted successfully, False otherwise.
message_id (int): ID of the deleted message.
message (str): A message describing the result of the deletion attempt.
"""
if not self.current_user:
return {"error": "No user is currently logged in."}
# Loop through the inbox in reverse order to find the first message sent to the receiver
for message in self.inbox[::-1]:
receiver, _ = list(message.items())[0]
if receiver == receiver_id:
self.inbox.remove(message)
return {
"deleted_status": True,
"message_id": receiver,
"message": f"Receiver {receiver_id}'s first message deleted successfully.",
}
return {"error": f"Receiver ID {receiver_id} not found."}
def view_messages_sent(self) -> Dict[str, Union[Dict[str, List[str]], str]]:
"""
View all historical messages sent by the current user.
Returns:
messages (Dict): Dictionary of messages grouped by receiver An example of the messages dictionary is {"USR001":["Hello"],"USR002":["World"]}.
"""
if not self.current_user:
return {"error": "No user is currently logged in."}
# Dictionary to collect messages grouped by receiver
sent_messages = {}
# Loop through the inbox and collect messages sent by the current user
for message in self.inbox:
receiver, message_content = list(message.items())[0]
if receiver not in sent_messages:
sent_messages[receiver] = [message_content]
else:
sent_messages[receiver].append(message_content)
return {"messages": sent_messages}
def add_contact(self, user_name: str) -> Dict[str, Union[bool, str]]:
"""
Add a contact to the workspace.
Args:
user_name (str): User name of contact to be added.
Returns:
added_status (bool): True if the contact was added successfully, False otherwise.
user_id (str): User ID of the added contact.
message (str): A message describing the result of the addition attempt.
"""
if user_name in self.user_map:
return {"error": f"User name '{user_name}' already exists."}
self.user_count += 1
user_id = f"USR{str(self.user_count).zfill(3)}"
if user_id in self.user_map.values():
return {"error": f"User ID '{user_id}' already exists."}
self.user_map[user_name] = user_id
return {
"added_status": True,
"user_id": user_id,
"message": f"Contact '{user_name}' added successfully.",
}
def search_messages(
self, keyword: str
) -> Dict[str, Union[List[Dict[str, Union[str, List[str]]]], str]]:
"""
Search for messages containing a specific keyword.
Args:
keyword (str): The keyword to search for in messages.
Returns:
results (List[Dict]): List of dictionaries containing matching messages.
- receiver_id (str): User ID of the receiver of the message.
- message (str): The message containing the keyword.
"""
if not self.current_user:
return {"error": "No user is currently logged in."}
keyword_lower = keyword.lower()
results = []
# Iterate through the inbox to search for the keyword in messages
# for message_id, message_data in self.inbox.items():
for message_data in self.inbox:
receiver_id, message_content = list(message_data.items())[0]
if keyword_lower in message_content.lower():
results.append(
{
"receiver_id": receiver_id,
"message": message_content,
}
)
return {"results": results}
def get_message_stats(self) -> Dict[str, Union[Dict[str, int], str]]:
"""
Get statistics about messages for the current user.
Returns:
stats (Dict): Dictionary containing message statistics.
- received_count (int): Number of messages received by the current user.
- total_contacts (int): Total number of contacts the user has interacted with.
"""
if not self.current_user:
return {"error": "No user is currently logged in."}
sent_count = 0
received_count = 0
contacts = set()
# Loop through the inbox to calculate stats
for message_data in self.inbox:
receiver_id, message_content = list(message_data.items())[0]
received_count += 1
contacts.add(receiver_id)
total_contacts = len(contacts)
return {
"stats": {
"received_count": received_count,
"total_contacts": total_contacts,
}
}