initial version
This commit is contained in:
commit
bc2e200a2b
5
.idea/.gitignore
generated
vendored
Normal file
5
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.vscode/
|
||||||
|
.env
|
||||||
|
venv/
|
||||||
10
.idea/OKR_Proposer.iml
generated
Normal file
10
.idea/OKR_Proposer.iml
generated
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
4
.idea/misc.xml
generated
Normal file
4
.idea/misc.xml
generated
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (OKR_Proposer)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/OKR_Proposer.iml" filepath="$PROJECT_DIR$/.idea/OKR_Proposer.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
69
.idea/workspace.xml
generated
Normal file
69
.idea/workspace.xml
generated
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="318c72a5-e9ec-4dd0-ac1a-cb0b5e2a86c2" name="Changes" comment="" />
|
||||||
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
|
</component>
|
||||||
|
<component name="FileTemplateManagerImpl">
|
||||||
|
<option name="RECENT_TEMPLATES">
|
||||||
|
<list>
|
||||||
|
<option value="Python Script" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="MarkdownSettingsMigration">
|
||||||
|
<option name="stateVersion" value="1" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectId" id="2qwhdtwwl3dnedx4FlvRdDYZobj" />
|
||||||
|
<component name="ProjectViewState">
|
||||||
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
|
<option name="showLibraryContents" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent">
|
||||||
|
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
||||||
|
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||||
|
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
<component name="RecentsManager">
|
||||||
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
|
<recent name="$PROJECT_DIR$" />
|
||||||
|
</key>
|
||||||
|
</component>
|
||||||
|
<component name="RunManager">
|
||||||
|
<configuration name="main" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
|
||||||
|
<module name="OKR_Proposer" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<envs>
|
||||||
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
|
</envs>
|
||||||
|
<option name="SDK_HOME" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||||
|
<option name="IS_MODULE_SDK" value="true" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/main.py" />
|
||||||
|
<option name="PARAMETERS" value="" />
|
||||||
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
|
<option name="EMULATE_TERMINAL" value="false" />
|
||||||
|
<option name="MODULE_MODE" value="false" />
|
||||||
|
<option name="REDIRECT_INPUT" value="false" />
|
||||||
|
<option name="INPUT_FILE" value="" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
|
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||||
|
<component name="TaskManager">
|
||||||
|
<task active="true" id="Default" summary="Default task">
|
||||||
|
<changelist id="318c72a5-e9ec-4dd0-ac1a-cb0b5e2a86c2" name="Changes" comment="" />
|
||||||
|
<created>1735579636156</created>
|
||||||
|
<option name="number" value="Default" />
|
||||||
|
<option name="presentableId" value="Default" />
|
||||||
|
<updated>1735579636156</updated>
|
||||||
|
</task>
|
||||||
|
<servers />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
7
.vscode/launch.json
vendored
Normal file
7
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": []
|
||||||
|
}
|
||||||
39
api.py
Normal file
39
api.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import requests
|
||||||
|
import os
|
||||||
|
import streamlit as st
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from settings import load_settings
|
||||||
|
from utils import construct_prompt
|
||||||
|
|
||||||
|
# Load API key from .env file
|
||||||
|
load_dotenv()
|
||||||
|
api_key = os.getenv("OPENAI_API_KEY")
|
||||||
|
|
||||||
|
if not api_key:
|
||||||
|
st.error("API key not found. Please set OPENAI_API_KEY in your .env file.")
|
||||||
|
st.stop()
|
||||||
|
|
||||||
|
api_url = "https://genai.dev.odp.lhgroup.de/openai/deployments/gpt-4-turbo/chat/completions?api-version=2023-07-01-preview"
|
||||||
|
|
||||||
|
def fetch_okrs(user_input: str):
|
||||||
|
settings = load_settings()
|
||||||
|
|
||||||
|
system_prompt = settings["system_prompt"]
|
||||||
|
input_template = settings["input_template"]
|
||||||
|
|
||||||
|
user_prompt = construct_prompt(prompt_template=input_template, user_input=user_input)
|
||||||
|
|
||||||
|
headers = {"api-key": api_key, "Content-Type": "application/json"}
|
||||||
|
body = {
|
||||||
|
"messages": [
|
||||||
|
{"role": "system", "content": system_prompt},
|
||||||
|
{"role": "user", "content": user_prompt}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
response = requests.post(url=api_url, headers=headers, json=body)
|
||||||
|
response.raise_for_status()
|
||||||
|
return response.json()
|
||||||
|
except Exception as e:
|
||||||
|
st.error(f"Error fetching data from API: {e}")
|
||||||
|
return None
|
||||||
135
app.py
Normal file
135
app.py
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import streamlit as st
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
from styles import apply_styles
|
||||||
|
|
||||||
|
from streamlit_option_menu import option_menu
|
||||||
|
|
||||||
|
# Import other pages or modules
|
||||||
|
from settings import settings_page, load_settings
|
||||||
|
from proposer import proposer_page
|
||||||
|
|
||||||
|
apply_styles()
|
||||||
|
#proposer_page()
|
||||||
|
|
||||||
|
|
||||||
|
# Navigation Menu
|
||||||
|
selected = option_menu(
|
||||||
|
menu_title="Main Menu",
|
||||||
|
options=["Home", "Settings"],
|
||||||
|
icons=["house", "gear"],
|
||||||
|
menu_icon="cast",
|
||||||
|
default_index=0,
|
||||||
|
orientation="horizontal",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Render pages based on selection
|
||||||
|
if selected == "Home":
|
||||||
|
# Home page logic goes here (e.g., OKR generator)
|
||||||
|
#from utils import construct_prompt # Example import; replace with actual logic.
|
||||||
|
|
||||||
|
proposer_page()
|
||||||
|
|
||||||
|
elif selected == "Settings":
|
||||||
|
settings_page()
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Streamlit App Layout
|
||||||
|
st.title("OKR Generator")
|
||||||
|
|
||||||
|
# Input Section and Buttons Row
|
||||||
|
st.subheader("Enter your idea or goal:")
|
||||||
|
user_input = st.text_area(
|
||||||
|
"Input your idea here:",
|
||||||
|
value=st.session_state.get("user_input", INPUT_TEMPLATE.strip()),
|
||||||
|
height=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
col1, col2 = st.columns([1, 1])
|
||||||
|
with col1:
|
||||||
|
if st.button("Reset All"):
|
||||||
|
st.session_state.clear()
|
||||||
|
with col2:
|
||||||
|
generate_okrs_clicked = st.button("Generate OKRs")
|
||||||
|
|
||||||
|
if generate_okrs_clicked:
|
||||||
|
if not user_input.strip():
|
||||||
|
st.warning("Please provide some input before generating OKRs.")
|
||||||
|
else:
|
||||||
|
with st.spinner("Generating OKRs..."):
|
||||||
|
# Construct prompt and call API
|
||||||
|
prompt = construct_prompt(prompt_template=PROMPT_TEMPLATE, user_input=user_input)
|
||||||
|
response = fetch_okrs(user_prompt=prompt, system_prompt=SYSTEM_PROMPT)
|
||||||
|
if response:
|
||||||
|
# Extract Objective and Key Results from response
|
||||||
|
objective, key_results = extract_llm_response(response)
|
||||||
|
st.session_state["objective"] = objective
|
||||||
|
st.session_state["key_results"] = key_results
|
||||||
|
|
||||||
|
# Display Results Only if an OKR Has Been Generated
|
||||||
|
if "objective" in st.session_state and "key_results" in st.session_state:
|
||||||
|
# Display Objective Field with Responsibles Input Below It
|
||||||
|
st.subheader("Proposal Objective:")
|
||||||
|
objective_text = st.text_area(
|
||||||
|
"Proposal Objective:",
|
||||||
|
value=st.session_state.get("objective", ""),
|
||||||
|
height=100,
|
||||||
|
)
|
||||||
|
|
||||||
|
responsible_for_objective = st.text_input(
|
||||||
|
"Responsibles for Objective (comma-separated):",
|
||||||
|
value="",
|
||||||
|
placeholder="e.g., Khanh Dinh, John Doe",
|
||||||
|
key="responsibles_objective"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Display Key Results with Responsibles Below Each One
|
||||||
|
st.subheader("Proposal Key Results:")
|
||||||
|
key_result_boxes = []
|
||||||
|
responsibles_for_key_results = []
|
||||||
|
|
||||||
|
for i, kr in enumerate(st.session_state["key_results"], start=1):
|
||||||
|
kr_text = st.text_area(f"Key Result {i}:", value=kr, key=f"kr_{i}")
|
||||||
|
responsible_for_kr = st.text_input(
|
||||||
|
f"Responsibles for Key Result {i} (comma-separated):",
|
||||||
|
value="",
|
||||||
|
placeholder="e.g., Khanh Dinh",
|
||||||
|
key=f"responsibles_kr_{i}"
|
||||||
|
)
|
||||||
|
|
||||||
|
key_result_boxes.append(kr_text)
|
||||||
|
responsibles_for_key_results.append(responsible_for_kr)
|
||||||
|
|
||||||
|
# Finalize Button Center-Aligned
|
||||||
|
#finalize_col = st.columns([3, 2, 3])[1]
|
||||||
|
#with finalize_col:
|
||||||
|
if st.button("Finalize"):
|
||||||
|
finalized_objective = objective_text.strip()
|
||||||
|
finalized_key_results = [st.session_state[f"kr_{i+1}"].strip() for i in range(len(key_result_boxes))]
|
||||||
|
|
||||||
|
# Append initials of responsibles to Objective and Key Results
|
||||||
|
responsibles_list_objective = [name.strip() for name in responsible_for_objective.split(",") if name.strip()]
|
||||||
|
initials_objective = [f"[{''.join([part[0] for part in name.split()]).upper()}]" for name in responsibles_list_objective]
|
||||||
|
initials_str_objective = ", ".join(initials_objective)
|
||||||
|
|
||||||
|
finalized_objective += f" [{initials_str_objective}]"
|
||||||
|
|
||||||
|
finalized_key_results_with_initials = []
|
||||||
|
for i, kr in enumerate(finalized_key_results):
|
||||||
|
responsibles_list_kr = [name.strip() for name in responsibles_for_key_results[i].split(",") if name.strip()]
|
||||||
|
initials_kr = [f"{''.join([part[0] for part in name.split()]).upper()}" for name in responsibles_list_kr]
|
||||||
|
initials_str_kr = ", ".join(initials_kr)
|
||||||
|
finalized_key_results_with_initials.append(f"KR{i+1}: [{initials_str_kr}] {kr}")
|
||||||
|
|
||||||
|
# Display finalized data in non-editable format (full width)
|
||||||
|
st.subheader("Finalized Objective:")
|
||||||
|
st.write(finalized_objective)
|
||||||
|
|
||||||
|
st.subheader("Finalized Key Results:")
|
||||||
|
for kr in finalized_key_results_with_initials:
|
||||||
|
st.write(kr)'''
|
||||||
58
config.py
Normal file
58
config.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
SYSTEM_PROMPT = """
|
||||||
|
You are an OKR coach and support us, as beginners in OKRs, with the correct phrasing of OKRs.
|
||||||
|
Always one proposal and provide the proposal in the requested format (json).
|
||||||
|
If you think the input is not clear enough and the OKR could be improved, then provide a hint,
|
||||||
|
what could be added to the user input in order to provide improved OKRs. The hint should also
|
||||||
|
always provided within the json.
|
||||||
|
|
||||||
|
Format could look like this:
|
||||||
|
{
|
||||||
|
"hint": "any additional questions, which can be added to the user input to rerun the prompting",
|
||||||
|
"proposals": [
|
||||||
|
{
|
||||||
|
"objective":"objective variant 1",
|
||||||
|
"key_results": ["key result 1"]
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
INPUT_TEMPLATE = """
|
||||||
|
We want to improve our SLA framework by finalizing the current SLA template, which is used for the negotiations with our ground service partners.
|
||||||
|
The resulting SLA will be used in order to measure the quality of the service partner and issue penalties if targets are not met.
|
||||||
|
We would like to improve this, to have a better steering function, e.g. by adding a bonus component to the SLA framework.
|
||||||
|
|
||||||
|
To achieve this, we need to develop a bonus concept which is viable, feasible and desirable.
|
||||||
|
We need to simulate the concept, so that we don't risk issuing too much bonus which we cannot cover.
|
||||||
|
We need to define organizational processes and responsibilities so that we are able to pay a bonus.
|
||||||
|
|
||||||
|
How should the OKR look like for the next cycle which starts in Jan 2025 and ends in Apr 2025?
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Prompt template for user input
|
||||||
|
PROMPT_TEMPLATE = """
|
||||||
|
Please help us in defining proper OKRs.
|
||||||
|
Here is what we have thought about and we would like to phrase an OKR with up to 5 key results.
|
||||||
|
|
||||||
|
this is the user input:
|
||||||
|
{user_input}
|
||||||
|
|
||||||
|
Please provide the response in json format.
|
||||||
|
the three proposals and potentially further questions to the user to improve the OKR, should be structured in a json as response.
|
||||||
|
Objective (key: objective)
|
||||||
|
key results (list with the key results)
|
||||||
|
The json could be structured like this:
|
||||||
|
|
||||||
|
{
|
||||||
|
"hint": "any additional questions, which can be added to the user input to rerun the prompting",
|
||||||
|
"proposals": [
|
||||||
|
{
|
||||||
|
"objective":"objective variant 1",
|
||||||
|
"key_result_1":"key result 1",
|
||||||
|
...
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""
|
||||||
42
main.py
Normal file
42
main.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import streamlit as st
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from api import fetch_okrs
|
||||||
|
from utils import construct_prompt, extract_llm_response
|
||||||
|
from styles import apply_styles
|
||||||
|
from config import SYSTEM_PROMPT, INPUT_TEMPLATE
|
||||||
|
|
||||||
|
# Load environment variables
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
# Apply custom styles
|
||||||
|
apply_styles()
|
||||||
|
|
||||||
|
# Streamlit App Layout
|
||||||
|
st.title("OKR Generator")
|
||||||
|
st.subheader("Enter your idea or goal:")
|
||||||
|
|
||||||
|
user_input = st.text_area(
|
||||||
|
"Input your idea here:",
|
||||||
|
value=st.session_state.get("user_input", INPUT_TEMPLATE.strip()),
|
||||||
|
height=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
if st.button("Generate OKRs"):
|
||||||
|
if not user_input.strip():
|
||||||
|
st.warning("Please provide some input before generating OKRs.")
|
||||||
|
else:
|
||||||
|
with st.spinner("Generating OKRs..."):
|
||||||
|
prompt = construct_prompt(user_input)
|
||||||
|
response = fetch_okrs(prompt=prompt, system_prompt=SYSTEM_PROMPT)
|
||||||
|
if response:
|
||||||
|
objective, key_results = extract_llm_response(response)
|
||||||
|
st.session_state["objective"] = objective
|
||||||
|
st.session_state["key_results"] = key_results
|
||||||
|
|
||||||
|
if "objective" in st.session_state:
|
||||||
|
st.subheader("Proposal Objective:")
|
||||||
|
st.write(st.session_state["objective"])
|
||||||
|
|
||||||
|
st.subheader("Proposal Key Results:")
|
||||||
|
for kr in st.session_state["key_results"]:
|
||||||
|
st.write(kr)
|
||||||
116
proposer.py
Normal file
116
proposer.py
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import streamlit as st
|
||||||
|
|
||||||
|
from api import fetch_okrs
|
||||||
|
from config import SYSTEM_PROMPT, INPUT_TEMPLATE, PROMPT_TEMPLATE
|
||||||
|
from utils import construct_prompt, extract_llm_response
|
||||||
|
|
||||||
|
def proposer_page():
|
||||||
|
# Streamlit App Layout
|
||||||
|
st.title("OKR Generator")
|
||||||
|
|
||||||
|
# Input Section and Buttons Row
|
||||||
|
st.subheader("Enter your idea or goal:")
|
||||||
|
user_input = st.text_area(
|
||||||
|
"Input your idea here:",
|
||||||
|
value=st.session_state.get("user_input", INPUT_TEMPLATE.strip()),
|
||||||
|
height=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
col1, col2 = st.columns([1, 1])
|
||||||
|
with col1:
|
||||||
|
if st.button("Reset All"):
|
||||||
|
st.session_state.clear()
|
||||||
|
with col2:
|
||||||
|
generate_okrs_clicked = st.button("Generate OKRs")
|
||||||
|
|
||||||
|
if generate_okrs_clicked:
|
||||||
|
if not user_input.strip():
|
||||||
|
st.warning("Please provide some input before generating OKRs.")
|
||||||
|
else:
|
||||||
|
with st.spinner("Generating OKRs..."):
|
||||||
|
# Construct prompt and call API
|
||||||
|
#prompt = construct_prompt(prompt_template=PROMPT_TEMPLATE, user_input=user_input)
|
||||||
|
response = fetch_okrs(user_input=user_input)
|
||||||
|
if response:
|
||||||
|
# Extract Objective and Key Results from response
|
||||||
|
print(response)
|
||||||
|
objective, key_results, hint = extract_llm_response(response)
|
||||||
|
|
||||||
|
st.session_state["objective"] = objective
|
||||||
|
st.session_state["key_results"] = key_results
|
||||||
|
st.session_state["hint"] = hint
|
||||||
|
|
||||||
|
#st.subheader("Hint to improve the OKR proposal")
|
||||||
|
#st.text(hint)
|
||||||
|
|
||||||
|
# Display Results Only if an OKR Has Been Generated
|
||||||
|
if "objective" in st.session_state and "key_results" in st.session_state:
|
||||||
|
|
||||||
|
# Display Objective Field with Responsibles Input Below It
|
||||||
|
st.subheader("Proposal Objective:")
|
||||||
|
objective_text = st.text_area(
|
||||||
|
"Proposal Objective:",
|
||||||
|
value=st.session_state.get("objective", ""),
|
||||||
|
height=100,
|
||||||
|
)
|
||||||
|
|
||||||
|
responsible_for_objective = st.text_input(
|
||||||
|
"Responsibles for Objective (comma-separated):",
|
||||||
|
value="",
|
||||||
|
placeholder="e.g., Khanh Dinh, John Doe",
|
||||||
|
key="responsibles_objective"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Display Key Results with Responsibles Below Each One
|
||||||
|
st.subheader("Proposal Key Results:")
|
||||||
|
key_result_boxes = []
|
||||||
|
responsibles_for_key_results = []
|
||||||
|
|
||||||
|
for i, kr in enumerate(st.session_state["key_results"], start=1):
|
||||||
|
kr_text = st.text_area(f"Key Result {i}:", value=kr, key=f"kr_{i}")
|
||||||
|
responsible_for_kr = st.text_input(
|
||||||
|
f"Responsibles for Key Result {i} (comma-separated):",
|
||||||
|
value="",
|
||||||
|
placeholder="e.g., Khanh Dinh",
|
||||||
|
key=f"responsibles_kr_{i}"
|
||||||
|
)
|
||||||
|
|
||||||
|
key_result_boxes.append(kr_text)
|
||||||
|
responsibles_for_key_results.append(responsible_for_kr)
|
||||||
|
|
||||||
|
# Finalize Button Center-Aligned
|
||||||
|
#finalize_col = st.columns([3, 2, 3])[1]
|
||||||
|
#with finalize_col:
|
||||||
|
if st.button("Finalize"):
|
||||||
|
finalized_objective = objective_text.strip()
|
||||||
|
finalized_key_results = [st.session_state[f"kr_{i+1}"].strip() for i in range(len(key_result_boxes))]
|
||||||
|
|
||||||
|
# Append initials of responsibles to Objective and Key Results
|
||||||
|
responsibles_list_objective = [name.strip() for name in responsible_for_objective.split(",") if name.strip()]
|
||||||
|
initials_objective = [f"[{''.join([part[0] for part in name.split()]).upper()}]" for name in responsibles_list_objective]
|
||||||
|
initials_str_objective = ", ".join(initials_objective)
|
||||||
|
|
||||||
|
finalized_objective = f"{initials_str_objective} {finalized_objective}"
|
||||||
|
|
||||||
|
finalized_key_results_with_initials = []
|
||||||
|
for i, kr in enumerate(finalized_key_results):
|
||||||
|
responsibles_list_kr = [name.strip() for name in responsibles_for_key_results[i].split(",") if name.strip()]
|
||||||
|
initials_kr = [f"{''.join([part[0] for part in name.split()]).upper()}" for name in responsibles_list_kr]
|
||||||
|
initials_str_kr = ", ".join(initials_kr)
|
||||||
|
finalized_key_results_with_initials.append(f"KR{i+1}: [{initials_str_kr}] {kr}")
|
||||||
|
|
||||||
|
# Display finalized data in non-editable format (full width)
|
||||||
|
st.subheader("Finalized Objective:")
|
||||||
|
st.code(
|
||||||
|
body=finalized_objective,
|
||||||
|
language=None,
|
||||||
|
wrap_lines=True
|
||||||
|
)
|
||||||
|
|
||||||
|
st.subheader("Finalized Key Results:")
|
||||||
|
for kr in finalized_key_results_with_initials:
|
||||||
|
st.code(
|
||||||
|
body=kr,
|
||||||
|
language=None,
|
||||||
|
wrap_lines=True
|
||||||
|
)
|
||||||
74
requirements.txt
Normal file
74
requirements.txt
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
altair==5.5.0
|
||||||
|
appnope==0.1.4
|
||||||
|
asttokens==3.0.0
|
||||||
|
attrs==24.3.0
|
||||||
|
blinker==1.9.0
|
||||||
|
cachetools==5.5.0
|
||||||
|
certifi==2024.12.14
|
||||||
|
charset-normalizer==3.4.1
|
||||||
|
click==8.1.8
|
||||||
|
comm==0.2.2
|
||||||
|
cramjam==2.9.1
|
||||||
|
debugpy==1.8.11
|
||||||
|
decorator==5.1.1
|
||||||
|
et-xmlfile==2.0.0
|
||||||
|
exceptiongroup==1.2.2
|
||||||
|
executing==2.1.0
|
||||||
|
fastparquet==2024.11.0
|
||||||
|
fsspec==2024.12.0
|
||||||
|
gitdb==4.0.11
|
||||||
|
GitPython==3.1.43
|
||||||
|
idna==3.10
|
||||||
|
importlib-metadata==8.5.0
|
||||||
|
ipykernel==6.29.5
|
||||||
|
ipython==8.18.1
|
||||||
|
jedi==0.19.2
|
||||||
|
jinja2==3.1.5
|
||||||
|
jsonschema==4.23.0
|
||||||
|
jsonschema-specifications==2024.10.1
|
||||||
|
jupyter-client==8.6.3
|
||||||
|
jupyter-core==5.7.2
|
||||||
|
markdown-it-py==3.0.0
|
||||||
|
MarkupSafe==3.0.2
|
||||||
|
matplotlib-inline==0.1.7
|
||||||
|
mdurl==0.1.2
|
||||||
|
narwhals==1.20.1
|
||||||
|
nest-asyncio==1.6.0
|
||||||
|
numpy==2.0.2
|
||||||
|
openpyxl==3.1.5
|
||||||
|
packaging==24.2
|
||||||
|
pandas==2.2.3
|
||||||
|
parso==0.8.4
|
||||||
|
pexpect==4.9.0
|
||||||
|
pillow==11.0.0
|
||||||
|
platformdirs==4.3.6
|
||||||
|
prompt-toolkit==3.0.48
|
||||||
|
protobuf==5.29.2
|
||||||
|
psutil==6.1.1
|
||||||
|
ptyprocess==0.7.0
|
||||||
|
pure-eval==0.2.3
|
||||||
|
pyarrow==18.1.0
|
||||||
|
pydeck==0.9.1
|
||||||
|
pygments==2.18.0
|
||||||
|
pypdf2==3.0.1
|
||||||
|
python-dateutil==2.9.0.post0
|
||||||
|
python-dotenv==1.0.1
|
||||||
|
pytz==2024.2
|
||||||
|
pyzmq==26.2.0
|
||||||
|
referencing==0.35.1
|
||||||
|
requests==2.32.3
|
||||||
|
rich==13.9.4
|
||||||
|
rpds-py==0.22.3
|
||||||
|
six==1.17.0
|
||||||
|
smmap==5.0.1
|
||||||
|
stack-data==0.6.3
|
||||||
|
streamlit==1.41.1
|
||||||
|
tenacity==9.0.0
|
||||||
|
toml==0.10.2
|
||||||
|
tornado==6.4.2
|
||||||
|
traitlets==5.14.3
|
||||||
|
typing-extensions==4.12.2
|
||||||
|
tzdata==2024.2
|
||||||
|
urllib3==2.3.0
|
||||||
|
wcwidth==0.2.13
|
||||||
|
zipp==3.21.0
|
||||||
202
settings.py
Normal file
202
settings.py
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
import streamlit as st
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from config import SYSTEM_PROMPT, INPUT_TEMPLATE, PROMPT_TEMPLATE
|
||||||
|
|
||||||
|
def settings_page():
|
||||||
|
st.title("Settings")
|
||||||
|
|
||||||
|
# Section for System Prompt
|
||||||
|
st.subheader("System Prompt")
|
||||||
|
if "system_prompt" not in st.session_state:
|
||||||
|
st.session_state["system_prompt"] = SYSTEM_PROMPT.strip()
|
||||||
|
system_prompt = st.text_area(
|
||||||
|
"Define the system prompt:",
|
||||||
|
value=st.session_state["system_prompt"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Section for Input Template
|
||||||
|
st.subheader("Input Template")
|
||||||
|
if "input_template" not in st.session_state:
|
||||||
|
st.session_state["input_template"] = INPUT_TEMPLATE.strip()
|
||||||
|
input_template = st.text_area(
|
||||||
|
"Define the input template:",
|
||||||
|
value=st.session_state["input_template"],
|
||||||
|
height=400
|
||||||
|
)
|
||||||
|
|
||||||
|
# Section for Prompt Template
|
||||||
|
st.subheader("Prompt Template")
|
||||||
|
if "prompt_template" not in st.session_state:
|
||||||
|
st.session_state["prompt_template"] = PROMPT_TEMPLATE.strip()
|
||||||
|
prompt_template = st.text_area(
|
||||||
|
"Define the prompt template:",
|
||||||
|
value=st.session_state["prompt_template"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Section for Number of Key Results
|
||||||
|
st.subheader("Number of Key Results")
|
||||||
|
if "num_key_results" not in st.session_state:
|
||||||
|
st.session_state["num_key_results"] = 4
|
||||||
|
num_key_results = st.number_input(
|
||||||
|
"Set the maximum number of key results:",
|
||||||
|
min_value=1,
|
||||||
|
max_value=10,
|
||||||
|
value=st.session_state["num_key_results"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Save Button for Settings
|
||||||
|
if st.button("Save Settings"):
|
||||||
|
st.session_state["system_prompt"] = system_prompt
|
||||||
|
st.session_state["input_template"] = input_template
|
||||||
|
st.session_state["prompt_template"] = prompt_template
|
||||||
|
st.session_state["num_key_results"] = num_key_results
|
||||||
|
st.success("Settings saved successfully!")
|
||||||
|
|
||||||
|
# Section for Team Member Management
|
||||||
|
team_member_management()
|
||||||
|
|
||||||
|
def team_member_management():
|
||||||
|
st.subheader("Team Member Management")
|
||||||
|
|
||||||
|
# Initialize team members in session state
|
||||||
|
if "team_members" not in st.session_state:
|
||||||
|
st.session_state["team_members"] = ["John Doe", "Jane Smith"]
|
||||||
|
|
||||||
|
# Display current team members
|
||||||
|
st.write("### Current Team Members")
|
||||||
|
for member in st.session_state["team_members"]:
|
||||||
|
col1, col2 = st.columns([4, 1])
|
||||||
|
col1.write(member)
|
||||||
|
if col2.button("Remove", key=f"remove_{member}"):
|
||||||
|
st.session_state["team_members"].remove(member)
|
||||||
|
st.experimental_rerun()
|
||||||
|
|
||||||
|
# Add new team member
|
||||||
|
st.write("### Add New Team Member")
|
||||||
|
new_member = st.text_input("Enter new team member name:", key="new_member")
|
||||||
|
if st.button("Add Team Member"):
|
||||||
|
if new_member.strip():
|
||||||
|
if new_member.strip() not in st.session_state["team_members"]:
|
||||||
|
st.session_state["team_members"].append(new_member.strip())
|
||||||
|
st.success(f"Added {new_member.strip()} to the team.")
|
||||||
|
st.experimental_rerun()
|
||||||
|
else:
|
||||||
|
st.warning(f"{new_member.strip()} is already in the team.")
|
||||||
|
else:
|
||||||
|
st.warning("Please enter a valid name.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SETTINGS_FILE = "settings.json"
|
||||||
|
|
||||||
|
# Load settings from JSON file
|
||||||
|
def load_settings():
|
||||||
|
if os.path.exists(SETTINGS_FILE) and 1 == 2:
|
||||||
|
with open(SETTINGS_FILE, "r") as f:
|
||||||
|
return json.load(f)
|
||||||
|
else:
|
||||||
|
# Default settings
|
||||||
|
return {
|
||||||
|
"system_prompt": SYSTEM_PROMPT,
|
||||||
|
"input_template": INPUT_TEMPLATE,
|
||||||
|
"prompt_template": PROMPT_TEMPLATE,
|
||||||
|
"num_key_results": 4,
|
||||||
|
"team_members": ["Khanh Dinh", "Robin Plitzko", "Roberto Renna"],
|
||||||
|
"team_member_template": "{name} - Team Member"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Save settings to JSON file
|
||||||
|
def save_settings(settings):
|
||||||
|
with open(SETTINGS_FILE, "w") as f:
|
||||||
|
json.dump(settings, f, indent=4)
|
||||||
|
|
||||||
|
# Settings Page
|
||||||
|
def settings_page():
|
||||||
|
st.title("Settings")
|
||||||
|
|
||||||
|
# Load settings
|
||||||
|
settings = load_settings()
|
||||||
|
|
||||||
|
# Section for System Prompt
|
||||||
|
st.subheader("System Prompt")
|
||||||
|
system_prompt = st.text_area(
|
||||||
|
"Define the system prompt:",
|
||||||
|
value=settings["system_prompt"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Section for Input Template
|
||||||
|
st.subheader("Input Template")
|
||||||
|
input_template = st.text_area(
|
||||||
|
"Define the input template:",
|
||||||
|
value=settings["input_template"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Section for Prompt Template
|
||||||
|
st.subheader("Prompt Template")
|
||||||
|
prompt_template = st.text_area(
|
||||||
|
"Define the prompt template (use {num_key_results} for dynamic insertion):",
|
||||||
|
value=settings["prompt_template"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Section for Number of Key Results
|
||||||
|
st.subheader("Number of Key Results")
|
||||||
|
num_key_results = st.number_input(
|
||||||
|
"Set the maximum number of key results:",
|
||||||
|
min_value=1,
|
||||||
|
max_value=10,
|
||||||
|
value=settings["num_key_results"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Section for Team Member Template
|
||||||
|
st.subheader("Team Member Template")
|
||||||
|
team_member_template = st.text_input(
|
||||||
|
"Define a template for team members (use {name} for dynamic insertion):",
|
||||||
|
value=settings["team_member_template"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Section for Team Member Management
|
||||||
|
team_member_management(settings)
|
||||||
|
|
||||||
|
# Save Button for Settings
|
||||||
|
if st.button("Save Settings"):
|
||||||
|
# Update settings dictionary
|
||||||
|
settings["system_prompt"] = system_prompt
|
||||||
|
settings["input_template"] = input_template
|
||||||
|
settings["prompt_template"] = prompt_template
|
||||||
|
settings["num_key_results"] = num_key_results
|
||||||
|
settings["team_member_template"] = team_member_template
|
||||||
|
|
||||||
|
# Save to file
|
||||||
|
save_settings(settings)
|
||||||
|
st.success("Settings saved successfully!")
|
||||||
|
|
||||||
|
# Team Member Management Section
|
||||||
|
def team_member_management(settings):
|
||||||
|
st.subheader("Team Member Management")
|
||||||
|
|
||||||
|
# Display current team members
|
||||||
|
st.write("### Current Team Members")
|
||||||
|
for member in settings["team_members"]:
|
||||||
|
col1, col2 = st.columns([4, 1])
|
||||||
|
col1.write(member)
|
||||||
|
if col2.button(f"Remove {member}", key=f"remove_{member}"):
|
||||||
|
settings["team_members"].remove(member)
|
||||||
|
save_settings(settings)
|
||||||
|
st.experimental_rerun()
|
||||||
|
|
||||||
|
# Add new team member
|
||||||
|
st.write("### Add New Team Member")
|
||||||
|
new_member = st.text_input("Enter new team member name:", key="new_member")
|
||||||
|
if st.button("Add Team Member"):
|
||||||
|
if new_member.strip():
|
||||||
|
if new_member.strip() not in settings["team_members"]:
|
||||||
|
settings["team_members"].append(new_member.strip())
|
||||||
|
save_settings(settings)
|
||||||
|
st.success(f"Added {new_member.strip()} to the team.")
|
||||||
|
st.experimental_rerun()
|
||||||
|
else:
|
||||||
|
st.warning(f"{new_member.strip()} is already in the team.")
|
||||||
|
else:
|
||||||
|
st.warning("Please enter a valid name.")
|
||||||
11
settings1.json
Normal file
11
settings1.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"system_prompt": "You are an OKR coach and support us, as beginners in OKRs, with the correct phrasing of OKRs.",
|
||||||
|
"input_template": "We want to improve our SLA framework by finalizing the current SLA template...",
|
||||||
|
"prompt_template": "Please help us in defining proper OKRs. Here is what we have thought about and we would like to phrase an OKR with max. 4 key results. this is the user input: {user_input} Please provide the response in json format. Objective (key: objective) key results (list with the key results)",
|
||||||
|
"num_key_results": 4,
|
||||||
|
"team_members": [
|
||||||
|
"John Doe",
|
||||||
|
"Jane Smith"
|
||||||
|
],
|
||||||
|
"team_member_template": "{name} - Team Member"
|
||||||
|
}
|
||||||
12
styles.py
Normal file
12
styles.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import streamlit as st
|
||||||
|
|
||||||
|
def apply_styles():
|
||||||
|
page_bg_color = """
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #002F5F;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
"""
|
||||||
|
st.markdown(page_bg_color, unsafe_allow_html=True)
|
||||||
42
test.ipynb
Normal file
42
test.ipynb
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 1,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"hello\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"print('hello')"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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
|
||||||
|
}
|
||||||
160
utils.py
Normal file
160
utils.py
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
import json
|
||||||
|
import streamlit as st
|
||||||
|
|
||||||
|
# Function to construct the prompt
|
||||||
|
def construct_prompt(prompt_template: str, user_input: str) -> str:
|
||||||
|
return prompt_template.format(user_input=user_input)
|
||||||
|
|
||||||
|
'''# Function to extract and parse JSON response
|
||||||
|
def extract_llm_response(response):
|
||||||
|
print("response:", response)
|
||||||
|
try:
|
||||||
|
raw_message_content = response["choices"][0]["message"]["content"]
|
||||||
|
print("raw_message_content:", raw_message_content)
|
||||||
|
# Clean and parse the JSON content
|
||||||
|
cleaned_content = raw_message_content.replace("`", "").split("json")[-1]
|
||||||
|
|
||||||
|
# for debugging
|
||||||
|
#if debug:
|
||||||
|
# print("cleaned:", '-'*50)
|
||||||
|
# print(cleaned_content.strip())
|
||||||
|
|
||||||
|
def parse_json_content(cleaned_content: str):
|
||||||
|
"""
|
||||||
|
Parses the cleaned content to extract valid JSON data.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cleaned_content (str): The raw content containing JSON data.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict or list: The parsed JSON object.
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
|
||||||
|
# Step 1: Strip unwanted characters and clean the content
|
||||||
|
cleaned_content = cleaned_content.strip()
|
||||||
|
|
||||||
|
# Step 2: Use regex to extract only the valid JSON block (e.g., starts with [ or {)
|
||||||
|
json_match = re.search(r"(\{.*\}|\[.*\])", cleaned_content, re.DOTALL)
|
||||||
|
|
||||||
|
if not json_match:
|
||||||
|
raise ValueError("No valid JSON found in the content.")
|
||||||
|
|
||||||
|
# Step 3: Extract and parse the valid JSON
|
||||||
|
valid_json = json_match.group(0) # Extract matched JSON block
|
||||||
|
try:
|
||||||
|
extracted_data = json.loads(valid_json)
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
raise ValueError(f"Failed to decode JSON. Error: {e}\nContent:\n{valid_json}")
|
||||||
|
|
||||||
|
return extracted_data
|
||||||
|
|
||||||
|
parsed_data = parse_json_content(cleaned_content=cleaned_content)
|
||||||
|
print("parsed_data:",parsed_data)
|
||||||
|
print("debug:", parsed_data.get("objective", ""))
|
||||||
|
|
||||||
|
#parsed_data = json.loads(cleaned_content)
|
||||||
|
return parsed_data.get("objective", ""), parsed_data.get("key_results", [])
|
||||||
|
except Exception as e:
|
||||||
|
st.error(f"Error parsing API response: {e}")
|
||||||
|
return "", []'''
|
||||||
|
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
|
||||||
|
def parse_json_content(cleaned_content: str):
|
||||||
|
"""
|
||||||
|
Parses the cleaned content to extract valid JSON data.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cleaned_content (str): The raw content containing JSON data.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict or list: The parsed JSON object.
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
|
||||||
|
# Step 1: Strip unwanted characters and clean the content
|
||||||
|
cleaned_content = cleaned_content.strip()
|
||||||
|
|
||||||
|
# Step 2: Use regex to extract only the valid JSON block (e.g., starts with [ or {)
|
||||||
|
json_match = re.search(r"(\{.*\}|\[.*\])", cleaned_content, re.DOTALL)
|
||||||
|
|
||||||
|
if not json_match:
|
||||||
|
raise ValueError("No valid JSON found in the content.")
|
||||||
|
|
||||||
|
# Step 3: Extract and parse the valid JSON
|
||||||
|
valid_json = json_match.group(0) # Extract matched JSON block
|
||||||
|
try:
|
||||||
|
extracted_data = json.loads(valid_json)
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
raise ValueError(f"Failed to decode JSON. Error: {e}\nContent:\n{valid_json}")
|
||||||
|
|
||||||
|
return extracted_data
|
||||||
|
|
||||||
|
# Function to extract and parse JSON response
|
||||||
|
def extract_llm_response(response):
|
||||||
|
"""
|
||||||
|
Extracts and parses the JSON response from the API.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
response (dict): The API response containing a hint and proposals.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: A tuple containing the objective (str), key results (list), and hint (str).
|
||||||
|
"""
|
||||||
|
print("RESPONSE:",response)
|
||||||
|
|
||||||
|
raw_message_content = response["choices"][0]["message"]["content"]
|
||||||
|
print("raw_message_content:", raw_message_content)
|
||||||
|
# Clean and parse the JSON content
|
||||||
|
cleaned_content = raw_message_content.replace("`", "").split("json")[-1]
|
||||||
|
print("cleaned content", cleaned_content)
|
||||||
|
|
||||||
|
parsed_data = parse_json_content(cleaned_content=cleaned_content)
|
||||||
|
print("parsed_data:",parsed_data)
|
||||||
|
|
||||||
|
hint = parsed_data.get("hint", "")
|
||||||
|
|
||||||
|
proposals = parsed_data.get("proposals", [])
|
||||||
|
|
||||||
|
if proposals:
|
||||||
|
# Extract the first proposal's objective and key results
|
||||||
|
first_proposal = proposals[0] # Get the first proposal (assuming it's a list)
|
||||||
|
objective = first_proposal.get("objective", "")
|
||||||
|
key_results = first_proposal.get("key_results", [])
|
||||||
|
else:
|
||||||
|
objective = ""
|
||||||
|
key_results = []
|
||||||
|
|
||||||
|
#print("debug:", parsed_data.get("objective", ""))
|
||||||
|
|
||||||
|
return objective, key_results, hint
|
||||||
|
|
||||||
|
#try:
|
||||||
|
# Extract hint from the response
|
||||||
|
hint = response.get("hint", "")
|
||||||
|
|
||||||
|
# Extract proposals from the response
|
||||||
|
proposals = response.get("proposals", [])
|
||||||
|
print("hint:", hint)
|
||||||
|
print("proposals:", proposals)
|
||||||
|
|
||||||
|
# Check if proposals are available
|
||||||
|
if proposals:
|
||||||
|
# Extract the first proposal's objective and key results
|
||||||
|
first_proposal = proposals[0] # Get the first proposal (assuming it's a list)
|
||||||
|
objective = first_proposal.get("objective", "")
|
||||||
|
key_results = first_proposal.get("key_results", [])
|
||||||
|
else:
|
||||||
|
objective = ""
|
||||||
|
key_results = []
|
||||||
|
|
||||||
|
# Log parsed data for debugging
|
||||||
|
print("parsed_data:", {"objective": objective, "key_results": key_results, "hint": hint})
|
||||||
|
|
||||||
|
return objective, key_results, hint
|
||||||
|
|
||||||
|
#except Exception as e:
|
||||||
|
# print(f"Error parsing API response: {e}")
|
||||||
|
# return "", [], ""
|
||||||
Loading…
Reference in New Issue
Block a user