Skip to content
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ pids
*.seed
*.pid.lock

# Ignore Python cache directories
__pycache__/

# Ignore compiled Python files
*.pyc

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

Expand Down Expand Up @@ -44,6 +50,8 @@ jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
backend/env/
.venv

# TypeScript cache
*.tsbuildinfo
Expand Down
7 changes: 7 additions & 0 deletions backend/crud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import mongoConnect as mc

if __name__ == "__main__":
uri = "mongodb+srv://wangyukun721:[email protected]/?retryWrites=true&w=majority&appName=Cluster0"

with mc.connect_to_mongoDB(uri) as client:
mc.upload(r'C:\Users\81548\OneDrive\文档\GitHub\Team-JSSH-HTV9\backend\test.txt', client)
150 changes: 150 additions & 0 deletions backend/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import os
from fastapi import FastAPI
# import autogen
import logging
from autogen import AssistantAgent, UserProxyAgent, GroupChat, GroupChatManager
from mongoConnect import router


app = FastAPI()
app.include_router(router)


# logging.basicConfig(level=logging.INFO)
# logger = logging.getLogger(__name__)
os.environ["OPENAI_API_KEY"] = ""

default_name_list = ["Critical Analyst", "The Problem-Solving Specialist", "The Creative Writer"]
default_system_prompt = [
"You are a critical analyst with expertise in breaking down complex ideas. When given a topic, your role is to dissect arguments, present pros and cons, and offer a balanced perspective. Stay logical, precise, and thorough in your evaluations.",
"You are an expert in problem-solving. Your goal is to help users find effective solutions to challenges they present. Focus on identifying key issues, providing clear steps, and considering practical constraints to offer actionable advice.",
"You are a creative writer specializing in storytelling. Your task is to generate imaginative narratives or metaphors based on any topic or question presented. Use vivid descriptions, evoke emotions, and bring ideas to life with creativity."
]

config_list = [{
"model": "gpt-4",
"api_key": os.environ["OPENAI_API_KEY"]
}]

llm_config_openai = {
"config_list": config_list,
"temperature": 0
}

input = {
"agents": [
{
"name": "Coder",
"system_prompt": "You are a coder."
},
{
"name": "Product_manager",
"system_prompt": "Creative in software product ideas."
},
{
"name": "security",
"system_prompt": "You act as a proxy for the user, forwarding their requests to the system and managing responses."
}
]
}

def create_assistant_agent(name=default_name_list[1], system_message=default_system_prompt[1]):
assistant = AssistantAgent(
name=name,
llm_config=llm_config_openai,
system_message=system_message
)
return assistant


# Function to create a UserProxyAgent
def create_user_proxy_agent(name=default_name_list[2], system_message=default_system_prompt[2]):
system_message += """Reply TERMINATE if the task has been solved at full satisfaction.
Otherwise, reply CONTINUE, or the reason why the task is not solved yet."""
user_proxy = UserProxyAgent(
name=name,
human_input_mode="NEVER",
is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),
code_execution_config={"work_dir": "web", "use_docker": False},
llm_config=llm_config_openai,
system_message=system_message
)
return user_proxy


# Define a POST endpoint to receive the agent definitions
@app.post("/agents/")
async def receive_agents(agents_request: dict):

agents = agents_request["agents"]

task = agents_request["prompt"]

created_agents = []

user_proxy = ""

for agent in agents:
if agent["name"].lower() == "security":
# Create an assistant agent
user_proxy = create_user_proxy_agent(name=agent["name"],
system_message=agent["system_prompt"])
# print(agent["name"])
# print(agent["system_prompt"])
# created_agents.append(user_proxy)
elif agent["name"].lower() != "security":
# Create a user proxy agent
created_agent = create_assistant_agent(name=agent["name"],
system_message=agent["system_prompt"])
# print(agent["name"])
# print(agent["system_prompt"])
created_agents.append(created_agent)
else:
return {"error": "Unknown agent type"}

