|
import pandas as pd |
|
import streamlit as st |
|
import os |
|
import json |
|
from openai import AzureOpenAI |
|
from model import create_models, configure_settings, load_documents_and_create_index, \ |
|
create_chat_prompt_template, execute_query |
|
from datasets import Dataset, DatasetDict, load_dataset, concatenate_datasets |
|
|
|
client = AzureOpenAI(azure_endpoint="https://personality-service.openai.azure.com/", |
|
api_key=os.getenv("AZURE_OPENAI_KEY"), api_version="2024-02-15-preview") |
|
|
|
TOKEN = os.getenv('hf_token') |
|
def store_feedback(user_input, response, feedback, rating,repo): |
|
dataset = load_dataset(repo, use_auth_token=TOKEN, download_mode="force_redownload", ignore_verifications=True) |
|
new_entry = pd.DataFrame({"user_input": [user_input], "response": [response], "feedback": [feedback], "rating": [rating]}) |
|
new_dataset = Dataset.from_pandas(new_entry) |
|
updated_dataset = concatenate_datasets([dataset["train"], new_dataset]) |
|
updated_dataset.push_to_hub(repo, private=False, use_auth_token=TOKEN) |
|
|
|
|
|
def generate_one_completion(message, temperature): |
|
response = client.chat.completions.create( |
|
model="personality_gpt4o", |
|
temperature=temperature, |
|
max_tokens=1000, |
|
frequency_penalty=0.2, |
|
presence_penalty=0.2, |
|
messages=message, |
|
stream=False |
|
) |
|
|
|
return response |
|
|
|
|
|
import json |
|
|
|
def get_profile_str(profile): |
|
bio_info = profile['bio_information'] |
|
main_profile = profile['main_profile'] |
|
red_flag = profile['red_flag'] |
|
motivation = profile['motivation'] |
|
profile_str = f"Bio Information:\n" |
|
for key, value in bio_info.items(): |
|
profile_str += f"- {key.replace('_', ' ').title()}: {value}\n" |
|
profile_str += f"\nMain Profile:\n" |
|
for key, value in main_profile.items(): |
|
profile_str += f"- {key.title()}: {value['score']} - {value['summary']}\n" |
|
profile_str += f"\nRed Flags:\n" |
|
for key, value in red_flag.items(): |
|
profile_str += f"- {key.title()}: {value['score']} - {value['summary']}\n" |
|
profile_str += f"\nMotivation:\n" |
|
for key, value in motivation.items(): |
|
profile_str += f"- {key.title()}: {value['score']} - {value['summary']}\n" |
|
return profile_str |
|
|
|
def generate_prompt_from_profile(profile, version="TestTakersSummary"): |
|
with open('prompts.json') as f: |
|
prompt_sets = json.load(f)['Prompts'] |
|
prompt_templates = prompt_sets[version] |
|
|
|
try: |
|
|
|
individual_name = profile['bio_information'].get('Name', 'the individual') |
|
|
|
|
|
bio_section = "\n".join( |
|
[f"- {k.replace('_', ' ').title()}: {v}" for k, v in profile['bio_information'].items()]) |
|
main_profile_section = "\n".join( |
|
[f"- {trait.title()}: {details['score']} - {details['summary']}" for trait, details in |
|
profile['main_profile'].items()]) |
|
red_flags_section = "\n".join( |
|
[f"- {trait.title()}: {details['score']} - {details['summary']}" for trait, details in |
|
profile['red_flag'].items()]) |
|
|
|
motivation_section = "\n".join( |
|
[f"- {trait.title()}: {details['score']} - {details['summary']}" for trait, details in |
|
profile['motivation'].items()]) |
|
|
|
|
|
prompts = [ |
|
x.replace('{{INDIVIDUAL_NAME}}', individual_name).replace('{{BIO}}', bio_section).replace('{{PROFILE}}',main_profile_section).replace( |
|
'{{REDFLAGS_PROFILE}}', red_flags_section).replace('{{MOTIVATION_PROFILE}}', motivation_section) for x in prompt_templates] |
|
|
|
|
|
prompt = "\n".join(prompts) |
|
|
|
except KeyError as e: |
|
return [{"role": "system", "content": f"Error processing profile data: missing {str(e)}"}] |
|
|
|
message = [ |
|
{"role": "system", "content": prompt_sets[version][0]}, |
|
{"role": "user", "content": prompt} |
|
] |
|
|
|
return message |
|
|
|
|
|
def display_profile_info(profile): |
|
main_profile = profile["main_profile"] |
|
red_flag = profile["red_flag"] |
|
bio_info = profile["bio_information"] |
|
|
|
st.sidebar.markdown("### Bio Information: ") |
|
st.sidebar.markdown("\n".join([f"- **{key.replace('_', ' ')}**: {value}" for key, value in bio_info.items()])) |
|
st.sidebar.markdown("### Main Profile: ") |
|
st.sidebar.markdown("\n".join( |
|
[f"- **{attribute}**: {details['score']} - {details['summary']}" for attribute, details in |
|
main_profile.items()])) |
|
st.sidebar.markdown("### Red Flags: ") |
|
st.sidebar.markdown("\n".join( |
|
[f"- **{attribute}**: {details['score']} - {details['summary']}" for attribute, details in red_flag.items()])) |
|
st.sidebar.markdown("### Motivation: ") |
|
st.sidebar.markdown("\n".join( |
|
[f"- **{attribute}**: {details['score']} - {details['summary']}" for attribute, details in profile['motivation'].items()])) |
|
|
|
|
|
def validate_json(profile): |
|
required_keys = ['bio_information', 'main_profile', 'red_flag', 'motivation'] |
|
for key in required_keys: |
|
if key not in profile: |
|
return False, f"Key '{key}' is missing." |
|
if not isinstance(profile[key], dict): |
|
return False, f"'{key}' should be a dictionary." |
|
return True, "JSON structure is valid." |
|
|
|
|
|
def logout(): |
|
st.session_state['authenticated'] = False |
|
st.session_state['profile'] = None |
|
st.session_state['show_chat'] = None |
|
st.session_state['analysis'] = None |
|
st.rerun() |
|
|
|
|
|
def main_app(): |
|
sidebar_components() |
|
|
|
if st.button('Logout'): |
|
logout() |
|
|
|
|
|
st.title('Metaprofiling\'s Career Insight Analyzer Demo') |
|
|
|
|
|
if st.session_state['profile']: |
|
profile = st.session_state['profile'] |
|
display_profile_info(profile) |
|
|
|
st.markdown(""" |
|
### Generation Temperature |
|
Adjust the 'Generation Temperature' to control the creativity of the AI responses. |
|
- A *lower temperature* (closer to 0.0) generates more predictable, conservative responses. |
|
- A *higher temperature* (closer to 1.0) generates more creative, diverse responses. |
|
""") |
|
|
|
st.session_state['temperature'] = st.slider("", min_value=0.0, max_value=1.0, value=0.5, step=0.01) |
|
|
|
|
|
st.session_state['version'] = st.selectbox("Select Prompt Version", ["TestTakersSummary", "ManagersSummary"]) |
|
|
|
|
|
|
|
if st.button(f'Analyze Profile ({st.session_state["version"]})'): |
|
|
|
prompt = generate_prompt_from_profile(profile, version=st.session_state['version']) |
|
|
|
with st.chat_message("assistant"): |
|
stream = client.chat.completions.create( |
|
model="personality_gpt4o", |
|
temperature=st.session_state['temperature'], |
|
max_tokens=4096, |
|
frequency_penalty=0.2, |
|
presence_penalty=0.2, |
|
messages=prompt, |
|
stream=True) |
|
|
|
response = st.write_stream(stream) |
|
|
|
|
|
st.session_state['analysis'] = response |
|
st.session_state['show_chat'] = True |
|
|
|
st.rerun() |
|
|
|
|
|
if st.session_state['analysis']: |
|
|
|
feedback = st.text_input("Provide your feedback on the response:") |
|
rating = st.slider("Rate the response:", 0, 10, 5) |
|
|
|
if st.sidebar.button('Submit Feedback'): |
|
store_feedback(str(prompt), response, feedback, rating, "wu981526092/feedback_report") |
|
|
|
st.markdown(st.session_state['analysis']) |
|
|
|
else: |
|
st.write("Please upload a profile JSON file or use the example profile.") |
|
|
|
|
|
|
|
def verify_credentials(): |
|
if st.session_state['username'] == os.getenv("username_app") and st.session_state['password'] == os.getenv( |
|
"password_app"): |
|
st.session_state['authenticated'] = True |
|
else: |
|
st.error("Invalid username or password") |
|
|
|
|
|
|
|
def login_page(): |
|
st.title("Welcome to Metaprofiling's Career Insight Analyzer Demo") |
|
st.write( |
|
"This application provides in-depth analysis and insights into professional profiles. Please log in to continue.") |
|
|
|
|
|
st.markdown(""" |
|
## How to Use This Application |
|
- Enter your username and password in the sidebar. |
|
- Click on 'Login' to access the application. |
|
- Once logged in, you will be able to upload and analyze professional profiles. |
|
""") |
|
|
|
st.sidebar.write("Login:") |
|
username = st.sidebar.text_input("Username") |
|
password = st.sidebar.text_input("Password", type="password") |
|
|
|
st.session_state['username'] = username |
|
st.session_state['password'] = password |
|
st.sidebar.button("Login", on_click=verify_credentials) |
|
|
|
|
|
def sidebar_components(): |
|
with st.sidebar: |
|
if st.button('Reset'): |
|
st.session_state['profile'] = None |
|
st.session_state['show_chat'] = None |
|
st.session_state['analysis'] = None |
|
st.rerun() |
|
|
|
if not st.session_state['show_chat']: |
|
|
|
st.markdown("### JSON File Requirements:") |
|
st.markdown("1. Must contain 'bio_information', 'main_profile', and 'red_flag' as top-level keys.") |
|
st.markdown("2. Both keys should have dictionary values.") |
|
|
|
st.markdown("### Choose the Definition:") |
|
st.session_state['definition'] = st.selectbox("Select Definition", [1, 2]) |
|
st.session_state['chat_context'] = st.selectbox("Select Chat Context", ["analysis", "profile"]) |
|
|
|
|
|
st.markdown("### Upload a profile JSON file") |
|
uploaded_file = st.file_uploader("", type=['json']) |
|
|
|
if uploaded_file is not None: |
|
try: |
|
profile_data = json.load(uploaded_file) |
|
valid, message = validate_json(profile_data) |
|
if valid: |
|
st.session_state['profile'] = profile_data |
|
|
|
else: |
|
st.error(message) |
|
except json.JSONDecodeError: |
|
st.error("Invalid JSON file. Please upload a valid JSON file.") |
|
|
|
|
|
if st.button('Use Example Profile'): |
|
if st.session_state['definition'] == 1: |
|
file_name = "example_data_definition_1.json" |
|
else: |
|
file_name = "example_data_definition_2.json" |
|
|
|
with open(file_name, 'r') as file: |
|
st.session_state['profile'] = json.load(file) |
|
|
|
|
|
|
|
else: |
|
st.sidebar.title("Chat with Our Career Advisor") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
question_templates = [ |
|
"What are the main risks associated with {}’s profile?", |
|
"What are the implications of {}’s profile for working with others?", |
|
|
|
|
|
|
|
|
|
|
|
|
|
] |
|
|
|
|
|
questions_list = [question.format("Test Taker") for question in question_templates] |
|
|
|
|
|
questions_markdown = "\n\n".join( |
|
[f"Q{index + 1}: {question}" for index, question in enumerate(questions_list)]) |
|
|
|
|
|
st.sidebar.markdown("### Suggest Questions") |
|
st.sidebar.markdown(questions_markdown) |
|
|
|
|
|
|
|
user_input = st.sidebar.text_input("Ask a question about the profile analysis:") |
|
|
|
llm, embed_model = create_models() |
|
configure_settings(llm, embed_model) |
|
index = load_documents_and_create_index() |
|
|
|
if st.sidebar.button('Submit'): |
|
if user_input: |
|
if st.session_state['chat_context'] == "profile": |
|
chat_prompt_template = create_chat_prompt_template(get_profile_str(st.session_state['profile']),st.session_state['definition']) |
|
else: |
|
chat_prompt_template = create_chat_prompt_template(st.session_state['analysis'],st.session_state['definition']) |
|
response = execute_query(index, chat_prompt_template, user_input) |
|
|
|
|
|
st.sidebar.markdown(response) |
|
|
|
|
|
feedback = st.sidebar.text_input("Provide your feedback on the response:") |
|
rating = st.sidebar.slider("Rate the response:", 0, 10, 5) |
|
|
|
if st.sidebar.button('Submit Feedback'): |
|
store_feedback(user_input, response, feedback, rating, "wu981526092/feedback_report") |
|
st.sidebar.success("Feedback submitted successfully!") |
|
|
|
|
|
|
|
|
|
session_defaults = { |
|
'show_chat': None, |
|
'definition': 1, |
|
'chat_context': "analysis", |
|
'profile': None, |
|
'analysis': None, |
|
'temperature': 0, |
|
'version': "", |
|
'username': '', |
|
'password': '', |
|
'authenticated': False |
|
} |
|
|
|
for key, default in session_defaults.items(): |
|
if key not in st.session_state: |
|
st.session_state[key] = default |
|
|
|
|
|
if st.session_state['authenticated']: |
|
main_app() |
|
else: |
|
login_page() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|