302 lines
11 KiB
Plaintext
302 lines
11 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 91,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import requests\n",
|
|
"import os\n",
|
|
"import streamlit as st\n",
|
|
"from dotenv import load_dotenv\n",
|
|
"from settings import load_settings\n",
|
|
"from utils import construct_prompt\n",
|
|
"import json"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 92,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Load API key from .env file\n",
|
|
"load_dotenv()\n",
|
|
"api_key = os.getenv(\"OPENAI_API_KEY\")\n",
|
|
"\n",
|
|
"if not api_key:\n",
|
|
" st.error(\"API key not found. Please set OPENAI_API_KEY in your .env file.\")\n",
|
|
" st.stop()\n",
|
|
"\n",
|
|
"api_url = \"https://genai.dev.odp.lhgroup.de/openai/deployments/gpt-4-turbo/chat/completions?api-version=2023-07-01-preview\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 93,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"system_prompt = \"\"\"\n",
|
|
"You are an OKR coach who helps beginners create well-phrased OKRs (Objectives and Key Results). \n",
|
|
"Your goal is to provide a proposal for an OKR based on user input, formatted as JSON. \n",
|
|
"If the input is unclear or incomplete, include a hint with specific questions or suggestions \n",
|
|
"to help improve the input.\n",
|
|
"\n",
|
|
"Always follow this format for your response:\n",
|
|
"{\n",
|
|
" \"hint\": \"Suggestions or questions to improve the input, if needed. If no hint is needed, return an empty string.\",\n",
|
|
" \"proposal\": [\n",
|
|
" {\n",
|
|
" \"objective\": \"A clear and concise objective variant\",\n",
|
|
" \"key_results\": [\"Key result 1\", \"Key result 2\", \"... up to 5 key results\"]\n",
|
|
" },\n",
|
|
" ...\n",
|
|
" ]\n",
|
|
"}\n",
|
|
"\n",
|
|
"Keep your responses concise, actionable, and aligned with OKR best practices. If you need more context from the user, ask for it in the `hint`.\n",
|
|
"Always provide a 'hint' how to further improve the user input in order to get better results.\n",
|
|
"\n",
|
|
"\"\"\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 94,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Prompt template for user input\n",
|
|
"prompt_template = \"\"\"\n",
|
|
"Please help us in defining proper OKRs.\n",
|
|
"Here is what we have thought about and we would like to phrase an OKR with maximum 5 key results.\n",
|
|
"\n",
|
|
"this is the user input:\n",
|
|
"{user_input}\n",
|
|
"\n",
|
|
"Please provide the response in json format. \n",
|
|
"\"\"\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 95,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"input_template = \"\"\"\n",
|
|
"We want to improve our SLA framework by finalizing the current SLA template, which is used for the negotiations with our ground service partners.\n",
|
|
"The resulting SLA will be used in order to measure the quality of the service partner and issue penalties if targets are not met. \n",
|
|
"We would like to improve this, to have a better steering function, e.g. by adding a bonus component to the SLA framework.\n",
|
|
"\n",
|
|
"To achieve this, we need to develop a bonus concept which is viable, feasible and desirable. \n",
|
|
"We need to simulate the concept, so that we don't risk issuing too much bonus which we cannot cover.\n",
|
|
"We need to define organizational processes and responsibilities so that we are able to pay a bonus.\n",
|
|
"\n",
|
|
"How should the OKR look like for the next cycle which starts in Jan 2025 and ends in Apr 2025?\n",
|
|
"We would like to phrase 4 key results.\n",
|
|
"\"\"\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 96,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def fetch_okrs(user_input: str, system_prompt: str, prompt_template: str):\n",
|
|
" #settings = load_settings()\n",
|
|
" \n",
|
|
" #system_prompt = settings[\"system_prompt\"]\n",
|
|
" #input_template = settings[\"input_template\"]\n",
|
|
"\n",
|
|
" user_prompt = construct_prompt(prompt_template=prompt_template, user_input=user_input)\n",
|
|
" \n",
|
|
" print(user_prompt)\n",
|
|
" headers = {\"api-key\": api_key, \"Content-Type\": \"application/json\"}\n",
|
|
" body = {\n",
|
|
" \"messages\": [\n",
|
|
" {\"role\": \"system\", \"content\": system_prompt},\n",
|
|
" {\"role\": \"user\", \"content\": user_prompt}\n",
|
|
" ]\n",
|
|
" }\n",
|
|
" try:\n",
|
|
" response = requests.post(url=api_url, headers=headers, json=body)\n",
|
|
" response.raise_for_status()\n",
|
|
" return response.json()\n",
|
|
" except Exception as e:\n",
|
|
" st.error(f\"Error fetching data from API: {e}\")\n",
|
|
" return None\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 97,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def parse_json_content(cleaned_content: str):\n",
|
|
" \"\"\"\n",
|
|
" Parses the cleaned content to extract valid JSON data.\n",
|
|
"\n",
|
|
" Args:\n",
|
|
" cleaned_content (str): The raw content containing JSON data.\n",
|
|
"\n",
|
|
" Returns:\n",
|
|
" dict or list: The parsed JSON object.\n",
|
|
" \"\"\"\n",
|
|
" import re\n",
|
|
"\n",
|
|
" # Step 1: Strip unwanted characters and clean the content\n",
|
|
" cleaned_content = cleaned_content.strip()\n",
|
|
"\n",
|
|
" # Step 2: Use regex to extract only the valid JSON block (e.g., starts with [ or {)\n",
|
|
" json_match = re.search(r\"(\\{.*\\}|\\[.*\\])\", cleaned_content, re.DOTALL)\n",
|
|
" \n",
|
|
" if not json_match:\n",
|
|
" raise ValueError(\"No valid JSON found in the content.\")\n",
|
|
"\n",
|
|
" # Step 3: Extract and parse the valid JSON\n",
|
|
" valid_json = json_match.group(0) # Extract matched JSON block\n",
|
|
" try:\n",
|
|
" extracted_data = json.loads(valid_json)\n",
|
|
" except json.JSONDecodeError as e:\n",
|
|
" raise ValueError(f\"Failed to decode JSON. Error: {e}\\nContent:\\n{valid_json}\")\n",
|
|
"\n",
|
|
" return extracted_data\n",
|
|
"\n",
|
|
"# Function to extract and parse JSON response\n",
|
|
"def extract_llm_response(response):\n",
|
|
" \"\"\"\n",
|
|
" Extracts and parses the JSON response from the API.\n",
|
|
"\n",
|
|
" Args:\n",
|
|
" response (dict): The API response containing a hint and proposals.\n",
|
|
"\n",
|
|
" Returns:\n",
|
|
" tuple: A tuple containing the objective (str), key results (list), and hint (str).\n",
|
|
" \"\"\"\n",
|
|
" #print(\"RESPONSE:\",response)\n",
|
|
"\n",
|
|
" raw_message_content = response[\"choices\"][0][\"message\"][\"content\"]\n",
|
|
" #print(\"raw_message_content:\", raw_message_content)\n",
|
|
" # Clean and parse the JSON content\n",
|
|
" cleaned_content = raw_message_content.replace(\"`\", \"\").split(\"json\")[-1]\n",
|
|
" #print(\"cleaned content\", cleaned_content)\n",
|
|
"\n",
|
|
" parsed_data = parse_json_content(cleaned_content=cleaned_content)\n",
|
|
" #print(\"parsed_data:\",parsed_data)\n",
|
|
"\n",
|
|
" hint = parsed_data.get(\"hint\", \"\")\n",
|
|
"\n",
|
|
" proposals = parsed_data.get(\"proposal\", [])\n",
|
|
"\n",
|
|
" if proposals:\n",
|
|
" # Extract the first proposal's objective and key results\n",
|
|
" first_proposal = proposals[0] # Get the first proposal (assuming it's a list)\n",
|
|
" objective = first_proposal.get(\"objective\", \"\")\n",
|
|
" key_results = first_proposal.get(\"key_results\", [])\n",
|
|
" else:\n",
|
|
" objective = \"\"\n",
|
|
" key_results = []\n",
|
|
"\n",
|
|
" #print(\"debug:\", parsed_data.get(\"objective\", \"\"))\n",
|
|
"\n",
|
|
" return objective, key_results, hint"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 98,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"Please help us in defining proper OKRs.\n",
|
|
"Here is what we have thought about and we would like to phrase an OKR with maximum 5 key results.\n",
|
|
"\n",
|
|
"this is the user input:\n",
|
|
"\n",
|
|
"We want to improve our SLA framework by finalizing the current SLA template, which is used for the negotiations with our ground service partners.\n",
|
|
"The resulting SLA will be used in order to measure the quality of the service partner and issue penalties if targets are not met. \n",
|
|
"We would like to improve this, to have a better steering function, e.g. by adding a bonus component to the SLA framework.\n",
|
|
"\n",
|
|
"To achieve this, we need to develop a bonus concept which is viable, feasible and desirable. \n",
|
|
"We need to simulate the concept, so that we don't risk issuing too much bonus which we cannot cover.\n",
|
|
"We need to define organizational processes and responsibilities so that we are able to pay a bonus.\n",
|
|
"\n",
|
|
"How should the OKR look like for the next cycle which starts in Jan 2025 and ends in Apr 2025?\n",
|
|
"We would like to phrase 4 key results.\n",
|
|
"\n",
|
|
"\n",
|
|
"Please provide the response in json format. \n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"\n",
|
|
"from config import INPUT_TEMPLATE, PROMPT_TEMPLATE\n",
|
|
"result = fetch_okrs(user_input=input_template, system_prompt=system_prompt, prompt_template=prompt_template)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 99,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"objective, key_results, hint = extract_llm_response(response=result)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 100,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Enhance the SLA framework to better incentivize ground service partners by April 2025\n",
|
|
"4 ['Finalize the updated SLA template with bonus components for better partner performance by February 2025', 'Develop a well-defined bonus concept that is viable, feasible, and desirable by March 2025', 'Simulate the bonus payout scenarios to ensure financial sustainability by end of March 2025', 'Establish clear organizational processes and assign responsibilities for bonus distribution by April 2025']\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"print(objective)\n",
|
|
"print(len(key_results), key_results)\n",
|
|
"print(hint)"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "venv",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.9.6"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|