mirror of
https://github.com/SkalaraAI/management-llm.git
synced 2025-04-09 15:00:19 -04:00
added model & matching algo to flask server
This commit is contained in:
parent
6a4c034f10
commit
403a489176
|
@ -3,7 +3,8 @@ import pandas as pd
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import os
|
import os
|
||||||
import openai
|
import openai
|
||||||
|
import joblib
|
||||||
|
import random
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
openai.api_key = os.getenv("OPENAI_API_KEY")
|
openai.api_key = os.getenv("OPENAI_API_KEY")
|
||||||
|
@ -12,67 +13,116 @@ openai.api_key = os.getenv("OPENAI_API_KEY")
|
||||||
tasks_data = {}
|
tasks_data = {}
|
||||||
users_data = {}
|
users_data = {}
|
||||||
|
|
||||||
def generate_prompt(task_form):
|
# Loads the SVM model, vectorizer, and encoder
|
||||||
base_text = "You are a software engineer at a software development company. Your job is to assign tags to tasks based on the software/tools used. Please generate one-word tags representing software/tools/libraries commonly used by developers to build or complete the following task."
|
model_filename = "svm_model.sav"
|
||||||
return base_text + "TASK: " + task_form
|
svm_model = joblib.load(model_filename)
|
||||||
|
|
||||||
|
vectorizer_filename = 'fitted_vectorizer.joblib'
|
||||||
|
word_vectorizer = joblib.load(vectorizer_filename)
|
||||||
|
|
||||||
|
encoder_filename = 'fitted_encoder.joblib'
|
||||||
|
encoder = joblib.load(encoder_filename)
|
||||||
|
|
||||||
def generate_technical_tags(task_form):
|
def generate_technical_tags(task_form):
|
||||||
prompt = generate_prompt(task_form)
|
# Vectorize
|
||||||
|
vectorized_text = word_vectorizer.transform([task_form])
|
||||||
response = openai.Completion.create(
|
decision_function_scores = svm_model.decision_function(vectorized_text)
|
||||||
model="text-davinci-003",
|
|
||||||
prompt=prompt,
|
|
||||||
temperature=0,
|
|
||||||
max_tokens=100,
|
|
||||||
stop=["TASK:"]
|
|
||||||
)
|
|
||||||
|
|
||||||
tags = response.choices[0].text.strip().split("\n")
|
# Get the top 3 predicted labels based on highest decision function scores
|
||||||
|
top_4_indices = decision_function_scores.argsort()[0][-3:][::-1]
|
||||||
|
top_4_labels = encoder.inverse_transform(top_4_indices)
|
||||||
|
|
||||||
|
tags = top_4_labels.tolist()
|
||||||
return tags
|
return tags
|
||||||
|
|
||||||
|
def match_tasks_to_users(tasks, users, user_max_tasks):
|
||||||
|
task_ids = list(tasks.keys())
|
||||||
|
|
||||||
|
# Create a dictionary to store the matched tasks and users
|
||||||
|
task_to_user_matches = {}
|
||||||
|
user_to_task_matches = {user_id: None for user_id in users}
|
||||||
|
|
||||||
|
# Helper function to calculate the preference score between a task and a user
|
||||||
|
def calculate_preference(task_id, user_id):
|
||||||
|
task_tags = set(tasks[task_id]['tags'])
|
||||||
|
user_strengths = set(users[user_id]['strengths'])
|
||||||
|
user_current_tasks = users[user_id]['current_tasks']
|
||||||
|
|
||||||
|
# Calculate the preference score based on matching tags and strengths
|
||||||
|
tag_score = len(task_tags.intersection(user_strengths))
|
||||||
|
|
||||||
|
# Calculate the total preference score, considering currentTasks as a tiebreaker
|
||||||
|
preference_score = tag_score - user_current_tasks * 0.1
|
||||||
|
|
||||||
|
# Makes the preference score negative if the user is already at max tasks
|
||||||
|
if user_current_tasks == user_max_tasks:
|
||||||
|
preference_score -= user_max_tasks
|
||||||
|
|
||||||
|
return preference_score
|
||||||
|
|
||||||
|
# Assign tasks to users based on preferences
|
||||||
|
for task_id in task_ids:
|
||||||
|
task_info = tasks[task_id]
|
||||||
|
|
||||||
|
# Sort the users based on their preference for this task
|
||||||
|
sorted_users = sorted(users.keys(), key=lambda user_id: calculate_preference(task_id, user_id), reverse=True)
|
||||||
|
# Assign the task to the first user in the sorted list who is not already matched
|
||||||
|
for user_id in sorted_users:
|
||||||
|
if user_to_task_matches[user_id] is None:
|
||||||
|
task_to_user_matches[task_id] = user_id
|
||||||
|
user_to_task_matches[user_id] = task_id
|
||||||
|
break
|
||||||
|
print(task_to_user_matches)
|
||||||
|
return task_to_user_matches
|
||||||
|
|
||||||
@app.route('/label_tasks', methods=['POST'])
|
@app.route('/label_tasks', methods=['POST'])
|
||||||
def get_task_tags():
|
def get_task_tags():
|
||||||
# try:
|
|
||||||
data = request.get_json()
|
|
||||||
tasks = data[0]['tasks']
|
|
||||||
result = {}
|
|
||||||
for task, task_description in tasks.items():
|
|
||||||
task_id = task_description["id"]
|
|
||||||
task_content = task_description["content"]
|
|
||||||
task_complexity = task_description["complexityScore"]
|
|
||||||
|
|
||||||
tags = generate_technical_tags(task_content) # where the function that gets the tags is placed
|
|
||||||
result[task_id] = tags
|
|
||||||
return jsonify(result)
|
|
||||||
# except Exception as e:
|
|
||||||
# return jsonify({"error": str(e)}), 500
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/assign_tasks', methods=['POST'])
|
|
||||||
def assign_tasks_to_users():
|
|
||||||
try:
|
try:
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
tasks = data[0]['tasks']
|
tasks = data[0]['tasks']
|
||||||
users = data[0]['users']
|
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
tasks_dict = {}
|
|
||||||
users_dict = {}
|
|
||||||
|
|
||||||
for task, task_description in tasks.items():
|
for task, task_description in tasks.items():
|
||||||
tasks_dict[task_description["id"]] = {"tags" : task_description["content"], "complexity" : task_description["complexityScore"]}
|
task_id = task_description["id"]
|
||||||
# tasks_dict[task_description["id"]] = {"tags" : generate_technical_tags(task_description["content"]), "complexity" : task_description["complexityScore"]}
|
task_content = task_description["content"]
|
||||||
|
task_complexity = task_description["complexityScore"]
|
||||||
for user, user_description in users.items():
|
|
||||||
users_dict[user_description["id"]] = {"strengths" : user_description["strengths"], "current_tasks" : user_description["currentTasks"]}
|
tags = generate_technical_tags(task_content) # where the function that gets the tags is placed
|
||||||
|
result[task_id] = tags
|
||||||
|
return jsonify(result)
|
||||||
|
|
||||||
# return jsonify(result)
|
|
||||||
return result
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({"error": str(e)}), 500
|
return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/assign_tasks', methods=['POST'])
|
||||||
|
def assign_tasks_to_users():
|
||||||
|
# try:
|
||||||
|
data = request.get_json()
|
||||||
|
tasks = data[0]['tasks']
|
||||||
|
users = data[0]['users']
|
||||||
|
result = {}
|
||||||
|
|
||||||
|
tasks_dict = {}
|
||||||
|
users_dict = {}
|
||||||
|
|
||||||
|
for task, task_description in tasks.items():
|
||||||
|
tasks_dict[task_description["id"]] = {"tags" : generate_technical_tags(task_description["content"]), "complexity" : task_description["complexityScore"]}
|
||||||
|
|
||||||
|
for user, user_description in users.items():
|
||||||
|
users_dict[user_description["id"]] = {"strengths" : user_description["strengths"], "current_tasks" : user_description["currentTasks"]}
|
||||||
|
|
||||||
|
|
||||||
|
matching = match_tasks_to_users(tasks_dict, users_dict, 3)
|
||||||
|
# result = {}
|
||||||
|
# for task, task_description in tasks.items():
|
||||||
|
# result[task_description["content"]] = {"assignedTo" : matchings[task_description["id"]]}
|
||||||
|
|
||||||
|
# print(result)
|
||||||
|
result = matching
|
||||||
|
return jsonify(result)
|
||||||
|
# return result
|
||||||
|
# except Exception as e:
|
||||||
|
# return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(debug=True)
|
app.run(debug=True)
|
||||||
|
|
BIN
task-server/fitted_encoder.joblib
Normal file
BIN
task-server/fitted_encoder.joblib
Normal file
Binary file not shown.
BIN
task-server/fitted_vectorizer.joblib
Normal file
BIN
task-server/fitted_vectorizer.joblib
Normal file
Binary file not shown.
28
task-server/model_integration_testing.py
Normal file
28
task-server/model_integration_testing.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import joblib
|
||||||
|
|
||||||
|
# To be translated
|
||||||
|
sample_text = "Implement a login page with form validation using React.js."
|
||||||
|
|
||||||
|
# Loads the model, vectorizer, and encoder
|
||||||
|
model_filename = "svm_model.sav"
|
||||||
|
svm_model = joblib.load(model_filename)
|
||||||
|
|
||||||
|
vectorizer_filename = 'fitted_vectorizer.joblib'
|
||||||
|
word_vectorizer = joblib.load(vectorizer_filename)
|
||||||
|
|
||||||
|
encoder_filename = 'fitted_encoder.joblib'
|
||||||
|
encoder = joblib.load(encoder_filename)
|
||||||
|
|
||||||
|
# Vectorize
|
||||||
|
vectorized_text = word_vectorizer.transform([sample_text])
|
||||||
|
|
||||||
|
binary_predictions = svm_model.predict(vectorized_text)
|
||||||
|
|
||||||
|
decision_function_scores = svm_model.decision_function(vectorized_text)
|
||||||
|
|
||||||
|
# Get the top 3 predicted labels based on highest decision function scores
|
||||||
|
top_4_indices = decision_function_scores.argsort()[0][-3:][::-1]
|
||||||
|
|
||||||
|
top_4_labels = encoder.inverse_transform(top_4_indices)
|
||||||
|
|
||||||
|
print("Top 3 predicted labels:", top_4_labels)
|
BIN
task-server/svm_model.sav
Normal file
BIN
task-server/svm_model.sav
Normal file
Binary file not shown.
|
@ -79,81 +79,82 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"users" : {
|
"users" : {
|
||||||
"1" : {
|
"1": {
|
||||||
"id": "1",
|
"id": "1",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["Objective-C", "Java", "Elasticsearch"]
|
||||||
},
|
},
|
||||||
"2" : {
|
"2": {
|
||||||
"id": "2",
|
"id": "2",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["SQL", "TypeScript", "jQuery"]
|
||||||
},
|
},
|
||||||
"3" : {
|
"3": {
|
||||||
"id": "3",
|
"id": "3",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["Java", "Bootstrap", "jQuery"]
|
||||||
},
|
},
|
||||||
"4" : {
|
"4": {
|
||||||
"id": "4",
|
"id": "4",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["HTML/CSS", "Adobe Creative Suite", "C++"]
|
||||||
},
|
},
|
||||||
"5" : {
|
"5": {
|
||||||
"id": "5",
|
"id": "5",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["SQL", "PostgreSQL", "Java"]
|
||||||
},
|
},
|
||||||
"6" : {
|
"6": {
|
||||||
"id": "6",
|
"id": "6",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["ReactJS", "JavaScript", "Bootstrap"]
|
||||||
},
|
},
|
||||||
"7" : {
|
"7": {
|
||||||
"id": "7",
|
"id": "7",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["Ruby", "ReactJS", "Firebase"]
|
||||||
},
|
},
|
||||||
"8" : {
|
"8": {
|
||||||
"id": "8",
|
"id": "8",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["Node.js", "JavaScript", "RESTful APIs"]
|
||||||
},
|
},
|
||||||
"9" : {
|
"9": {
|
||||||
"id": "9",
|
"id": "9",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["HTML/CSS", "jQuery", "Go"]
|
||||||
},
|
},
|
||||||
"10" : {
|
"10": {
|
||||||
"id": "10",
|
"id": "10",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["JavaScript", "ReactJS", "C++"]
|
||||||
},
|
},
|
||||||
"11" : {
|
"11": {
|
||||||
"id": "11",
|
"id": "11",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": [".NET", "API Integration", "PHP"]
|
||||||
},
|
},
|
||||||
"12" : {
|
"12": {
|
||||||
"id": "12",
|
"id": "12",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["SQL", "MongoDB", "Azure"]
|
||||||
},
|
},
|
||||||
"13" : {
|
"13": {
|
||||||
"id": "13",
|
"id": "13",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["API Integration", "RESTful APIs", "Linux/Unix"]
|
||||||
},
|
},
|
||||||
"14" : {
|
"14": {
|
||||||
"id": "14",
|
"id": "14",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["Ruby", "ReactJS", "C++"]
|
||||||
},
|
},
|
||||||
"15" : {
|
"15": {
|
||||||
"id": "15",
|
"id": "15",
|
||||||
"currentTasks": 0,
|
"currentTasks": 0,
|
||||||
"strengths" : []
|
"strengths": ["JavaScript", "ReactJS", "Bootstrap"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
]
|
]
|
Loading…
Reference in New Issue
Block a user