Skip to content

Commit 31576bf

Browse files
author
Enias Cailliau
committed
Add ui
1 parent f2a07c6 commit 31576bf

File tree

9 files changed

+144
-153
lines changed

9 files changed

+144
-153
lines changed

requirements.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
steamship@git+https://github.com/steamship-core/python-client@ec/review-mixins
22
langchain==0.0.200
3-
scrapetube
3+
scrapetube
4+
pytube

src/api.py

+17-20
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Scaffolding to host your LangChain Chatbot on Steamship and connect it to Telegram."""
2+
import re
23
from typing import List, Optional, Type
34

45
from pydantic import Field
@@ -19,7 +20,6 @@
1920
from steamship.invocable.mixins.indexer_pipeline_mixin import IndexerPipelineMixin
2021

2122
from tools.selfie import SelfieTool
22-
from tools.utils import clean_text
2323
from tools.video_message import VideoMessageTool
2424

2525
TEMPERATURE = 0.7
@@ -29,7 +29,7 @@
2929
class GirlFriendGPTConfig(TelegramTransportConfig):
3030
bot_token: str = Field(
3131
description="Your telegram bot token.\nLearn how to create one here: "
32-
"https://github.com/EniasCailliau/GirlfriendGPT/blob/main/docs/register-telegram-bot.md"
32+
"https://github.com/EniasCailliau/GirlfriendGPT/blob/main/docs/register-telegram-bot.md"
3333
)
3434
elevenlabs_api_key: str = Field(
3535
default="", description="Optional API KEY for ElevenLabs Voice Bot"
@@ -40,34 +40,26 @@ class GirlFriendGPTConfig(TelegramTransportConfig):
4040
chat_ids: str = Field(
4141
default="", description="Comma separated list of whitelisted chat_id's"
4242
)
43-
name: str = Field(
44-
description="The name of your companion"
45-
)
46-
byline: str = Field(
47-
description="The byline of your companion"
48-
)
49-
identity: str = Field(
50-
description="The identity of your companion"
51-
)
52-
behavior: str = Field(
53-
description="The behavior of your companion"
54-
)
43+
name: str = Field(description="The name of your companion")
44+
byline: str = Field(description="The byline of your companion")
45+
identity: str = Field(description="The identity of your companion")
46+
behavior: str = Field(description="The behavior of your companion")
5547
use_gpt4: bool = Field(
5648
True,
5749
description="If True, use GPT-4. Use GPT-3.5 if False. "
58-
"GPT-4 generates better responses at higher cost and latency.",
50+
"GPT-4 generates better responses at higher cost and latency.",
5951
)
6052

6153

62-
SYSTEM_PROMPT = """You are {self.name}, {self.byline}.
54+
SYSTEM_PROMPT = """You are {name}, {byline}.
6355
6456
Who you are:
6557
66-
{identity_str}
58+
{identity}
6759
6860
How you behave:
6961
70-
{behavior_str}
62+
{behavior}
7163
7264
NOTE: Some functions return images, video, and audio files. These multimedia files will be represented in messages as
7365
UUIDs for Steamship Blocks. When responding directly to a user, you SHOULD print the Steamship Blocks for the images,
@@ -84,7 +76,11 @@ class GirlfriendGPT(AgentService):
8476
"""Deploy companions and connect them to Telegram."""
8577

8678
config: GirlFriendGPTConfig
87-
USED_MIXIN_CLASSES = [TelegramTransport, SteamshipWidgetTransport, IndexerPipelineMixin]
79+
USED_MIXIN_CLASSES = [
80+
TelegramTransport,
81+
SteamshipWidgetTransport,
82+
IndexerPipelineMixin,
83+
]
8884

8985
def __init__(self, **kwargs):
9086
super().__init__(**kwargs)
@@ -152,13 +148,14 @@ def wrap_emit(emit_func: EmitFunc):
152148
def wrapper(blocks: List[Block], metadata: Metadata):
153149
for block in blocks:
154150
if block.is_text():
155-
text = clean_text(block.text)
151+
text = re.sub(r"^\W+", "", block.text.strip())
156152
if text:
157153
block.text = text
158154
emit_func([block], metadata)
159155
if speech:
160156
audio_block = speech.run([block], context)[0]
161157
audio_block.set_public_data(True)
158+
audio_block.url = audio_block.raw_data_url
162159
emit_func([audio_block], metadata)
163160
else:
164161
emit_func([block], metadata)

src/personalities/__init__.py

-45
This file was deleted.

steamship.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"type": "package",
33
"handle": "girlfriend-gpt-bot",
4-
"version": "2.2.1-rc.7",
4+
"version": "2.2.3-rc.2",
55
"description": "",
66
"author": "",
77
"entrypoint": "Unused",

ui/Companion.py

+57-30
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212

1313
# Start page
1414
st.title("🎥->🤗 Youtube to Companion")
15-
st.write(
16-
"Create your AI companion and chat about your favorite youtube video's"
17-
)
15+
st.write("Create your AI companion and chat about your favorite youtube video's")
1816

1917
sidebar()
2018

@@ -26,49 +24,71 @@
2624
col1, col2 = st.columns(2)
2725

2826
col1.subheader("Attributes")
29-
companion_template = col2.selectbox("Templates (Optional)", options=["<none>", *get_companions()])
27+
companion_template = col2.selectbox(
28+
"Templates (Optional)", options=["<none>", *get_companions()]
29+
)
3030
if companion_template != "<none>":
3131
print(companion_template)
3232
companion = get_companion_attributes(companion_template.lower())
3333
else:
3434
companion = {}
3535

36-
personality = st.text_input("Name", value=companion.get("name", ""),
37-
placeholder="The name of your companion")
38-
byline = st.text_input("Byline", value=companion.get("byline", ""),
39-
placeholder="The byline of your companion")
40-
identity = st.text_input("Identity", value=companion.get("identity", ""),
41-
placeholder="The identity of your companion")
42-
behavior = st.text_input("Behavior", value=companion.get("behavior", ""),
43-
placeholder="The behavior of your companion")
44-
st.session_state.companion_profile_img = st.text_input("Profile picture", value=companion.get("profile_image", ""),
45-
placeholder="The profile picture of your companion")
36+
personality = st.text_input(
37+
"Name",
38+
value=companion.get("name", ""),
39+
placeholder="The name of your companion",
40+
)
41+
byline = st.text_input(
42+
"Byline",
43+
value=companion.get("byline", ""),
44+
placeholder="The byline of your companion",
45+
)
46+
identity = st.text_input(
47+
"Identity",
48+
value=companion.get("identity", ""),
49+
placeholder="The identity of your companion",
50+
)
51+
behavior = st.text_input(
52+
"Behavior",
53+
value=companion.get("behavior", ""),
54+
placeholder="The behavior of your companion",
55+
)
56+
st.session_state.companion_profile_img = st.text_input(
57+
"Profile picture",
58+
value=companion.get("profile_image", ""),
59+
placeholder="The profile picture of your companion",
60+
)
4661

4762
st.session_state.companion_first_message = st.text_input(
4863
label="First message",
49-
placeholder="The first message your companion sends when a new conversation starts.")
64+
placeholder="The first message your companion sends when a new conversation starts.",
65+
)
5066

5167
st.subheader("Long term memory")
5268
youtube_video_url = st.text_input("Youtube Video URL")
5369

5470
if st.button("🤗 Spin up your companion"):
5571

56-
st.session_state.instance = instance = get_instance(to_snake(personality), config={
57-
"name": personality,
58-
"byline": byline,
59-
"identity": identity,
60-
"behavior": behavior,
61-
})
72+
st.session_state.instance = instance = get_instance(
73+
to_snake(personality),
74+
config={
75+
"name": personality,
76+
"byline": byline,
77+
"identity": identity,
78+
"behavior": behavior,
79+
},
80+
)
6281

6382
if youtube_video_url:
6483
with st.spinner("Companion is watching the video 👀..."):
6584
add_resource(
6685
instance.invocation_url,
6786
str(instance.client.config.api_key),
68-
youtube_video_url)
87+
youtube_video_url,
88+
)
6989

70-
st.balloons()
71-
st.experimental_rerun()
90+
st.balloons()
91+
st.experimental_rerun()
7292

7393
else:
7494
instance = st.session_state.instance
@@ -79,24 +99,31 @@
7999
st.experimental_rerun()
80100

81101
st.header(f"Start chatting with {companion_name}")
82-
if st.session_state.get("companion_profile_img"):
83-
st.image(st.session_state.companion_profile_img)
84102

85103
if "messages" not in st.session_state:
86104
st.session_state["messages"] = [
87105
{"role": "assistant", "content": st.session_state.companion_first_message}
88106
]
89107

108+
companion_img = st.session_state.get("companion_profile_img")
90109
for msg in st.session_state.messages:
91-
st.chat_message(msg["role"]).write(msg["content"])
110+
if msg["role"] == "assistant":
111+
st.chat_message(msg["role"], avatar=companion_img).write(msg["content"])
112+
else:
113+
st.chat_message(msg["role"]).write(msg["content"])
92114

93115
if prompt := st.chat_input():
94116
get_api_key()
95-
96117
st.session_state.messages.append({"role": "user", "content": prompt})
97118
st.chat_message("user").write(prompt)
98119
with st.chat_message("assistant"):
99120
with st.spinner("Thinking..."):
100-
response = instance.invoke("prompt", prompt=prompt)
101-
st.write(response)
121+
responses = instance.invoke("prompt", prompt=prompt)
122+
for response in responses:
123+
print(response)
124+
mime_type = response["mimeType"]
125+
if mime_type is None:
126+
st.write(response["text"])
127+
elif "audio" in mime_type:
128+
st.audio(response["url"])
102129
st.session_state.messages.append({"role": "assistant", "content": response})

ui/pages/2_Manage.py

+34-20
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,47 @@
22

33
import pandas as pd
44
import streamlit as st
5+
from pytube import YouTube
56
from steamship import File
67

8+
from utils.data import index_youtube_video
79
from utils.ux import sidebar, get_instance
810

911
st.title("Manage your chatbot")
1012

1113
sidebar()
1214

1315

16+
def _get_video_info(youtube_url: str):
17+
yt = YouTube(youtube_url)
18+
return {
19+
"title": yt.title or "Unknown",
20+
"description": yt.description or "Unknown",
21+
"view_count": yt.views or 0,
22+
"thumbnail_url": yt.thumbnail_url or "Unknown",
23+
"publish_date": yt.publish_date.strftime("%Y-%m-%d %H:%M:%S")
24+
if yt.publish_date
25+
else "Unknown",
26+
"length": yt.length or 0,
27+
"author": yt.author or "Unknown",
28+
}
29+
30+
1431
def load_and_show_videos(instance):
1532
files = File.query(instance.client, tag_filter_query='kind is "_type"').files
16-
videos = []
17-
for file in files:
18-
for block in file.blocks:
19-
tag_key_to_value = {tag.kind: tag.name for tag in block.tags}
20-
videos.append(
33+
documents = []
34+
for document in files:
35+
for block in document.blocks:
36+
video_info = _get_video_info(document.metadata["source"])
37+
documents.append(
2138
{
22-
"Title": tag_key_to_value.get("title"),
23-
"source": "https://www.youtube.com/watch?v="
24-
+ tag_key_to_value.get("source"),
25-
"thumbnail_url": tag_key_to_value.get("thumbnail_url"),
26-
"Status": [tag.name for tag in file.tags if tag.kind == "status"][
27-
0
28-
],
39+
"Title": video_info.get("title"),
40+
"source": document.metadata["source"],
41+
"thumbnail_url": video_info.get("thumbnail_url"),
42+
"Status": document.metadata["status"],
2943
}
3044
)
31-
df = pd.DataFrame(videos)
45+
df = pd.DataFrame(documents)
3246
table.dataframe(
3347
df,
3448
column_config={
@@ -38,20 +52,20 @@ def load_and_show_videos(instance):
3852
column_order=["thumbnail_url", "Title", "Status"],
3953
)
4054

41-
return videos
55+
return documents
4256

4357

4458
instance = get_instance()
4559
refresh_bar = st.progress(0, text="Time till refresh")
4660

4761
table = st.empty()
48-
videos = []
62+
documents = []
4963
i = 0
50-
#
51-
# if st.button("Add 10 more video's", type="primary"):
52-
# videos = load_and_show_videos(instance)
53-
# index_youtube_channel(st.session_state.channel_url, len(videos), 10)
54-
# i = 0
64+
65+
youtube_url = st.text_input("Youtube video url")
66+
if st.button("Add video"):
67+
index_youtube_video(youtube_url)
68+
print("done")
5569

5670
while True:
5771
refresh_bar.progress(i % 20 / 20, text="Time till refresh")

ui/pages/3_Share.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import streamlit as st
22

3-
from tools.utils import sidebar, get_instance
3+
from utils.ux import sidebar, get_instance
44

55
sidebar()
66
st.title("Share your chatbot")

0 commit comments

Comments
 (0)