added worker validation bot
This commit is contained in:
@@ -0,0 +1,81 @@
|
|||||||
|
%PDF-1.3
|
||||||
|
3 0 obj
|
||||||
|
<</Type /Page
|
||||||
|
/Parent 1 0 R
|
||||||
|
/Resources 2 0 R
|
||||||
|
/Contents 4 0 R>>
|
||||||
|
endobj
|
||||||
|
4 0 obj
|
||||||
|
<</Filter /FlateDecode /Length 449>>
|
||||||
|
stream
|
||||||
|
xœm’OoÛ0Åïý<nÀ Zþç¸tÖÓ€ÛÙ±éD«-¢ì,ûô£dgi‘^l@¢Þ{ü‘1¼<D"+àüðµ‚Çg 2QUß*$‹\Äeꫪ>íL«ôªš^ag†±G§Œ†'ÓLj÷ªßëÛÇçd|“KE”¥P«D
|
||||||
|
YB!#Q$A¶:)‚vB;#AM0Zc:p§Úñálì+Z8ñ
|
||||||
|
MMƒDÝÔ÷h–$؆ªfÉè8ã5OôÎ8ßÄ"ÙãšH5¶âMòµ(ãÄ×tÔ@éÙôójÓ™¾7gﴒѶ÷Bq&ò2I¿¬r¾¸†wbtݤ›ÀÐß®o
|
||||||
|
ÚÚÕÐY3pÙnÿ:Õã}¬,D’áXÀw�Àãóê“VLÉ‘—EM“Å%ôÕÍ£ˆñψ�ûˆ@–—a|¬ŸxÂÃt<†èº3:5¨¿�ó‚ܱ0¢åßPëA
|
||||||
|
ÜÏ2Ñêi$òì=ß3ç¹ÍÒ3á†�@RuŠOÈÔC†erp¸„2šØ{Vdì½WºID™¯|[ZÞÂG‡Ã�×JF_ ŽâôþyÆ”áùþ¿Ë^j�¼ùxÿ!*
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
1 0 obj
|
||||||
|
<</Type /Pages
|
||||||
|
/Kids [3 0 R ]
|
||||||
|
/Count 1
|
||||||
|
/MediaBox [0 0 595.28 841.89]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
5 0 obj
|
||||||
|
<</Type /Font
|
||||||
|
/BaseFont /Helvetica-Bold
|
||||||
|
/Subtype /Type1
|
||||||
|
/Encoding /WinAnsiEncoding
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
6 0 obj
|
||||||
|
<</Type /Font
|
||||||
|
/BaseFont /Helvetica
|
||||||
|
/Subtype /Type1
|
||||||
|
/Encoding /WinAnsiEncoding
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
2 0 obj
|
||||||
|
<<
|
||||||
|
/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
|
||||||
|
/Font <<
|
||||||
|
/F1 5 0 R
|
||||||
|
/F2 6 0 R
|
||||||
|
>>
|
||||||
|
/XObject <<
|
||||||
|
>>
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
7 0 obj
|
||||||
|
<<
|
||||||
|
/Producer (PyFPDF 1.7.2 http://pyfpdf.googlecode.com/)
|
||||||
|
/CreationDate (D:20240910213710)
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
8 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Catalog
|
||||||
|
/Pages 1 0 R
|
||||||
|
/OpenAction [3 0 R /FitH null]
|
||||||
|
/PageLayout /OneColumn
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
xref
|
||||||
|
0 9
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000606 00000 n
|
||||||
|
0000000890 00000 n
|
||||||
|
0000000009 00000 n
|
||||||
|
0000000087 00000 n
|
||||||
|
0000000693 00000 n
|
||||||
|
0000000794 00000 n
|
||||||
|
0000001004 00000 n
|
||||||
|
0000001113 00000 n
|
||||||
|
trailer
|
||||||
|
<<
|
||||||
|
/Size 9
|
||||||
|
/Root 8 0 R
|
||||||
|
/Info 7 0 R
|
||||||
|
>>
|
||||||
|
startxref
|
||||||
@@ -2,6 +2,7 @@ import os
|
|||||||
from flask import Flask
|
from flask import Flask
|
||||||
from src.api.routes.sops import sops_bp
|
from src.api.routes.sops import sops_bp
|
||||||
from src.api.routes.questions import qs_b
|
from src.api.routes.questions import qs_b
|
||||||
|
from src.api.routes.chatbot import bot
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
@@ -9,6 +10,7 @@ def create_app():
|
|||||||
# Register the blueprint with the desired prefix
|
# Register the blueprint with the desired prefix
|
||||||
app.register_blueprint(sops_bp, url_prefix='/api/v1/sop')
|
app.register_blueprint(sops_bp, url_prefix='/api/v1/sop')
|
||||||
app.register_blueprint(qs_b,url_prefix='/api/v1/qs')
|
app.register_blueprint(qs_b,url_prefix='/api/v1/qs')
|
||||||
|
app.register_blueprint(bot,url_prefix='/api/v1/bot')
|
||||||
|
|
||||||
# Set up the upload folder configuration inside the src directory
|
# Set up the upload folder configuration inside the src directory
|
||||||
UPLOAD_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../uploads')
|
UPLOAD_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../uploads')
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import os
|
||||||
|
from flask import Blueprint, request, jsonify, current_app
|
||||||
|
from werkzeug.utils import secure_filename
|
||||||
|
from src.services.chatbot import Chatbot
|
||||||
|
from src.utils.utils import delete_all_files_in_directory
|
||||||
|
from src.utils.document_loader import load_document
|
||||||
|
|
||||||
|
|
||||||
|
# Initialize the Blueprint
|
||||||
|
bot = Blueprint('chatbot', __name__)
|
||||||
|
|
||||||
|
# Allowed file extensions
|
||||||
|
ALLOWED_EXTENSIONS = {'pdf', 'doc', 'docx'}
|
||||||
|
|
||||||
|
def allowed_file(filename):
|
||||||
|
"""Check if the file has an allowed extension."""
|
||||||
|
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||||
|
|
||||||
|
@bot.route('/validate_worker_document', methods=['POST'])
|
||||||
|
def validate_worker_document():
|
||||||
|
try:
|
||||||
|
# Retrieve form data
|
||||||
|
question = request.form.get('question')
|
||||||
|
file = request.files.get('document')
|
||||||
|
|
||||||
|
if not question or not file:
|
||||||
|
return jsonify({"error": "Missing data", "message": "Question or document not provided."}), 400
|
||||||
|
|
||||||
|
if file.filename == '':
|
||||||
|
return jsonify({"error": "No selected file", "message": "No file was selected for upload."}), 400
|
||||||
|
|
||||||
|
if file and allowed_file(file.filename):
|
||||||
|
# Secure the file name and save it
|
||||||
|
filename = secure_filename(file.filename)
|
||||||
|
upload_folder = current_app.config['UPLOAD_FOLDER']
|
||||||
|
file_path = os.path.join(upload_folder, filename)
|
||||||
|
file.save(file_path)
|
||||||
|
|
||||||
|
# Load the document for processing
|
||||||
|
docs = load_document(file_path)
|
||||||
|
|
||||||
|
# Instantiate the chatbot service
|
||||||
|
chatbot = Chatbot()
|
||||||
|
|
||||||
|
# Validate the worker's response using the provided document
|
||||||
|
validation_result = chatbot.validate_worker(question, docs)
|
||||||
|
|
||||||
|
if not validation_result:
|
||||||
|
return jsonify({"error": "Validation failed", "message": "Validation process failed."}), 400
|
||||||
|
|
||||||
|
# Clean up uploaded file (optional)
|
||||||
|
os.remove(file_path)
|
||||||
|
|
||||||
|
# Return the validation result
|
||||||
|
return jsonify({"result": validation_result["result"]}), 200
|
||||||
|
|
||||||
|
else:
|
||||||
|
return jsonify({"error": "Invalid file", "message": "File format not supported."}), 400
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": "Internal Server Error", "message": str(e)}), 500
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from typing import List, Dict
|
||||||
|
|
||||||
|
class ValidateWorker(BaseModel):
|
||||||
|
result:str
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
def validate_worker_prompt() -> str:
|
||||||
|
return """
|
||||||
|
You are a worker in the company "Validate" where you are asked a specific yes or no question:
|
||||||
|
|
||||||
|
The worker's response: "Yes"
|
||||||
|
|
||||||
|
Since the worker answered "Yes," they are required to submit a document to justify their answer.
|
||||||
|
|
||||||
|
Your role is to analyze the question being asked, review the document the worker uploaded, and verify whether the worker's answer is valid or not.
|
||||||
|
The goal is to assess the document's content to see if it aligns with the worker's claim of "Yes."
|
||||||
|
|
||||||
|
response format
|
||||||
|
if not validated return "not validated"
|
||||||
|
{
|
||||||
|
result:"validated"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import os
|
||||||
|
import json
|
||||||
|
from openai import OpenAI
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
from typing import List, Dict, Optional
|
||||||
|
from src.prompts.sops import *
|
||||||
|
from src.prompts.chatbot import *
|
||||||
|
from src.models.sop_response_schemas import *
|
||||||
|
from src.models.bot_response_schema import *
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
|
||||||
|
#SopGeneratorDocument
|
||||||
|
class Chatbot:
|
||||||
|
def __init__(self):
|
||||||
|
self.api_key = os.getenv("OPENAI_API_KEY")
|
||||||
|
self.client = OpenAI(api_key=self.api_key)
|
||||||
|
self.model = "gpt-4o-mini"
|
||||||
|
|
||||||
|
def _extract_text_from_docs(self, docs):
|
||||||
|
"""Extract text content from document objects."""
|
||||||
|
return [doc.page_content for doc in docs]
|
||||||
|
# Existing methods...
|
||||||
|
|
||||||
|
def validate_worker(self, question, docs) -> VisionMissionResponse:
|
||||||
|
"""
|
||||||
|
This method is responsible for validating the worker's response ("yes" or "no") using the provided document(s).
|
||||||
|
The system generates a prompt, extracts document content, and validates the response using the GPT-4 model.
|
||||||
|
|
||||||
|
:param question: The yes/no question asked to the worker.
|
||||||
|
:param docs: A list of document(s) uploaded by the worker.
|
||||||
|
:return: VisionMissionResponse containing the validated result or None if an error occurs.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
docs_text = self._extract_text_from_docs(docs)
|
||||||
|
prompt = validate_worker_prompt()
|
||||||
|
response = self.client.beta.chat.completions.parse(
|
||||||
|
model=self.model,
|
||||||
|
messages=[
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": f'''{prompt} The document is uploaded next.'''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": f"Question :{question}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": [{"type": "text", "text": text} for text in docs_text],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
response_format=ValidateWorker,
|
||||||
|
max_tokens=4096,
|
||||||
|
temperature=0.1
|
||||||
|
)
|
||||||
|
|
||||||
|
# Parse the response from the LLM
|
||||||
|
extracted_text = json.loads(response.choices[0].message.content)
|
||||||
|
|
||||||
|
return extracted_text
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"An error occurred: {e}")
|
||||||
|
return None
|
||||||
@@ -1,72 +1,16 @@
|
|||||||
import json
|
# Example usage of the Chatbot class:
|
||||||
from src.services.questions_generator import QuestionsGenerator
|
from src.services.chatbot import Chatbot
|
||||||
|
from src.utils.document_loader import load_document
|
||||||
|
if __name__ == "__main__":
|
||||||
|
chatbot = Chatbot()
|
||||||
|
|
||||||
# Mocking the SOPs input as described in your example
|
# Example inputs
|
||||||
mock_sops_input = {
|
path = r"C:\Users\User\Desktop\Blessing_AI\MKD\test_erp_ai\erp_ai\test\erp_ai\data\raw\coding_task_completion_document.pdf"
|
||||||
"sops": {
|
|
||||||
"departments": [
|
|
||||||
{
|
|
||||||
"name": "Accounts Receivable",
|
|
||||||
"workers": [
|
|
||||||
{
|
|
||||||
"name": "Angela Lewis",
|
|
||||||
"position": "AR Director",
|
|
||||||
"sops": {
|
|
||||||
"must": [],
|
|
||||||
"shall": [],
|
|
||||||
"will": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Jamie Vega",
|
|
||||||
"position": "AR Supervisor",
|
|
||||||
"sops": {
|
|
||||||
"must": [
|
|
||||||
"Provide escalation information to the AR Director if additional escalations are needed."
|
|
||||||
],
|
|
||||||
"shall": [],
|
|
||||||
"will": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Jessica Merzougui",
|
|
||||||
"position": "AR Supervisor",
|
|
||||||
"sops": {
|
|
||||||
"must": [
|
|
||||||
"Provide escalation information to the AR Director if additional escalations are needed."
|
|
||||||
],
|
|
||||||
"shall": [],
|
|
||||||
"will": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Deniece Santos",
|
|
||||||
"position": "AR Analyst",
|
|
||||||
"sops": {
|
|
||||||
"must": [],
|
|
||||||
"shall": [],
|
|
||||||
"will": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Defining the full input data including additional parameters
|
question = "Have you completed Task X?"
|
||||||
input_data = {
|
user_input = "Yes"
|
||||||
"sops": json.dumps(mock_sops_input), # Convert SOPs to JSON string format
|
docs = load_document(path)
|
||||||
"assessment_type": "progress", # Set the assessment type
|
|
||||||
"frequency_type": "weekly", # Set the frequency type (daily, weekly, etc.)
|
|
||||||
"duration": 4 # Set the duration (number of frequency cycles, e.g., 4 weeks)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Initialize the QuestionsGenerator
|
# Validate the worker's answer using the provided document
|
||||||
generator = QuestionsGenerator()
|
validation_result = chatbot.validate_worker(question, docs)
|
||||||
|
print(validation_result)
|
||||||
# Invoke the generate_questions method with the mock input
|
|
||||||
questions_response = generator.generate_questions(input_data)
|
|
||||||
|
|
||||||
# Print the generated questions response
|
|
||||||
print(json.dumps(questions_response, indent=4))
|
|
||||||
Reference in New Issue
Block a user