-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrhyme_bot.py
218 lines (187 loc) · 9.21 KB
/
rhyme_bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
import streamlit as st
import requests
import tempfile
from transformers import pipeline
from langdetect import detect
import json
# --------------------- Helper Functions --------------------- #
def get_rhyme_suggestions(word):
# Placeholder: In a real implementation, call a rhyme API.
# Example static suggestions:
suggestions = {
"day": ["play", "say", "way", "clay", "array"],
"amor": ["dolor", "calor", "motor"],
}
return suggestions.get(word.lower(), ["No suggestions found."])
def generate_ai_image(prompt):
# Placeholder for DALL·E image generation call.
# If you have an API endpoint:
# headers = {"Authorization": f"Bearer {api_key}"}
# json_data = {"prompt": prompt, "n":1, "size":"512x512"}
# response = requests.post("DALL_E_API_ENDPOINT", headers=headers, json=json_data)
# image_url = response.json()["data"][0]["url"]
# return image_url
return None
def get_background_beat(tone):
# Placeholder: return a URL or local file path to an audio file
# In reality, you might have different audio files depending on tone.
if "uplifting" in tone or "joyful" in tone:
return "https://example.com/happy_beat.mp3"
elif "encouraging" in tone:
return "https://example.com/encouraging_beat.mp3"
elif "calm" in tone:
return "https://example.com/calm_beat.mp3"
else:
return "https://example.com/default_beat.mp3"
def construct_system_prompt(personality, mode, language, sentiment_tone):
persona_prompts = {
"Shakespearean Poet": "Respond with a rhyming couplet in the style of Shakespeare.",
"Modern Rapper": "Drop a rap line with a rhyme and rhythm based on the user's input.",
"Playful Jokester": "Respond with a rhyming line that's humorous and playful."
}
# Base persona prompt
system_prompt = persona_prompts[personality]
# Multilingual support
if language != "en":
system_prompt = f"Respond with a rhyme in {language}."
# Adjust tone based on sentiment
system_prompt += f" Respond in a tone that is {sentiment_tone}."
# Additional mode instructions
if mode == "Rhyme Battle":
system_prompt += " We are in a rhyme battle. The user and I take turns adding lines that rhyme with each other."
elif mode == "Storytelling":
system_prompt += " We are creating a longer rhyming story, each of my responses should advance the narrative."
elif mode == "Song Lyrics":
system_prompt += " We are creating a song. The user provides verses, and I provide a rhyming chorus."
return system_prompt
# --------------------- Streamlit App --------------------- #
st.title("Rhyme Bot: Speak, and I'll Rhyme!")
# Input for OpenAI API key
api_key = st.text_input(
"Enter your OpenAI API key",
type="password",
placeholder="Enter your API key here...",
)
if not api_key:
st.warning("Please enter your OpenAI API key to proceed.")
else:
# Personality Selector
personality = st.radio(
"Choose a personality for Rhyme Bot:",
("Shakespearean Poet", "Modern Rapper", "Playful Jokester")
)
# Advanced Features
mode = st.selectbox(
"Select mode:",
("Normal", "Rhyme Battle", "Storytelling", "Song Lyrics")
)
# Educational Features Toggle
show_education = st.checkbox("Show Rhyme Tutorials & Word Suggestions")
# Record audio
audio_file = st.audio_input("Say something, and I'll rhyme!")
if audio_file:
# Display the recorded audio for playback
st.audio(audio_file, format="audio/wav")
# Save the audio file temporarily for processing
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as temp_audio:
temp_audio.write(audio_file.read())
temp_audio_path = temp_audio.name
# Transcribe audio using OpenAI Whisper API
try:
with st.spinner("Transcribing your voice..."):
with open(temp_audio_path, "rb") as audio:
headers = {
"Authorization": f"Bearer {api_key}",
}
files = {
"file": audio,
}
data = {
"model": "whisper-1",
}
response = requests.post(
"https://api.openai.com/v1/audio/transcriptions",
headers=headers,
files=files,
data=data,
)
if response.status_code == 200:
transcription = response.json()["text"]
st.success("Transcription completed!")
st.write("**You said:**")
st.write(transcription)
# Language Detection
language = detect(transcription)
# Sentiment Analysis
sentiment_analyzer = pipeline("sentiment-analysis")
sentiment = sentiment_analyzer(transcription)[0]["label"].upper()
# Determine tone based on sentiment
if sentiment == "NEGATIVE":
tone = "uplifting and encouraging"
elif sentiment == "POSITIVE":
tone = "joyful and celebratory"
else:
tone = "neutral and calm"
# Construct dynamic system prompt
system_prompt = construct_system_prompt(personality, mode, language, tone)
# Generate a rhyming response using GPT Chat API
with st.spinner("Let me rhyme..."):
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
}
chat_data = {
"model": "gpt-4",
"messages": [
{
"role": "system",
"content": system_prompt,
},
{
"role": "user",
"content": transcription,
},
],
"temperature": 0.8,
}
response = requests.post(
"https://api.openai.com/v1/chat/completions",
headers=headers,
json=chat_data,
)
if response.status_code == 200:
rhyming_line = response.json()["choices"][0]["message"]["content"].strip()
st.write("**Rhyme Bot says:**")
# Display rhyme with creative typography (placeholder)
# In practice, you could use st.markdown with custom CSS or images.
st.markdown(f"<h2 style='font-family:serif; color:#3A3A3A;'>{rhyming_line}</h2>", unsafe_allow_html=True)
# Add background beat (if any)
beat_url = get_background_beat(tone)
if beat_url:
st.audio(beat_url, format="audio/mp3")
# AI-generated image based on the rhyme content (if available)
# For example, if user said something about a "sunny day":
if "sun" in transcription.lower():
image_prompt = "A bright sunny landscape with vibrant colors"
image_url = generate_ai_image(image_prompt)
if image_url:
st.image(image_url, caption="AI-generated illustration")
# Educational Features
if show_education:
st.write("**Rhyme Tutorial:**")
st.write("A common rhyme scheme is AABB, where the first two lines rhyme and the next two lines rhyme. For example:\nLine 1 (A) and Line 2 (A) rhyme.\nLine 3 (B) and Line 4 (B) rhyme.")
# Suggest rhymes for a word if the user wants
if transcription:
last_word = transcription.strip().split()[-1]
suggestions = get_rhyme_suggestions(last_word)
st.write(f"**Word Suggestions for '{last_word}':**", suggestions)
else:
st.error(
f"Failed to generate rhyme: {response.status_code} {response.text}"
)
else:
st.error(
f"Failed to transcribe audio: {response.status_code} {response.text}"
)
except Exception as e:
st.error(f"An error occurred: {e}")