Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
|
|
| 1 |
import streamlit as st
|
| 2 |
-
import
|
| 3 |
from typing import List, Dict
|
|
|
|
| 4 |
|
| 5 |
from config import MODEL_CHOICES, DEFAULT_MODEL, DEFAULT_PERSONA_PATH
|
| 6 |
from utils import (
|
|
@@ -28,7 +30,8 @@ if "api_key" not in st.session_state:
|
|
| 28 |
# Sidebar: API key, model, personas upload
|
| 29 |
# -------------------------
|
| 30 |
st.sidebar.header("π API Configuration")
|
| 31 |
-
|
|
|
|
| 32 |
if api_key_input:
|
| 33 |
st.session_state.api_key = api_key_input
|
| 34 |
import openai
|
|
@@ -40,7 +43,7 @@ model_choice = st.sidebar.selectbox("Model", MODEL_CHOICES, index=MODEL_CHOICES.
|
|
| 40 |
|
| 41 |
st.sidebar.markdown("---")
|
| 42 |
st.sidebar.header("π₯ Personas")
|
| 43 |
-
uploaded = st.sidebar.file_uploader("Upload personas.json", type=["json"])
|
| 44 |
personas = get_personas(uploaded, path=DEFAULT_PERSONA_PATH)
|
| 45 |
st.sidebar.metric("Total Personas", len(personas))
|
| 46 |
|
|
@@ -53,13 +56,12 @@ tabs = st.tabs(["Text", "Files"])
|
|
| 53 |
with tabs[0]:
|
| 54 |
text_desc = st.text_area("Describe your feature", height=160)
|
| 55 |
with tabs[1]:
|
| 56 |
-
uploaded_files = st.file_uploader("Upload wireframes / mockups", accept_multiple_files=True, type=["png",
|
| 57 |
|
| 58 |
feature_inputs = {
|
| 59 |
"Text": text_desc or "",
|
| 60 |
"Files": [f.name for f in (uploaded_files or [])]
|
| 61 |
}
|
| 62 |
-
|
| 63 |
st.markdown("---")
|
| 64 |
|
| 65 |
# -------------------------
|
|
@@ -67,7 +69,7 @@ st.markdown("---")
|
|
| 67 |
# -------------------------
|
| 68 |
st.header("π₯ Choose Personas")
|
| 69 |
if not personas:
|
| 70 |
-
st.warning("No personas available.")
|
| 71 |
selected_personas: List[Dict] = []
|
| 72 |
else:
|
| 73 |
labels = [f"{p['name']} ({p.get('occupation','')})" for p in personas]
|
|
@@ -87,7 +89,7 @@ clear_btn = c3.button("ποΈ Clear")
|
|
| 87 |
|
| 88 |
if ask_btn:
|
| 89 |
if not st.session_state.api_key:
|
| 90 |
-
st.warning("Please set your OpenAI API key in the sidebar.")
|
| 91 |
elif not selected_personas:
|
| 92 |
st.warning("Please select at least one persona.")
|
| 93 |
elif not (question or feature_inputs["Text"]):
|
|
@@ -140,10 +142,9 @@ if st.session_state.conversation_history.strip() and selected_personas:
|
|
| 140 |
matched = True
|
| 141 |
break
|
| 142 |
if not matched:
|
| 143 |
-
# user or neutral lines
|
| 144 |
st.markdown(line)
|
| 145 |
|
| 146 |
-
st.info("π‘ Continue the discussion using the **question field above** to ask
|
| 147 |
|
| 148 |
# Build & show heatmap
|
| 149 |
df_summary = build_sentiment_summary(lines, selected_personas)
|
|
@@ -151,7 +152,7 @@ if st.session_state.conversation_history.strip() and selected_personas:
|
|
| 151 |
st.markdown("## π₯ Persona Sentiment Heatmap")
|
| 152 |
st.altair_chart(chart, use_container_width=True)
|
| 153 |
else:
|
| 154 |
-
st.info("No conversation yet. Ask your personas a question to get started!")
|
| 155 |
|
| 156 |
# -------------------------
|
| 157 |
# Sidebar persona creation (persist)
|
|
|
|
| 1 |
+
# app.py
|
| 2 |
import streamlit as st
|
| 3 |
+
import os
|
| 4 |
from typing import List, Dict
|
| 5 |
+
import json
|
| 6 |
|
| 7 |
from config import MODEL_CHOICES, DEFAULT_MODEL, DEFAULT_PERSONA_PATH
|
| 8 |
from utils import (
|
|
|
|
| 30 |
# Sidebar: API key, model, personas upload
|
| 31 |
# -------------------------
|
| 32 |
st.sidebar.header("π API Configuration")
|
| 33 |
+
api_env = os.getenv("OPENAI_API_KEY", "")
|
| 34 |
+
api_key_input = st.sidebar.text_input("OpenAI API Key (or set OPENAI_API_KEY variable)", type="password", value=st.session_state.api_key or api_env)
|
| 35 |
if api_key_input:
|
| 36 |
st.session_state.api_key = api_key_input
|
| 37 |
import openai
|
|
|
|
| 43 |
|
| 44 |
st.sidebar.markdown("---")
|
| 45 |
st.sidebar.header("π₯ Personas")
|
| 46 |
+
uploaded = st.sidebar.file_uploader("Upload personas.json (optional)", type=["json"])
|
| 47 |
personas = get_personas(uploaded, path=DEFAULT_PERSONA_PATH)
|
| 48 |
st.sidebar.metric("Total Personas", len(personas))
|
| 49 |
|
|
|
|
| 56 |
with tabs[0]:
|
| 57 |
text_desc = st.text_area("Describe your feature", height=160)
|
| 58 |
with tabs[1]:
|
| 59 |
+
uploaded_files = st.file_uploader("Upload wireframes / mockups", accept_multiple_files=True, type=["png","jpg","jpeg","pdf"])
|
| 60 |
|
| 61 |
feature_inputs = {
|
| 62 |
"Text": text_desc or "",
|
| 63 |
"Files": [f.name for f in (uploaded_files or [])]
|
| 64 |
}
|
|
|
|
| 65 |
st.markdown("---")
|
| 66 |
|
| 67 |
# -------------------------
|
|
|
|
| 69 |
# -------------------------
|
| 70 |
st.header("π₯ Choose Personas")
|
| 71 |
if not personas:
|
| 72 |
+
st.warning("No personas available. Create personas in the sidebar or upload a personas.json.")
|
| 73 |
selected_personas: List[Dict] = []
|
| 74 |
else:
|
| 75 |
labels = [f"{p['name']} ({p.get('occupation','')})" for p in personas]
|
|
|
|
| 89 |
|
| 90 |
if ask_btn:
|
| 91 |
if not st.session_state.api_key:
|
| 92 |
+
st.warning("Please set your OpenAI API key in the sidebar or via OPENAI_API_KEY.")
|
| 93 |
elif not selected_personas:
|
| 94 |
st.warning("Please select at least one persona.")
|
| 95 |
elif not (question or feature_inputs["Text"]):
|
|
|
|
| 142 |
matched = True
|
| 143 |
break
|
| 144 |
if not matched:
|
|
|
|
| 145 |
st.markdown(line)
|
| 146 |
|
| 147 |
+
st.info("π‘ Continue the discussion using the **question field above** to ask another question.")
|
| 148 |
|
| 149 |
# Build & show heatmap
|
| 150 |
df_summary = build_sentiment_summary(lines, selected_personas)
|
|
|
|
| 152 |
st.markdown("## π₯ Persona Sentiment Heatmap")
|
| 153 |
st.altair_chart(chart, use_container_width=True)
|
| 154 |
else:
|
| 155 |
+
st.info("π‘ No conversation yet. Ask your personas a question to get started!")
|
| 156 |
|
| 157 |
# -------------------------
|
| 158 |
# Sidebar persona creation (persist)
|