# logger.info("Created agents: %s", created_agents)

# return {"message": "Agents created successfully", "agents": "created_agents", "user_proxy": "user_proxy"}
# return {"message": "Agents created successfully", "agents": agents}
groupchat = GroupChat(
agents=created_agents,
messages=[],
max_round=20,
speaker_selection_method='round_robin'
)

manager = GroupChatManager(groupchat=groupchat, llm_config=llm_config_openai)

result = user_proxy.initiate_chat(
manager,
message=task
)
result_text = groupchat.messages
# chat_history_list = str(result_text)
chat_history_list = result_text
# chat_history_list = [{'content': '\nTell me about the meaning of life\n', 'role': 'user', 'name': 'security'}, {'content': "I'm here to assist with coding-related questions. If you have any coding tasks or questions, feel free to ask!", 'role': 'user', 'name': 'Coder'}, {'content': 'How about a software product that helps users track and manage their digital footprint and online security? It could provide insights into what personal information is available online, offer suggestions for improving privacy settings, and alert users to potential security risks. Users could also receive tips on how to enhance their online security practices. What do you think?', 'role': 'user', 'name': 'Product_manager'}, {'content': "That sounds like a valuable and relevant software product idea! It addresses a growing concern for many users about their online privacy and security. Implementing features like tracking personal information online, providing privacy setting suggestions, and offering security risk alerts can be very beneficial. Additionally, providing tips to enhance online security practices can help users better protect themselves. It's important to consider user-friendly interfaces and clear communication of the benefits to attract and retain users. If you need help with the technical aspects or development of this product, feel free to ask!", 'role': 'user', 'name': 'Coder'}, {'content': "Great to hear that you find the software product idea valuable! If you have any specific technical questions or need assistance with the development of this product, feel free to ask. I'm here to help with any coding-related tasks or challenges you may encounter along the way.", 'role': 'user', 'name': 'Product_manager'}, {'content': 'TERMINATE', 'role': 'user', 'name': 'Coder'}]

names = []
for item in chat_history_list:
names.append(item['name'])

json_data = {}
round = 1
name_have_seen = []
json_data[f"round-{round}"] = {}
# begin with "round" + round to combine to a string
for i in range(len(chat_history_list)):
if not chat_history_list[i]['name'] in name_have_seen:
name_have_seen.append(chat_history_list[i]['name'])
json_data[f"round-{round}"][chat_history_list[i]['name']] = chat_history_list[i]['content']
else:
name_have_seen = []
round += 1
json_data[f"round-{round}"] = {}

return {"conversation_summary": json_data}


if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
132 changes: 132 additions & 0 deletions backend/mongoConnect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import pprint
import ast
from fastapi import APIRouter

from pymongo import MongoClient
import pymongo
from bson.objectid import ObjectId
from pydantic import BaseModel

class MeetingRecord(BaseModel):
name: str
role: str
content: str

router = APIRouter()


def connect_to_mongoDB(uri):
try:
client = MongoClient(uri, server_api=pymongo.server_api.ServerApi(
version="1", strict=True, deprecation_errors=True))
# end example code here
client.admin.command("ping")
print("Connected successfully")
return client

except Exception as e:
raise Exception(
"The following error occurred: ", e)
def read_and_parse_file(file_path):
"""
Safely reads a string from a text file and converts it into a list of dictionaries.

:param file_path: The path to the text file containing the string representation of a list of dictionaries.
:return: A list of dictionaries if parsing is successful, otherwise None.
"""
try:
# Step 1: Read the file content
with open(file_path, 'r', encoding='utf-8') as file:
file_content = file.read()

# Step 2: Safely parse the content using ast.literal_eval
data = ast.literal_eval(file_content)

# Ensure that the parsed data is indeed a list of dictionaries
if isinstance(data, list) and all(isinstance(item, dict) for item in data):
return data
else:
raise ValueError("Parsed content is not a list of dictionaries.")

