added sops generation for personal assessment

This commit is contained in:
2024-09-05 02:59:01 +00:00
parent 6f781cb90a
commit 67d30fbc6a
6 changed files with 368 additions and 71 deletions
+157 -29
View File
@@ -3,29 +3,10 @@ import json
from openai import OpenAI
from pydantic import BaseModel, Field
from typing import List, Dict, Optional
from src.prompts.sops import *
from src.models.response_schemas import *
class SOPs(BaseModel):
must: Optional[List[str]] = Field(default_factory=list)
shall: Optional[List[str]] = Field(default_factory=list)
will: Optional[List[str]] = Field(default_factory=list)
class RoleSOPs(BaseModel):
sops: SOPs
class SOPsFound(BaseModel):
message: str
status: bool
class RolesResponse(BaseModel):
roles: List[str]
class SOPsResponse(BaseModel):
roles_sops: Dict[str, SOPs] = Field(default_factory=dict)
class VisionMissionResponse(BaseModel):
vision: Optional[str]
mission: Optional[str]
message: str
class SopGenerator:
@@ -171,19 +152,19 @@ class SopGenerator:
def generate_sops_by_role_and_area(self, role: str, area: str) -> RoleSOPs:
def generate_sops_by_role_and_area(self, role: str, areas: str) -> RoleSops:
response = self.client.beta.chat.completions.parse(
model=self.model,
messages=[
{
"role": "system",
"content": f'''Your job is to generate Standard Operating Procedures (SOPs) for the role of "{role}" with a focus on the area "{area}" based on the following instructions:
"content": f'''Your job is to generate Standard Operating Procedures (SOPs) for the role of "{role}" with a focus on the areas "{areas}" based on the following instructions:
Instructions:
Categorization: Organize the SOPs under three categories: "must," "shall," and "will."
Direct Instructions: The SOPs should directly address responsibilities, objectives, and challenges related to the area of "{area}" for the role of "{role}".
Categorization: Organize the SOPs under the selected categories: a checkboxex of the three categories "must" , "shall" and "will"
Direct Instructions: The SOPs should directly address responsibilities, objectives, and challenges related to the area of "{areas}" for the role of "{role}".
Contextual Inference: If SOPs for the area are not explicitly stated, infer them from the role and area context provided.
Empty Lists: If no SOPs are generated, return an empty list for each category.
Format: The SOPs should be direct and concise.
@@ -197,7 +178,7 @@ class SopGenerator:
return json.loads(response.choices[0].message.content)
def generate_executive_sops_from_questionnaire(self, data: dict) -> RoleSOPs:
def generate_executive_sops_from_questionnaire(self, data: dict) -> RoleSops:
"""
Generate SOPs based on the answers from an executive questionnaire.
@@ -242,7 +223,7 @@ class SopGenerator:
''',
}
],
response_format=RoleSOPs,
response_format=RoleSops,
max_tokens=1024,
temperature=0.1
)
@@ -325,8 +306,6 @@ class SopGenerator:
# Parse the response from the LLM
extracted_text = json.loads(response.choices[0].message.content)
print(F"extracted text:{extracted_text}")
# Assuming the response contains fields for 'vision' and 'mission' (or 'goals')
vision_section = extracted_text["vision"]
mission_section = extracted_text["mission"]
@@ -334,3 +313,152 @@ class SopGenerator:
return vision_section, mission_section
class SopGeneratorDocument:
def __init__(self):
self.api_key = os.getenv("OPENAI_API_KEY")
self.client = OpenAI(api_key=self.api_key)
self.model = "gpt-4o-2024-08-06"
def _extract_text_from_docs(self, docs):
"""Extract text content from document objects."""
return [doc.page_content for doc in docs]
# Existing methods...
def extract_sops_from_doc(self, docs) -> VisionMissionResponse:
"""
Extracts Vision, Mission, and SOPs categorized into 'must,' 'shall,' and 'will' from the document.
:param docs: The document(s) from which to extract information.
:return: VisionMissionResponse containing the vision, mission, and role-specific SOPs.
"""
try:
docs_text = self._extract_text_from_docs(docs)
prompt = get_sop_extraction_from_doc()
response = self.client.beta.chat.completions.parse(
model=self.model,
messages=[
{
"role": "system",
"content": f'''{prompt}'''
},
{
"role": "user",
"content": [{"type": "text", "text": text} for text in docs_text],
}
],
response_format=SOPsResponse,
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:
return False
class SopPersonalAssessment:
def __init__(self):
self.api_key = os.getenv("OPENAI_API_KEY")
self.client = OpenAI(api_key=self.api_key)
self.model = "gpt-4o-mini"
# Existing methods...
def extract_sops_from_questionnaire(self, questionnaire_data: dict) -> VisionMissionResponse:
"""
Extracts SOPs categorized into 'must,' 'shall,' and 'will' based on free-text questionnaire information.
:param questionnaire_data: A dictionary containing plain text responses to the questionnaire.
:return: SOPsResponse containing the vision, mission, and role-specific SOPs
"""
try:
# Extract the plain text answers from the questionnaire
vision = questionnaire_data.get("vision", "No vision provided")
roles = questionnaire_data.get("roles", "No roles provided") # This will be a plain text string
responsibilities = questionnaire_data.get("responsibilities", "No responsibilities provided") # Plain text string
project_details = questionnaire_data.get("project_details", "No additional project details provided")
# Get the appropriate prompt for the questionnaire scenario
prompt = get_sop_personalassessment_from_questionnaire()
# Combine the plain text data into a string to pass to the LLM
user_content = f'''
Vision: {vision}
Roles: {roles}
Responsibilities: {responsibilities}
Project Details: {project_details}
'''
# Send the combined plain text content to the LLM
response = self.client.beta.chat.completions.parse(
model=self.model,
messages=[
{
"role": "system",
"content": f'''{prompt}'''
},
{
"role": "user",
"content": user_content,
}
],
response_format=SOPsResponse,
max_tokens=2048,
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"Error occurred: {str(e)}")
return False
def generate_sops_by_role_and_area(self, roles: List[dict]) -> RoleSops:
try:
sops_by_role = []
for role_info in roles:
role = role_info['role']
sop_types = role_info['sop_types'] # List of SOP types: ["will", "shall", "must"]
areas = role_info['areas'] # List of areas: ["communication", "development", etc.]
prompt = get_sop_personalassessment_from_area_role(role,areas,sop_types)
response = self.client.beta.chat.completions.parse(
model=self.model,
messages=[
{
"role": "system",
"content": f'''{prompt}
''',
}
],
response_format=RoleSops,
max_tokens=1024,
temperature=0.1
)
extracted_text = json.loads(response.choices[0].message.content)
# You can customize this to generate SOPs based on the role, SOP types, and areas
sops_by_role.append(extracted_text)
return sops_by_role
except:
return False