Skip to content

Commit 74b094d

Browse files
authored
Merge pull request #79 from trubrics/st-feedback-streaming
St feedback streaming
2 parents 9c92229 + a1d437f commit 74b094d

File tree

13 files changed

+263
-99
lines changed

13 files changed

+263
-99
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ if st.session_state.logged_prompt:
108108
model=st.session_state.logged_prompt.config_model.model,
109109
prompt_id=st.session_state.logged_prompt.id,
110110
align="flex-start",
111-
single_submit=False
112111
)
113112
```
114113

docs/integrations/streamlit.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ if st.session_state.logged_prompt:
9090
model=st.session_state.logged_prompt.config_model.model,
9191
prompt_id=st.session_state.logged_prompt.id,
9292
align="flex-start",
93-
single_submit=False
9493
)
9594
```
9695

examples/streamlit/basic_app.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,4 @@
2323
model=st.session_state.logged_prompt.config_model.model,
2424
prompt_id=st.session_state.logged_prompt.id,
2525
align="flex-start",
26-
single_submit=False,
2726
)

examples/streamlit/llm_app.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
if "response" not in st.session_state:
88
st.session_state.response = ""
9+
if "feedback_key" not in st.session_state:
10+
st.session_state.feedback_key = 0
911
if "logged_prompt" not in st.session_state:
1012
st.session_state.logged_prompt = ""
1113

@@ -15,13 +17,17 @@
1517
email, password = trubrics_config()
1618

1719
if email and password:
18-
collector = FeedbackCollector(
19-
project="default",
20-
email=email,
21-
password=password,
22-
)
20+
try:
21+
collector = FeedbackCollector(email=email, password=password, project="default")
22+
except Exception:
23+
st.error(f"Error authenticating '{email}' with [Trubrics](https://trubrics.streamlit.app/). Please try again.")
24+
st.stop()
2325
else:
24-
st.warning("To save some feedback to Trubrics, add your account details in the sidebar.")
26+
st.info(
27+
"To ask a question to an LLM and save your feedback to Trubrics, add your email and password in the sidebar."
28+
" Don't have an account yet? Create one for free [here](https://trubrics.streamlit.app/)!"
29+
)
30+
st.stop()
2531

2632
models = ("gpt-3.5-turbo",)
2733
model = st.selectbox(
@@ -32,7 +38,8 @@
3238

3339
openai.api_key = st.secrets.get("OPENAI_API_KEY")
3440
if openai.api_key is None:
35-
raise ValueError("OpenAI key is missing. Set OPENAI_API_KEY in st.secrets")
41+
st.info("Please add your OpenAI API key to continue.")
42+
st.stop()
3643

3744
prompt = st.text_area(label="Prompt", label_visibility="collapsed", placeholder="What would you like to know?")
3845
button = st.button(f"Ask {model}")
@@ -41,9 +48,10 @@
4148
response = openai.ChatCompletion.create(model=model, messages=[{"role": "user", "content": prompt}])
4249
response_text = response.choices[0].message["content"]
4350
st.session_state.logged_prompt = collector.log_prompt(
44-
config_model={"model": model}, prompt=prompt, generation=response_text, tags=["llm_app.py"]
51+
config_model={"model": model}, prompt=prompt, generation=response_text, tags=["llm_app.py"], user_id=email
4552
)
4653
st.session_state.response = response_text
54+
st.session_state.feedback_key += 1
4755

4856
if st.session_state.response:
4957
st.markdown(f"#### :violet[{st.session_state.response}]")
@@ -55,8 +63,9 @@
5563
prompt_id=st.session_state.logged_prompt.id,
5664
model=model,
5765
align="flex-start",
58-
single_submit=False,
5966
tags=["llm_app.py"],
67+
key=f"feedback_{st.session_state.feedback_key}", # overwrite with new key
68+
user_id=email,
6069
)
6170

6271
if feedback:

examples/streamlit/llm_chatbot.py

Lines changed: 71 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,31 @@
66

77
from trubrics.integrations.streamlit import FeedbackCollector
88

9+
st.title("💬 Trubrics - Chat with user feedback")
10+
911
with st.sidebar:
1012
email, password = trubrics_config()
1113

14+
if not email or not password:
15+
st.info(
16+
"To chat with an LLM and save your feedback to Trubrics, add your email and password in the sidebar."
17+
" Don't have an account yet? Create one for free [here](https://trubrics.streamlit.app/)!"
18+
)
19+
st.stop()
20+
1221

1322
@st.cache_data
1423
def init_trubrics(email, password):
15-
collector = FeedbackCollector(email=email, password=password, project="default")
16-
return collector
24+
try:
25+
collector = FeedbackCollector(email=email, password=password, project="default")
26+
return collector
27+
except Exception:
28+
st.error(f"Error authenticating '{email}' with [Trubrics](https://trubrics.streamlit.app/). Please try again.")
29+
st.stop()
1730

1831

1932
collector = init_trubrics(email, password)
2033