except (SyntaxError, ValueError, IOError) as e:
print(f"An error occurred while reading or parsing the file: {e}")
return None

def upload_txt (fp, client):
db = client.history
history_collection = db.singleton
content = read_and_parse_file(fp)
for dictionary in content:
db.singleton.insert_one(dictionary)
print("upload success")

def upload_json(jsonFile, client):
db = client.history
history_collection = db.singleton
for dictionary in jsonFile:
db.singleton.insert_one(dictionary)
print("upload success")

def format_meeting_records(documents):
"""
Converts a list of MongoDB documents into a human-readable string format,
separating each meeting by the 'TERMINATE' marker and formatting each speaker's content.

:param documents: List of dictionaries containing 'content', 'role', and 'name'.
:return: A string that organizes the content into separate meetings, formatted for readability.
"""
meetings = []
current_meeting = []

for document in documents:
content = document['content'].strip()
role = document['role']
name = document['name']

# If the document's content is 'TERMINATE', finalize the current meeting and start a new one
if content == 'TERMINATE':
meetings.append('\n'.join(current_meeting)) # Finalize the current meeting
current_meeting = [] # Reset for the next meeting
else:
# Format each speaker's contribution
formatted_entry = f"{name} ({role}):\n{content}\n"
current_meeting.append(formatted_entry)

# If there's leftover content after the last 'TERMINATE', finalize it
if current_meeting:
meetings.append('\n'.join(current_meeting))

# Combine all meetings with a separator between them
formatted_output = "\n\n=== New Meeting ===\n\n".join(meetings)

return formatted_output

@router.get("/read_history/")
async def download_from_db(client = None): # Dependency injection
"""
Downloads the entire meeting history from MongoDB and returns it as a formatted string.
"""

if client is None:
# Connect to MongoDB if client is not provided through dependency injection
client = connect_to_mongoDB(uri="mongodb+srv://wangyukun721:@cluster0.ld92j.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0")
db = client.history
history_collection = db.singleton
result = history_collection.find({}, {"content": 1, "role": 1, "name": 1, "_id": 0}) # Project relevant fields
meetings = format_meeting_records(result)
# Close the connection if not using dependency injection
if client is not None:
client.close()

return meetings


if __name__ == "__main__":
uri = "mongodb+srv://wangyukun721:@cluster0.ld92j.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0"

# with connect_to_mongoDB(uri) as client:
# meetings = download_from_db(client)
# print(meetings)
# client.close()


1 change: 1 addition & 0 deletions backend/test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{'content': '\nwrite a code to comput the factorial of a numbers\n', 'role': 'assistant', 'name': 'user_proxy'}, {'content': 'Sure, here is a Python code to compute the factorial of a number:\n\n```python\ndef factorial(n):\n if n == 0:\n return 1\n else:\n return n * factorial(n-1)\n\nnumber = 5\nresult = factorial(number)\nprint(f"The factorial of {number} is {result}")\n```\n\nThis code defines a recursive function `factorial` that calculates the factorial of a given number `n`. It then calculates the factorial of 5 and prints the result.', 'name': 'Sam', 'role': 'user'}, {'content': 'The code provided by Sam looks correct. It defines a recursive function to calculate the factorial of a number and then calculates the factorial of 5. The code should work as expected.\n\nDo you need any further assistance with this code?', 'name': 'John', 'role': 'user'}, {'content': 'exitcode: 0 (execution succeeded)\nCode output: \nThe factorial of 5 is 120\n', 'role': 'assistant', 'name': 'user_proxy'}, {'content': "Great! I'm glad the code worked as expected. If you have any more questions or need further assistance in the future, feel free to ask.", 'name': 'Sam', 'role': 'user'}, {'content': "I'm glad to hear that the code worked correctly. If you have any more questions or need assistance in the future, feel free to reach out. Have a great day!", 'name': 'John', 'role': 'user'}, {'content': 'TERMINATE', 'role': 'assistant', 'name': 'user_proxy'}]
Loading