updated sops apis and questions generator
This commit is contained in:
@@ -5,6 +5,7 @@ from src.services.chatbot import Chatbot
|
||||
from src.utils.utils import delete_all_files_in_directory
|
||||
from src.utils.document_loader import load_document
|
||||
from src.services.chatbot import Chatbot
|
||||
from src.utils.auth import auth_check
|
||||
|
||||
|
||||
# Initialize the Blueprint
|
||||
@@ -18,6 +19,7 @@ def allowed_file(filename):
|
||||
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||
|
||||
@bot.route('/validate_worker_document', methods=['POST'])
|
||||
@auth_check
|
||||
def validate_worker_document():
|
||||
try:
|
||||
# Retrieve form data
|
||||
@@ -63,6 +65,7 @@ def validate_worker_document():
|
||||
|
||||
|
||||
@bot.route('/predict_next_n_assessments', methods=['POST'])
|
||||
@auth_check
|
||||
def predict_next_n_assessments():
|
||||
try:
|
||||
# Retrieve JSON data from the request
|
||||
@@ -94,6 +97,7 @@ def predict_next_n_assessments():
|
||||
|
||||
|
||||
@bot.route('/use_bot_predict_assessments', methods=['POST'])
|
||||
@auth_check
|
||||
def use_bot_predict_assessments():
|
||||
try:
|
||||
# Retrieve JSON data from the request
|
||||
@@ -124,6 +128,7 @@ def use_bot_predict_assessments():
|
||||
|
||||
|
||||
@bot.route('/suggest_assessment_frequencies', methods=['POST'])
|
||||
@auth_check
|
||||
def use_bot_suggest_frequencies():
|
||||
try:
|
||||
# Retrieve JSON data from the request
|
||||
@@ -155,6 +160,7 @@ def use_bot_suggest_frequencies():
|
||||
|
||||
|
||||
@bot.route('/predict_goal_achievment_proba', methods=['POST'])
|
||||
@auth_check
|
||||
def predict_goal_achievement():
|
||||
try:
|
||||
# Retrieve JSON data from the request
|
||||
|
||||
@@ -9,6 +9,7 @@ from src.services.questions_generator import QuestionsGenerator
|
||||
from src.utils.utils import delete_all_files_in_directory
|
||||
from src.utils.document_loader import load_document
|
||||
import json
|
||||
from src.utils.auth import auth_check
|
||||
# Initialize the Blueprint
|
||||
qs_b = Blueprint('questions', __name__)
|
||||
|
||||
@@ -22,7 +23,9 @@ def allowed_file(filename):
|
||||
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||
|
||||
|
||||
|
||||
@qs_b.route('/generate_questions_from_sop', methods=['POST'])
|
||||
@auth_check
|
||||
def generate_questions_from_sop():
|
||||
# Check if the request contains data
|
||||
if not request.is_json:
|
||||
|
||||
+15
-3
@@ -3,6 +3,7 @@ from flask import Blueprint, request, jsonify, current_app
|
||||
from werkzeug.utils import secure_filename
|
||||
from src.services.sop_generator import (SopPersonalAssessment,SopGeneratorExecutive)
|
||||
from src.services.sop_document_parser import DocumentParser
|
||||
from src.utils.auth import auth_check
|
||||
|
||||
from src.utils.utils import delete_all_files_in_directory
|
||||
from src.utils.document_loader import load_document
|
||||
@@ -20,6 +21,7 @@ def allowed_file(filename):
|
||||
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||
|
||||
@sops_bp.route('/personal_assessment/get_roles_from_doc', methods=['POST'])
|
||||
@auth_check
|
||||
def get_roles():
|
||||
# Check if the post request has the file part
|
||||
if 'document' not in request.files:
|
||||
@@ -63,6 +65,7 @@ def get_roles():
|
||||
|
||||
|
||||
@sops_bp.route('/personal_assessment/get_roles_from_questionnaire', methods=['POST'])
|
||||
@auth_check
|
||||
def get_roles_questionnaire():
|
||||
# Check if the post request has the file part
|
||||
questionnaire_data = request.json
|
||||
@@ -87,6 +90,7 @@ def get_roles_questionnaire():
|
||||
|
||||
|
||||
@sops_bp.route('/personal_assessment/generate_sops_from_doc', methods=['POST'])
|
||||
@auth_check
|
||||
def generate_sops():
|
||||
# Check if the POST request has the file part
|
||||
if 'document' not in request.files:
|
||||
@@ -143,6 +147,7 @@ def generate_sops():
|
||||
|
||||
|
||||
@sops_bp.route('/personal_assessment/generate_sops_from_questionnaire', methods=['POST'])
|
||||
@auth_check
|
||||
def generate_sops_from_questionnaire_per():
|
||||
"""
|
||||
Generate SOPs based on the questionnaire data provided in the request body.
|
||||
@@ -184,6 +189,7 @@ def generate_sops_from_questionnaire_per():
|
||||
|
||||
|
||||
@sops_bp.route('/personal_assessment/generate_sops_by_roles_and_areas', methods=['POST'])
|
||||
@auth_check
|
||||
def generate_sops_by_roles_and_areas():
|
||||
"""
|
||||
Generate SOPs based on the roles, SOP types (will, shall, must), and areas provided in the request body.
|
||||
@@ -216,6 +222,7 @@ def generate_sops_by_roles_and_areas():
|
||||
|
||||
|
||||
@sops_bp.route('/executive/generate_sop_mission_from_vision', methods=['POST'])
|
||||
@auth_check
|
||||
def generate_executive_sops_from_doc():
|
||||
"""
|
||||
Generate SOPs for executives based on a document containing vision and mission.
|
||||
@@ -292,6 +299,7 @@ def generate_executive_sops_from_doc():
|
||||
|
||||
|
||||
@sops_bp.route('/executive/generate_sop_managers_doc', methods=['POST'])
|
||||
@auth_check
|
||||
def generate_sop_managers_doc():
|
||||
if 'document' not in request.files:
|
||||
return jsonify({"error": "No file part", "message": "Please upload a file with the key 'document'."}), 400
|
||||
@@ -312,18 +320,18 @@ def generate_sop_managers_doc():
|
||||
docs = load_document(file_path)
|
||||
|
||||
# Load department managers from form data as a JSON string
|
||||
department_managers_json = request.form.get('department_managers', '[]')
|
||||
department_managers_json = request.form.get('departments_managers', '[]')
|
||||
department_managers = json.loads(department_managers_json)
|
||||
|
||||
sop_generator = DocumentParser()
|
||||
result = sop_generator.extract_sops_for_managers_by_department(docs, department_managers)
|
||||
result = sop_generator.extract_sops_for_workers_by_department(docs, department_managers)
|
||||
|
||||
delete_all_files_in_directory(upload_folder)
|
||||
|
||||
if not result:
|
||||
return jsonify({"error": "Processing error", "message": "Failed to generate SOPs for department managers."}), 500
|
||||
|
||||
return jsonify({"sops": result.dict(), "message": "SOPs successfully generated for department managers."}), 200
|
||||
return jsonify({"sops": result, "message": "SOPs successfully generated for department managers."}), 200
|
||||
|
||||
except Exception as e:
|
||||
delete_all_files_in_directory(upload_folder)
|
||||
@@ -334,6 +342,7 @@ def generate_sop_managers_doc():
|
||||
|
||||
|
||||
@sops_bp.route('/executive/generate_sops_from_questionnaire', methods=['POST'])
|
||||
@auth_check
|
||||
def generate_sops_from_questionnaire():
|
||||
try:
|
||||
data = request.json
|
||||
@@ -366,6 +375,7 @@ def generate_sops_from_questionnaire():
|
||||
|
||||
|
||||
@sops_bp.route('/executive/get_roles_for_reference_managers', methods=['POST'])
|
||||
@auth_check
|
||||
def get_roles_for_reference_managers():
|
||||
try:
|
||||
# Retrieve form data
|
||||
@@ -409,6 +419,7 @@ def get_roles_for_reference_managers():
|
||||
|
||||
|
||||
@sops_bp.route('/manager/get_roles_for_reference_workers', methods=['POST'])
|
||||
@auth_check
|
||||
def get_roles_for_reference_workers():
|
||||
try:
|
||||
# Retrieve form data
|
||||
@@ -450,6 +461,7 @@ def get_roles_for_reference_workers():
|
||||
|
||||
|
||||
@sops_bp.route('/manager/generate_sop_workers_doc', methods=['POST'])
|
||||
@auth_check
|
||||
def generate_sop_workers_doc():
|
||||
try:
|
||||
# Check if the document is provided
|
||||
|
||||
@@ -12,7 +12,7 @@ def get_questions_prompt():
|
||||
Input:
|
||||
assessment type: (e.g., daily, weekly, biweekly)
|
||||
frequency type: (e.g., daily, weekly, biweekly)
|
||||
frequency number: (e.g., day 3, week 2, biweekly 1)
|
||||
frequency number(the current week or frequency e.g if assessment is weekly and frequcny number is 2 , it means week 2): (e.g., day 3, week 2, biweekly 1)
|
||||
total duration: (e.g., 6 weeks, 12 days)
|
||||
SOPs of the assessment:
|
||||
roles_data e.g [{"position""test position","mame":"name of staff"}]
|
||||
@@ -23,6 +23,7 @@ def get_questions_prompt():
|
||||
2. Regardless of the assement type, always use 1,2,3 for the frequency numbering, nothing else
|
||||
3. All questions are "yes" or "no" questions nothing extra and precise ,not long
|
||||
4. Generate a total of at least 20 questions all rounda based on the sops and roles for each frequency number
|
||||
5. make sure the questions are up to 20 for the current frequency
|
||||
Example response:
|
||||
|
||||
questions
|
||||
@@ -36,7 +37,8 @@ def get_questions_prompt():
|
||||
"assigned_to": "name",
|
||||
"role": "person role",
|
||||
"question": "e.g., Is the internal project team being followed according to the SOP?"
|
||||
"area_tag":"timeline"
|
||||
"area_tag":"timeline",
|
||||
"postion":"person position"
|
||||
}
|
||||
] ## up to at least 20 questions
|
||||
},
|
||||
@@ -48,7 +50,8 @@ def get_questions_prompt():
|
||||
"assigned_to": "name",
|
||||
"role": "person role",
|
||||
"question": "e.g., Have communication protocols been followed for the task at hand?".
|
||||
"area_tag":"communication"
|
||||
"area_tag":"communication",
|
||||
"position":"person position"
|
||||
} ## up to at least 20 questions
|
||||
]
|
||||
}
|
||||
|
||||
+6
-6
@@ -317,16 +317,16 @@ def get_sop_for_department_workers():
|
||||
}
|
||||
'''
|
||||
|
||||
def get_sop_for_department_workers():
|
||||
return '''Generate SOPs for each worker under the unique department based on the information the workers info provided
|
||||
def get_sop_for_department_managers():
|
||||
return '''Generate SOPs for each manager under the unique department based on the information the managers info provided
|
||||
|
||||
Instructions:
|
||||
1. Focus on the provided department and manager role.
|
||||
2. Categorize SOPs into "must," "shall," and "will."
|
||||
3. SOPs should be actionable and relevant to the worker's duties.
|
||||
3. SOPs should be actionable and relevant to the manager's duties.
|
||||
4. If no SOPs can be generated, return empty lists for each category.
|
||||
5. Use the provided document and the workers and department information to generate the SOP.
|
||||
6. If the provided document cannot provide SOPs for a specific worker stated, then return an empty list for the SOP for that worker.
|
||||
5. Use the provided document and the managers and department information to generate the SOP.
|
||||
6. If the provided document cannot provide SOPs for a specific manager stated, then return an empty list for the SOP for that worker.
|
||||
|
||||
Example forma
|
||||
{
|
||||
@@ -335,7 +335,7 @@ def get_sop_for_department_workers():
|
||||
"name": "Department A",
|
||||
"managers": [
|
||||
{
|
||||
"name": "Worker A",
|
||||
"name": "manager A",
|
||||
"must": ["Conduct weekly meetings"],
|
||||
"shall": ["Submit monthly reports"],
|
||||
"will": ["Improve efficiency"]
|
||||
|
||||
@@ -103,7 +103,7 @@ class QuestionsGenerator:
|
||||
{"role": "user", "content": f"Roles Data: {roles_data}"}
|
||||
],
|
||||
response_format=AssementQuestion, # Ensure you specify the correct format
|
||||
max_tokens=4096,
|
||||
max_tokens=10000,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ class DocumentParser:
|
||||
}
|
||||
],
|
||||
response_format=VisionMissionResponse,
|
||||
max_tokens=4096,
|
||||
max_tokens=1600,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
@@ -120,7 +120,7 @@ class DocumentParser:
|
||||
}
|
||||
],
|
||||
response_format=Roles_response,
|
||||
max_tokens=1024,
|
||||
max_tokens=4096,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
@@ -172,7 +172,7 @@ class DocumentParser:
|
||||
{"role": "user", "content": [{"type": "text", "text": text} for text in docs_text]}
|
||||
],
|
||||
response_format=DepartmentsAndWorkersResponse, # Use the updated response schema
|
||||
max_tokens=4096,
|
||||
max_tokens=16000,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
@@ -212,7 +212,7 @@ class DocumentParser:
|
||||
{"role": "system", "content": f"The reference roles are{reference_roles} while the extracted roles are {extracted_managers}"},
|
||||
{"role": "user", "content": prompt}
|
||||
],
|
||||
max_tokens=1024,
|
||||
max_tokens=16000,
|
||||
temperature=0.1,
|
||||
response_format=RolesComparisonResponse
|
||||
)
|
||||
@@ -257,7 +257,7 @@ class DocumentParser:
|
||||
{"role": "system", "content": f"The reference roles are{reference_roles} while the extracted roles are {extracted_workers}"},
|
||||
{"role": "user", "content": prompt}
|
||||
],
|
||||
max_tokens=1024,
|
||||
max_tokens=16000,
|
||||
temperature=0.1,
|
||||
response_format=RolesComparisonResponse
|
||||
)
|
||||
@@ -288,7 +288,7 @@ class DocumentParser:
|
||||
{"role": "user", "content": [{"type": "text", "text": text} for text in docs_text]}
|
||||
],
|
||||
response_format=DepartmentMembers, # Use the updated response schema
|
||||
max_tokens=4096,
|
||||
max_tokens=16000,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
@@ -316,7 +316,7 @@ class DocumentParser:
|
||||
{"role": "user", "content": [{"type": "text", "text": text} for text in docs_text]}
|
||||
],
|
||||
response_format=WorkerSOPsResponse, # Use the updated response schema
|
||||
max_tokens=4096,
|
||||
max_tokens=16000,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
@@ -328,24 +328,24 @@ class DocumentParser:
|
||||
|
||||
def extract_sops_for_managers_by_department(self, docs,depts_managers):
|
||||
"""
|
||||
Extract sops for managers from the document.
|
||||
Extract departments, managers, and workers from the document.
|
||||
|
||||
:param docs: List of document chunks
|
||||
:return: Dictionary containing departments, their managers,
|
||||
:return: Dictionary containing departments, their managers, and workers.
|
||||
"""
|
||||
try:
|
||||
docs_text = self._extract_text_from_docs(docs)
|
||||
prompt = get_sop_for_department_workers() # Update your prompt to handle managers and workers
|
||||
prompt = get_sop_for_department_managers() # Update your prompt to handle managers and workers
|
||||
|
||||
response = self.client.beta.chat.completions.parse(
|
||||
model=self.model,
|
||||
messages=[
|
||||
{"role": "system", "content": prompt},
|
||||
{"role": "user", "content": f"Mangers information: {depts_managers}"},
|
||||
{"role": "user", "content": f"Workers information: {depts_managers}"},
|
||||
{"role": "user", "content": [{"type": "text", "text": text} for text in docs_text]}
|
||||
],
|
||||
response_format=ManagerWithSOPs, # Use the updated response schema
|
||||
max_tokens=4096,
|
||||
response_format=WorkerSOPsResponse, # Use the updated response schema
|
||||
max_tokens=16000,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ class SopPersonalAssessment:
|
||||
}
|
||||
],
|
||||
response_format=SOPsResponse,
|
||||
max_tokens=2048,
|
||||
max_tokens=16000,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
@@ -94,7 +94,7 @@ class SopPersonalAssessment:
|
||||
}
|
||||
],
|
||||
response_format=RoleSops,
|
||||
max_tokens=1024,
|
||||
max_tokens=16000,
|
||||
temperature=0.1
|
||||
)
|
||||
extracted_text = json.loads(response.choices[0].message.content)
|
||||
@@ -127,7 +127,7 @@ class SopPersonalAssessment:
|
||||
}
|
||||
],
|
||||
response_format=Roles_response,
|
||||
max_tokens=1024,
|
||||
max_tokens=16000,
|
||||
temperature=0.1
|
||||
)
|
||||
extracted_text = json.loads(response.choices[0].message.content)
|
||||
@@ -180,7 +180,7 @@ class SopGeneratorExecutive:
|
||||
}
|
||||
],
|
||||
response_format=Categories,
|
||||
max_tokens=2048,
|
||||
max_tokens=16000,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
@@ -214,7 +214,7 @@ class SopGeneratorExecutive:
|
||||
{"role": "user", "content": f"Generate SOPs for {role['position']} in {department['name']} department."}
|
||||
],
|
||||
response_format=ManagerSOPs,
|
||||
max_tokens=1024,
|
||||
max_tokens=16000,
|
||||
temperature=0.1
|
||||
)
|
||||
manager_sops = json.loads(response.choices[0].message.content)
|
||||
@@ -246,7 +246,7 @@ class SopGeneratorExecutive:
|
||||
{"role": "user", "content": f"Generate SOPs based on this questionnaire:\n{user_content}\n\nExecutives to consider: {', '.join(executives)}\nManagers to consider: {', '.join(managers)}\nDepartments to consider: {', '.join(departments)}"}
|
||||
],
|
||||
response_format={"type": "json_object"},
|
||||
max_tokens=4096,
|
||||
max_tokens=16000,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import os
|
||||
from functools import wraps
|
||||
from flask import Flask, session, redirect, url_for, request, g, jsonify
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
|
||||
API_KEY = os.getenv("API_KEY")
|
||||
|
||||
def auth_check(func):
|
||||
@wraps(func)
|
||||
def decorated_function(*args, **kwargs):
|
||||
auth_header = request.headers.get('Authorization')
|
||||
|
||||
if not auth_header or not auth_header.startswith('Bearer '):
|
||||
return jsonify({"error": "Unauthorized", "message": "API key is missing or invalid."}), 401
|
||||
|
||||
token = auth_header.split(' ')[1]
|
||||
if token != API_KEY:
|
||||
return jsonify({"error": "Unauthorized", "message": "API key does not match."}), 401
|
||||
|
||||
g.authenticated = True
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return decorated_function
|
||||
Reference in New Issue
Block a user