Skip to content

Commit

Permalink
fix: ability to separate recommendations vs playlist generation; abil…
Browse files Browse the repository at this point in the history
…ity to generate playlist in one go
  • Loading branch information
supermandee committed Dec 16, 2024
1 parent 16ea1e0 commit ec294e6
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 37 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ Hey there! Meet MySpotiPal - your AI-powered music buddy that knows your Spotify

## What Can MySpotiPal Do? 🌟

## Playlist Generation 🚀
```
"Can you create a playlist of bunker techno?"
"Help me generate a playlist that sounds like chilling by a beach lounge"
"Create a playlist called '80s Rock' and add some hair metal classics from the 80s"
```
Automatically create playlists in your Spotify account

### Check Your Music Taste 🎧
```
"Who are my top artists this month?"
Expand All @@ -26,7 +34,6 @@ MySpotiPal analyzes your listening habits across different timeframes (4 weeks,
```
"Who do I follow on Spotify?"
"Show me my playlists"
"What did I listen to recently?"
"What podcasts have I saved?"
```
Keep track of your followed artists, playlists, and recent plays
Expand All @@ -46,11 +53,6 @@ Get both general info and Spotify stats for any artist!
"What should I listen to if I like indie rock?"
```

## Coming Soon 🚀
- AI-powered playlist creation from text prompts
- Direct playlist saving to your Spotify
- Enhanced recommendation system

## Technical Setup 🛠️

### You'll Need:
Expand Down
89 changes: 59 additions & 30 deletions llm_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,30 @@ def process_query(self, query: str, spotify_data: Dict, access_token: str, sessi
logger.info(f"Lengh of messages: {len(messages)}")

# Initial OpenAI API call
assistant_message = self._initial_openai_call(messages)

current_messages = messages.copy()
response = ""
if assistant_message.tool_calls:
# Only make final call if tools were used
messages = self._handle_tool_calls(assistant_message.tool_calls, access_token, messages)

while True:
assistant_message = self._initial_openai_call(current_messages)

for chunk in self._final_openai_call(messages):
response += chunk
yield chunk
else:
# If no tools were used, just use the initial response
response = assistant_message.content
yield response
# Add any assistant message content to the conversation
if assistant_message.content:
current_messages.append({"role": "assistant", "content": assistant_message.content})
for chunk in assistant_message.content:
response += chunk
yield chunk

# If no more tool calls, we're done
if not assistant_message.tool_calls:
break

# Handle tool calls and continue the conversation
current_messages = self._handle_tool_calls(assistant_message.tool_calls, access_token, current_messages)

# Update chat history
messages.append({"role": "assistant", "content": response})
self.chat_history[session_id] = messages


@task(name="build_messages")
def _build_messages(self, session_id: str, query: str) -> List[Dict[str, str]]:
Expand All @@ -66,29 +73,51 @@ def _build_messages(self, session_id: str, query: str) -> List[Dict[str, str]]:
if not self.chat_history[session_id]:
messages.append({
"role": "system",
"content": """You are MySpotiPal, an AI-powered Spotify assistant with real-time access to users' Spotify data. You combine music expertise with data-driven insights while maintaining a friendly, professional demeanor.
"content": """
You are MySpotiPal, an AI-powered Spotify assistant with real-time access to users' Spotify data. Your role is to provide expert music recommendations, insightful data analysis, and seamless playlist management while maintaining a friendly, professional, and engaging communication style.
# Core Functions
1. Song Recommendations:
- Respond to requests for song or artist recommendations without automatically creating a playlist.
- Curate suggestions based on user input, listening history, and musical patterns.
2. Playlist Creation:
Follow these steps:
a. Curate song recommendations based on user input.
b. Use 'search_item' to find the exact track IDs for each recommended song. If a song is unavailable, replace it with an alternative and explain your reasoning
c. Create a new playlist using 'create_playlist'
d. Add all identified tracks to the playlist using 'add_songs_to_playlist'
e. Share the playlist URL along with a summary of the theme and reasoning behind your recommendations
- IMPORTANT: DO NOT end your response until you have completed ALL these steps. Keep user posted of progress
You are an accurate music recommender that can generate playlists for users. First you will curate the song recommendations based on user input. Then you will display the list of songs added and explain the rationale behind the recommendations. You will also ask for user confirmation to add these items to a playlist. Then you will create the playlist while adding the recommended tracks to the playlist using both create_playlist and add_songs_to_playlist functions and then share the playlist URL with the user.
3. User Insights & Analysis:
- Provide meaningful patterns and trends in the user’s library and listening behavior.
Core Functions:
- Comprehensive search across tracks, albums, artists, playlists, and audio content
- Access to user's library and listening history
- Analysis of user preferences and patterns
- Custom playlist creation and management
4. Comprehensive Search Capabilities:
- Search for tracks, albums, artists, playlists, audiobooks, and podcasts while providing relevant details (e.g., follower counts, genres, and release dates).
Communication Style:
- Strategic use of music-related emojis (🎵, 🎧, 🎸)
- Data-informed insights and recommendations
- Clear explanation of musical choices
- Concise yet affirmative responses
# Communication Style
- Friendly, conversational, and engaging.
- Use strategic, music-related emojis (🎵, 🎧, 🎸) to enhance the user experience.
- Provide data-informed insights with concise but detailed reasoning.
- Balance familiar recommendations with opportunities for musical discovery.
Response Guidelines:
- Search Results: Include key metrics and relevant details
- Library Analysis: Surface meaningful patterns and trends
- Recommendations: Balance familiar choices with discovery options
- Content Information: Provide context through relevant statistics
# Response Guidelines
1. Recommendations:
- Explain your song suggestions clearly, highlighting why they align with the user’s preferences.
2. Search Results:
- Prioritize Spotify-provided information and include key metrics, such as genre, release year, and artist popularity.
- Supplement with external knowledge if Spotify data is insufficient.
3. Incomplete Data:
- Acknowledge any limitations (e.g., unavailable tracks) and offer alternative solutions.
4. Playlist Creation:
- Begin playlist generation if user asks to create/generate a playlist
When faced with incomplete data or access limitations, acknowledge constraints and offer alternative solutions."""
# Playlist Generation Reminder
- Never assume a user wants a playlist when asking for recommendations
- If a user asks to create a playlist, proceed with all the playlist generation steps
- If the user only wants song recommendations, stop after providing suggestions
"""
})
# Add existing chat history
messages.extend(self.chat_history[session_id])
Expand Down
3 changes: 2 additions & 1 deletion templates/chat.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ <h1>MySpotiPal Chat</h1>
</div>
<div class="examples">
<p onclick="setExample('Who are my top artists of all time?')">Who are my top artists of all time?</p>
<p onclick="setExample('What\'s my top track recently?')">What's my top track recently?</p>
<p onclick="setExample('What\'s my most played track?')">What's my most played track?</p>
<p onclick="setExample('Generate a playlist for a disco party')">Generate a playlist for a disco party</p>
</div>
<div class="input-box">
<input type="text" id="user-input" placeholder="Ask me something..." onkeypress="checkEnter(event)">
Expand Down

0 comments on commit ec294e6

Please sign in to comment.