21-
22-
st.title("💬 Trubrics - Chat with user feedback")
2334
if "messages" not in st.session_state:
2435
st.session_state["messages"] = [{"role": "assistant", "content": "How can I help you?"}]
2536
if "prompt_ids" not in st.session_state:
@@ -30,46 +41,66 @@ def init_trubrics(email, password):
3041
model = st.secrets.get("OPENAI_API_MODEL") or "gpt-3.5-turbo"
3142

3243
openai_api_key = st.secrets.get("OPENAI_API_KEY")
44+
45+
messages = st.session_state.messages
46+
feedback_kwargs = {
47+
"component": "default",
48+
"feedback_type": "thumbs",
49+
"open_feedback_label": "[Optional] Provide additional feedback",
50+
"model": model,
51+
"tags": ["llm_chatbot.py"],
52+
}
53+
54+
for n, msg in enumerate(messages):
55+
st.chat_message(msg["role"]).write(msg["content"])
56+
57+
if msg["role"] == "assistant" and n > 1:
58+
feedback_key = f"feedback_{int(n/2)}"
59+
60+
if feedback_key not in st.session_state:
61+
st.session_state[feedback_key] = None
62+
63+
disable_with_score = st.session_state[feedback_key].get("score") if st.session_state[feedback_key] else None
64+
feedback = collector.st_feedback(
65+
**feedback_kwargs,
66+
key=feedback_key,
67+
disable_with_score=disable_with_score,
68+
prompt_id=st.session_state.prompt_ids[int(n / 2) - 1],
69+
user_id=email,
70+
)
71+
if feedback:
72+
trubrics_successful_feedback(feedback)
73+
74+
3375
if prompt := st.chat_input():
76+
messages.append({"role": "user", "content": prompt})
77+
st.chat_message("user").write(prompt)
3478
if not openai_api_key:
3579
st.info("Please add your OpenAI API key to continue.")
3680
st.stop()
3781
else:
3882
openai.api_key = openai_api_key
39-
40-
st.session_state.messages.append({"role": "user", "content": prompt})
41-
response = openai.ChatCompletion.create(model=model, messages=st.session_state.messages)
42-
msg = response.choices[0].message
43-
logged_prompt = collector.log_prompt(
44-
config_model={"model": model},
45-
prompt=prompt,
46-
generation=msg["content"],
47-
session_id=st.session_state.session_id,
48-
tags=["llm_chatbot.py"],
83+
response = openai.ChatCompletion.create(model=model, messages=messages)
84+
generation = response.choices[0].message.content
85+
86+
with st.chat_message("assistant"):
87+
logged_prompt = collector.log_prompt(
88+
config_model={"model": model},
89+
prompt=prompt,
90+
generation=generation,
91+
session_id=st.session_state.session_id,
92+
tags=["llm_chatbot.py"],
93+
user_id=email,
94+
)
95+
st.session_state.prompt_ids.append(logged_prompt.id)
96+
messages.append({"role": "assistant", "content": generation})
97+
st.write(generation)
98+
99+
feedback = collector.st_feedback(
100+
**feedback_kwargs,
101+
key=f"feedback_{int(len(messages)/2)}",
102+
prompt_id=st.session_state.prompt_ids[int(len(messages) / 2) - 1],
103+
user_id=email,
49104
)
50-
st.session_state.prompt_ids.append(logged_prompt.id)
51-
st.session_state.messages.append(msg)
52-
53-
feedback = None
54-
for n, msg in enumerate(st.session_state.messages):
55-
st.chat_message(msg["role"]).write(msg["content"])
56-
57-
if msg["role"] == "assistant" and msg["content"] != "How can I help you?":
58-
if email and password:
59-
feedback = collector.st_feedback(
60-
component="default",
61-
feedback_type="thumbs",
62-
model=model,
63-
prompt_id=st.session_state.prompt_ids[int(n / 2) - 1],
64-
open_feedback_label="[Optional] Provide additional feedback",
65-
align="flex-end",
66-
single_submit=True,
67-
key=f"feedback_{int(n/2)}",
68-
tags=["llm_chatbot.py"],
69-
)
70-
71-
else:
72-
st.warning("To save some feedback to Trubrics, add your account details in the sidebar.")
73-
74-
if feedback:
75-
trubrics_successful_feedback(feedback)
105+
if feedback:
106+
trubrics_successful_feedback(feedback)
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import uuid
2+
3+
import openai
4+
import streamlit as st
5+
from trubrics_utils import trubrics_config, trubrics_successful_feedback
6+
7+
from trubrics.integrations.streamlit import FeedbackCollector
8+
9+
st.title("💬 Trubrics - Streaming chat with user feedback")
10+
11+
with st.sidebar:
12+
email, password = trubrics_config()
13+
14+
if not email or not password:
15+
st.info(
16+
"To chat with an LLM and save your feedback to Trubrics, add your email and password in the sidebar."
17+
" Don't have an account yet? Create one for free [here](https://trubrics.streamlit.app/)!"
18+
)
19+
st.stop()
20+
21+
22+
@st.cache_data
23+
def init_trubrics(email, password):
24+
try:
25+
collector = FeedbackCollector(email=email, password=password, project="default")
26+
return collector
27+
except Exception:
28+
st.error(f"Error authenticating '{email}' with [Trubrics](https://trubrics.streamlit.app/). Please try again.")
29+
st.stop()
30+
31+
32+
collector = init_trubrics(email, password)
33+
34+
if "messages" not in st.session_state:
35+
st.session_state["messages"] = [{"role": "assistant", "content": "How can I help you?"}]
36+
if "prompt_ids" not in st.session_state:
37+
st.session_state["prompt_ids"] = []
38+
if "session_id" not in st.session_state:
39+
st.session_state["session_id"] = str(uuid.uuid4())
40+
41+
model = st.secrets.get("OPENAI_API_MODEL") or "gpt-3.5-turbo"
42+
43+
openai_api_key = st.secrets.get("OPENAI_API_KEY")
44+
45+
messages = st.session_state.messages
46+
feedback_kwargs = {
47+
"component": "default",
48+
"feedback_type": "thumbs",
49+
"open_feedback_label": "[Optional] Provide additional feedback",
50+
"model": model,
51+
"tags": ["llm_chatbot.py"],
52+
}
53+
54+
for n, msg in enumerate(st.session_state.messages):
55+
st.chat_message(msg["role"]).write(msg["content"])
56+
57+
if msg["role"] == "assistant" and n > 1:
58+
feedback_key = f"feedback_{int(n/2)}"
59+
60+
if feedback_key not in st.session_state:
61+
st.session_state[feedback_key] = None
62+
63+
disable_with_score = st.session_state[feedback_key].get("score") if st.session_state[feedback_key] else None
64+
feedback = collector.st_feedback(
65+
**feedback_kwargs,
66+
key=feedback_key,
67+
disable_with_score=disable_with_score,
68+
prompt_id=st.session_state.prompt_ids[int(n / 2) - 1],
69+
user_id=email,
70+
)
71+
if feedback:
72+
trubrics_successful_feedback(feedback)
73+
74+
if prompt := st.chat_input("What is up?"):
75+
st.session_state.messages.append({"role": "user", "content": prompt})
76+
with st.chat_message("user"):
77+
st.markdown(prompt)
78+
with st.chat_message("assistant"):
79+
message_placeholder = st.empty()
80+
full_response = ""
81+
if not openai_api_key:
82+
st.info("Please add your OpenAI API key to continue.")
83+
st.stop()
84+
else:
85+
openai.api_key = openai_api_key
86+
87+
for response in openai.ChatCompletion.create(
88+
model=model,
89+
messages=[{"role": m["role"], "content": m["content"]} for m in st.session_state.messages],
90+
stream=True,
91+
):
92+
full_response += response.choices[0].delta.get("content", "")
93+
message_placeholder.markdown(full_response + "▌")
94+
message_placeholder.markdown(full_response)
95+
st.session_state.messages.append({"role": "assistant", "content": full_response})
96+
logged_prompt = collector.log_prompt(
97+
config_model={"model": model},
98+
prompt=prompt,
99+
generation=full_response,
100+
session_id=st.session_state.session_id,
101+
tags=["llm_chatbot.py"],
102+
user_id=email,
103+
)
104+
st.session_state.prompt_ids.append(logged_prompt.id)
105+
feedback = collector.st_feedback(
106+
**feedback_kwargs,
107+
key=f"feedback_{int(len(messages)/2)}",
108+
prompt_id=logged_prompt.id,
109+
user_id=email,
110+
)
111+
if feedback:
112+
trubrics_successful_feedback(feedback)

examples/streamlit/titanic_app.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ def init_trubrics():
6262
open_feedback_label="[Optional] Provide additional feedback",
6363
metadata=metadata,
6464
align="flex-start",
65-
single_submit=False,
6665
)
6766
if feedback:
6867
trubrics_successful_feedback(feedback)

examples/streamlit/trubrics_utils.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ def trubrics_config(default_component: bool = True):
1414
type="password",
1515
value=st.secrets.get("TRUBRICS_PASSWORD", ""),
1616
)
17-
st.write("Don't have an account yet? Create one [here](https://trubrics.streamlit.app/)!")
1817

1918
if default_component:
2019
return email, password

mkdocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
site_name: trubrics-sdk
2-
site_description: Combine data science knowledge with business user feedback to validate machine learning
2+
site_description: The first user analytics platform for AI.
33
repo_url: https://github.com/trubrics/trubrics-sdk.git
44
repo_name: trubrics/trubrics-sdk
55
plugins:

requirements-dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pytest-cov>=3.0.0
2424

2525
#extras (Note: in setup.cfg)
2626
streamlit>=1.21.0
27-
streamlit-feedback>=0.0.9
27+
streamlit-feedback==0.1.2
2828
numpy>=1.21.6
2929
pandas>=1.3.5
3030
scikit-learn>=1.0.0,<1.1.0

0 commit comments

Comments
 (0)