jesshewyz's picture
fix: reset project
f876a7b verified
from enum import Enum
# from ProjectClient import Client,zus_coffee,ssm, game
from prompts import *
from langtrace_python_sdk.utils.with_root_span import with_langtrace_root_span
import openai
from contextlib import contextmanager
# import json
@contextmanager
def openai_session():
"""Context manager to properly handle OpenAI API sessions"""
try:
# Initialize client
client = openai.OpenAI()
yield client
finally:
# Clean up client resources
if hasattr(client, 'close'):
client.close()
@with_langtrace_root_span()
def call_o1_mini(prompt):
print(f"calling o1-mini with prompt: {prompt}")
with openai_session() as client:
try:
client = openai.OpenAI()
# Call API
response = client.chat.completions.create(
model="o1-mini", # Replace with the appropriate model
messages=[
{"role": "user", "content": prompt}
]
)
# Extract response text
result = response.choices[0].message.content
return result
except Exception as e:
return f"Error generating output: {str(e)}"
@with_langtrace_root_span()
def call_4o_mini(prompt):
print(f"calling 4o-mini with prompt: {prompt}")
with openai_session() as client:
try:
client = openai.OpenAI()
# Call API
response = client.chat.completions.create(
model="gpt-4o-mini", # Replace with the appropriate model
# model="chatgpt-4o-latest", # Replace with the appropriate model
messages=[
{"role": "user", "content": prompt}
]
)
# Extract response text
result = response.choices[0].message.content
return result
except Exception as e:
return f"Error generating output: {str(e)}"
class ProjectType(Enum):
Page = "Page"
Sage = "Sage"
Engage = "Engage"
class Project:
def __init__(self, project_type: ProjectType, session_id = None):
self.project_type = project_type
self.session_id = session_id
# requirement_rubric, fetch from db
# then retrive from here again, omit recalls to fetch the same thing over and over
self.rubric = []
self.rubric_section_names = []
self.project_detail = []
self.generated_prd = ""
self.component_list = []
self.component_csv = ""
self.flared_csv = ""
# Method 2 - Top Down Approach Variables
# The top down approach involves breaking PRD into phases & components, then subtasks and unit and mandays
self.derived_components = ""
self.derived_tasks = ""
self.derived_baseunits = ""
self.derived_mandays = ""
def reset_project(self):
# requirement_rubric, fetch from db
# then retrive from here again, omit recalls to fetch the same thing over and over
self.rubric = []
self.rubric_section_names = []
self.project_detail = []
self.generated_prd = ""
self.component_list = []
self.component_csv = ""
self.flared_csv = ""
# Method 2 - Top Down Approach Variables
# The top down approach involves breaking PRD into phases & components, then subtasks and unit and mandays
self.derived_components = ""
self.derived_tasks = ""
self.derived_baseunits = ""
self.derived_mandays = ""
def set_rubric(self,rubric):
self.rubric = rubric
def set_component_csv(self,component_csv):
self.component_csv = component_csv
def is_active(self):
return self.session_id != None
def get_component_csv(self):
return self.component_csv
def set_component_list(self,component_list):
self.component_list = component_list
def set_rubric_section_names(self,rubric_section_names):
self.rubric_section_names = rubric_section_names
def set_project_detail(self,project_detail):
self.project_detail = project_detail
def add_project_detail(self,project_detail):
self.project_detail.append(project_detail)
def get_project_detail(self):
return(self.project_detail)
# the rubric to generate project questions
def project_question_generation_rubric(self ):
headers = [ 'Criteria', 'Initial Questions', 'Quantifiable Value']
# table = '| ' + ' | '.join(headers) + ' |'
table = ' | '.join(headers)
# table += '\n' + '| ' + ' | '.join(['---'] * len(headers)) + ' |'
# print(len(self.rubric))
for entry in self.rubric:
# print(entry)
# table += f"\n{entry['criteria']} | {entry['explanation']} | {entry['priority']} | {entry['quantifiable_value'] or ''}"
table += f"\n{entry['criteria']} | {entry['initial_question']} | {entry['quantifiable_value'] or ''}"
# table += f"\n| {entry['section_name']} | {entry['criteria']} | {entry['explanation']} | {entry['priority']} | {entry['quantifiable_value'] or ''} |"
return table
# the rubric to grade answers project questions
def project_question_grading_rubric(self):
headers = ['Criteria', 'Explanation', 'Priority', 'Quantifiable Value']
# headers = ['Criteria', 'Explanation', 'Priority', 'Quantifiable Value']
# table = '| ' + ' | '.join(headers) + ' |'
table = ' | '.join(headers)
# table += '\n' + '| ' + ' | '.join(['---'] * len(headers)) + ' |'
# print(len(self.rubric))
for entry in self.rubric:
# print(entry)
# table += f"\n{entry['criteria']} | {entry['explanation']} | {entry['priority']} | {entry['quantifiable_value'] or ''}"
table += f"\n{entry['criteria']} | {entry['explanation']} | {entry['priority']} | {entry['quantifiable_value'] or ''}"
# table += f"\n| {entry['section_name']} | {entry['criteria']} | {entry['explanation']} | {entry['priority']} | {entry['quantifiable_value'] or ''} |"
return table
# different pemutation of columns, to reduce token count
def rubric_to_text(self):
headers = ['Section Name', 'Criteria', 'Explanation', 'Priority', 'Quantifiable Value']
# headers = ['Criteria', 'Explanation', 'Priority', 'Quantifiable Value']
# table = '| ' + ' | '.join(headers) + ' |'
table = ' | '.join(headers)
# table += '\n' + '| ' + ' | '.join(['---'] * len(headers)) + ' |'
# print(len(self.rubric))
for entry in self.rubric:
# print(entry)
# table += f"\n{entry['criteria']} | {entry['explanation']} | {entry['priority']} | {entry['quantifiable_value'] or ''}"
table += f"\n{entry['section_name']} | {entry['criteria']} | {entry['explanation']} | {entry['priority']} | {entry['quantifiable_value'] or ''}"
# table += f"\n| {entry['section_name']} | {entry['criteria']} | {entry['explanation']} | {entry['priority']} | {entry['quantifiable_value'] or ''} |"
return table
def rubric_to_verify(self):
# headers = ['Section Name', 'Criteria', 'Explanation', "Priority"]
headers = ['Criteria', 'Explanation', "Priority"]
# table = '| ' + ' | '.join(headers) + ' |'
table = ' | '.join(headers)
# table += '\n' + '| ' + ' | '.join(['---'] * len(headers)) + ' |'
# print(len(self.rubric))
for entry in self.rubric:
merged_columns = entry['explanation'] + " " + (entry['quantifiable_value'] or '')
# print(entry)
table += f"\n {entry['criteria']} | {merged_columns} | {entry['priority']}"
# table += f"\n| {entry['section_name']} | {entry['criteria']} | {entry['explanation']} | {entry['priority']} | {entry['quantifiable_value'] or ''} |"
return table
def component_to_text(self):
# If input is empty, return empty string
if not self.component_list:
return ""
# Get headers from the first row
# headers = list(self.component_list[0].keys())
headers = ["base_project_name", "module", "submodule","unit_type", "quantity"]
# Create header row
table = " | ".join(headers) + "\n"
table += "-" * len(table) + "\n"
# Add data rows
for row in self.component_list:
# Convert None values to empty strings and all values to strings
values = [str(row[header]) if row[header] is not None else "" for header in headers]
table += " | ".join(values) + "\n"
return table
def get_component_mandays(self):
# If input is empty, return empty list
if not self.component_list:
return []
# Define headers we want to extract
headers = ["module", "submodule", "mandays_per_unit"]
# Create list of dictionaries with only the headers we want
result = []
for row in self.component_list:
filtered_row = {
header: row[header] if row[header] is not None else ""
for header in headers
}
result.append(filtered_row)
return result
def generate_client_follow_up(self ,system_prompt = client_follow_up_with_sample_answers):
# current_form = self.filter_non_empty_answer()
prompt = f"""
{system_prompt}
# Input:
## Client Details / Project Requirement Q&A
{self.project_detail}
"""
# print(f"\n\generate_client_follow_up with prompt: {prompt}\n\n")
result = call_o1_mini(prompt)
# print(f"type, result : {type(result)}, {result}")
return result
def generate_questions(self, system_prompt=question_generator_with_sample_answer):
prompt = f"""
{system_prompt}
# Input:
## Client Details / Project Requirement Q&A
{self.project_detail}
## Requirement Rubric
{self.project_question_generation_rubric()}
"""
# print(f"\n\generate_questions with prompt: {prompt}\n\n")
result = call_o1_mini(prompt)
# print(f"type, result : {type(result)}, {result}")
return result
def generate_follow_up(self ,system_prompt = followup_question_generator_with_sample_answers):
# current_form = self.filter_non_empty_answer()
prompt = f"""
{system_prompt}
# Input:
## Client Details / Project Requirement Q&A
{self.project_detail}
## Requirement Rubric
{self.project_question_grading_rubric()}
"""
# print(f"\n\generate_questions with prompt: {prompt}\n\n")
result = call_o1_mini(prompt)
return result
def rewrite_qa(self,system_prompt = structure_qa):
prompt = f"""
{system_prompt}
# Input:
## Client Details / Project Requirement Q&A
{self.get_project_detail()}"""
result = call_o1_mini(prompt)
self.generated_prd = result
# print(f"POPULATED TABLE : {result}")
return result
def flare_tasks(self, system_prompt = flare_task):
# current_form = self.filter_non_empty_answer()
# {self.get_project_detail()}
prompt = f"""
{system_prompt}
# Input:
{self.generated_prd}
## Component List
{self.component_to_text()}
"""
# print(f"\n\ additional_tasks with prompt: {prompt}\n\n")
result = call_o1_mini(prompt)
self.flared_csv = result
# self.set_component_csv(result)
# print(f"POPULATED ADDITIONAL TASK TABLE : {result}")
return result
def populate_template_with_units(self, system_prompt = populate_csv):
# current_form = self.filter_non_empty_answer()
prompt = f"""
{system_prompt}
# Input:
## Client Details / Project Requirement Q&A
{self.get_project_detail()}
## Component List
{self.component_to_text()}
"""
# print(f"\n\populate_template_with_units with prompt: {prompt}\n\n")
result = call_o1_mini(prompt)
self.set_component_csv(result)
# print(f"POPULATED TABLE : {result}")
return result
def populate_template_with_orgranised_qa(self, system_prompt = populate_csv_v2):
# organised_qa = self.rewrite_qa()
# current_form = self.filter_non_empty_answer()
prompt = f"""
{system_prompt}
# Input:
{self.generated_prd}
## Component / Tasks List
{self.flared_csv}
"""
# print(f"\n\populate_template_with_units with prompt: {prompt}\n\n")
result = call_o1_mini(prompt)
self.set_component_csv(result)
# print(f"POPULATED TABLE : {result}")
return result
def additional_tasks(self, system_prompt = missing_task):
# current_form = self.filter_non_empty_answer()
prompt = f"""
{system_prompt}
# Input:
## Client Details / Project Requirement Q&A
{self.get_project_detail()}
## Componet List
{self.component_csv}
"""
# print(f"\n\ additional_tasks with prompt: {prompt}\n\n")
result = call_o1_mini(prompt)
# self.set_component_csv(result)
# print(f"POPULATED ADDITIONAL TASK TABLE : {result}")
return result
def analyse_quotation(self, system_prompt=quotation_analysis_prompt, quotation_details=None,quotation_table=None):
# Check for None parameters
if self.generated_prd == "" or self.generated_prd is None:
error_message = "Error: generated_prd must not be None. / empty"
print(error_message)
return error_message
if quotation_details is None:
error_message = "Error: quotation_details must not be None."
print(error_message)
return error_message
if quotation_table is None:
error_message = "Error: quotation_table must not be None."
print(error_message)
return error_message
# current_form = self.filter_non_empty_answer()
prompt = f"""
{system_prompt}
1.Project Requirements Document
{self.generated_prd}
2.Quotation Details:
{quotation_details}
3.Quotation Task List
{quotation_table}
"""
print(f"\n\ analyse_quotation with prompt: {prompt}\n\n")
result = call_o1_mini(prompt)
# self.set_component_csv(result)
# print(f"POPULATED ADDITIONAL TASK TABLE : {result}")
return result
def generate_components(self, system_prompt = define_components):
prompt = f"""
{system_prompt}
# PRD :
{self.generated_prd}
"""
# print(prompt)
result = call_4o_mini(prompt)
self.derived_components = result
return result
def generate_dev_components(self, system_prompt = define_dev_components):
prompt = f"""
{system_prompt}
# PRD :
{self.generated_prd}
"""
# print(prompt)
result = call_o1_mini(prompt)
# need to check whether this would work
self.derived_components = result + self.derived_components
return result
def generate_tasks(self, system_prompt = define_technical_task):
prompt = f"""
{system_prompt}
# PRD :
{self.generated_prd}
# Component List
{self.derived_components}
"""
# print(prompt)
result = call_o1_mini(prompt)
self.derived_tasks = result
print(result)
return result
def generate_baseunits(self, system_prompt = derive_unit):
prompt = f"""
{system_prompt}
# PRD :
{self.generated_prd}
# Task List
{self.derived_tasks}
"""
# print(prompt)
result = call_o1_mini(prompt)
self.derived_baseunits = result
return result
def generate_mandays(self, system_prompt = derive_mandays):
prompt = f"""
{system_prompt}
# Task Breakdown Document
{self.derived_baseunits}
"""
# print(prompt)
result = call_o1_mini(prompt)
self.derived_mandays = result
return result