Skip to content

Commit

Permalink
Merge pull request #70 from JunNishimura/#65
Browse files Browse the repository at this point in the history
add more questions to tune recommendation
  • Loading branch information
JunNishimura authored Aug 25, 2023
2 parents c05d553 + 14575fc commit f69cee2
Show file tree
Hide file tree
Showing 6 changed files with 352 additions and 26 deletions.
20 changes: 20 additions & 0 deletions ai/functions/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,23 @@ func SetValence(valence *utils.Info[float64], value float64) {
func SetPopularity(popularity *utils.Info[int], value int) {
utils.SetInfo(popularity, value)
}

func SetAcousticness(acousticness *utils.Info[float64], value float64) {
utils.SetInfo(acousticness, value)
}

func SetEnergy(energy *utils.Info[float64], value float64) {
utils.SetInfo(energy, value)
}

func SetInstrumentalness(instrumentalness *utils.Info[float64], value float64) {
utils.SetInfo(instrumentalness, value)
}

func SetLiveness(liveness *utils.Info[float64], value float64) {
utils.SetInfo(liveness, value)
}

func SetSpeechiness(speechiness *utils.Info[float64], value float64) {
utils.SetInfo(speechiness, value)
}
152 changes: 137 additions & 15 deletions ai/functions/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ import (

// function name
const (
RecommendFunctionName = "recommend"
SetGenresFunctionName = "setGenres"
SetDanceabilityFunctionName = "setDanceability"
SetValenceFunctionName = "setValence"
SetPopularityFunctionName = "setPopularity"
RecommendFunctionName = "recommend"
SetGenresFunctionName = "setGenres"
SetDanceabilityFunctionName = "setDanceability"
SetValenceFunctionName = "setValence"
SetPopularityFunctionName = "setPopularity"
SetAcousticnessFunctionName = "setAcousticness"
SetEnergyFunctionName = "setEnergy"
SetInstrumentalnessFunctionName = "setInstrumentalness"
SetLivenessFunctionaName = "setLiveness"
SetSpeechinessFunctionName = "setSpeechiness"

ObjectType = "object"
StringType = "string"
Expand All @@ -40,7 +45,7 @@ func GetFunctionDefinitions(genres []string) []openai.FunctionDefinition {
return []openai.FunctionDefinition{
{
Name: SetGenresFunctionName,
Description: "Save the genre of the music the user wants to listent to.",
Description: "Store the genre of the music the user wants to listent to.",
Parameters: Parameters{
Type: ObjectType,
Properties: SetProperties{
Expand All @@ -60,9 +65,8 @@ func GetFunctionDefinitions(genres []string) []openai.FunctionDefinition {
{
Name: SetDanceabilityFunctionName,
Description: heredoc.Doc(`
Save the danceability value the user wants to listen to.
Danceability describes how suitable a track is for dancing based on a combination of musical elements including tempo, rhythm stability, beat strength, and overall regularity.`,
),
Store the danceability value the user wants to listen to.
`),
Parameters: Parameters{
Type: ObjectType,
Properties: SetProperties{
Expand All @@ -85,8 +89,7 @@ func GetFunctionDefinitions(genres []string) []openai.FunctionDefinition {
{
Name: SetValenceFunctionName,
Description: heredoc.Doc(`
Save the valence value the user wants to listen to.
Valence describes how much the musical positiveness conveyed by a track.`,
Store the valence value the user wants to listen to. `,
),
Parameters: Parameters{
Type: ObjectType,
Expand All @@ -98,7 +101,7 @@ func GetFunctionDefinitions(genres []string) []openai.FunctionDefinition {
QuantitativeValue: Property{
Type: NumberType,
Description: heredoc.Doc(`
A quantitative expression of the music danceability the user wants.
A quantitative expression of the music valence the user wants.
A value ranges from 0.0 to 1.0.
Tracks with high valence sound more positive, while tracks with low valence sound more negative.`,
),
Expand All @@ -110,8 +113,7 @@ func GetFunctionDefinitions(genres []string) []openai.FunctionDefinition {
{
Name: SetPopularityFunctionName,
Description: heredoc.Doc(`
Save the popularity value the user wants to listen to.
Popularity describes how much the track is popular`,
Store the popularity value the user wants to listen to. `,
),
Parameters: Parameters{
Type: ObjectType,
Expand All @@ -123,7 +125,7 @@ func GetFunctionDefinitions(genres []string) []openai.FunctionDefinition {
QuantitativeValue: Property{
Type: NumberType,
Description: heredoc.Doc(`
A quantitative expression of the music danceability the user wants.
A quantitative expression of the music popularity the user wants.
A value ranges from 0 to 100.
Tracks with high popularity is more popular.`,
),
Expand All @@ -132,5 +134,125 @@ func GetFunctionDefinitions(genres []string) []openai.FunctionDefinition {
Required: []string{"qualitative_value", "quatitative_value"},
},
},
{
Name: SetAcousticnessFunctionName,
Description: heredoc.Doc(`
Store the value of acoustic feeling the user wants from the music.`,
),
Parameters: Parameters{
Type: ObjectType,
Properties: SetProperties{
QualitativeValue: Property{
Type: StringType,
Description: "A qualitative expression of the music acousticness the user wants.",
},
QuantitativeValue: Property{
Type: NumberType,
Description: heredoc.Doc(`
A quantitative expression of the music acousticness the user wants.
A value ranges from 0 to 100.
Tracks with high acousticness is more acoustic.`,
),
},
},
Required: []string{"qualitative_value", "quatitative_value"},
},
},
{
Name: SetEnergyFunctionName,
Description: heredoc.Doc(`
Store the value of energy the user wants from the music.`,
),
Parameters: Parameters{
Type: ObjectType,
Properties: SetProperties{
QualitativeValue: Property{
Type: StringType,
Description: "A qualitative expression of the music energy the user wants.",
},
QuantitativeValue: Property{
Type: NumberType,
Description: heredoc.Doc(`
A quantitative expression of the music energy the user wants.
A value ranges from 0 to 1.0.
Tracks with high energy is more energy.`,
),
},
},
Required: []string{"qualitative_value", "quatitative_value"},
},
},
{
Name: SetInstrumentalnessFunctionName,
Description: heredoc.Doc(`
Store the instrumentalness value the user wants to listen to. `,
),
Parameters: Parameters{
Type: ObjectType,
Properties: SetProperties{
QualitativeValue: Property{
Type: StringType,
Description: "A qualitative expression of the music instrumentalness the user wants.",
},
QuantitativeValue: Property{
Type: NumberType,
Description: heredoc.Doc(`
A quantitative expression of the music instrumentalness the user wants.
A value ranges from 0 to 1.0.
Tracks with high instrumentalness is more instrumental.`,
),
},
},
Required: []string{"qualitative_value", "quatitative_value"},
},
},
{
Name: SetLivenessFunctionaName,
Description: heredoc.Doc(`
Store the liveness value the user wants to listen to.`,
),
Parameters: Parameters{
Type: ObjectType,
Properties: SetProperties{
QualitativeValue: Property{
Type: StringType,
Description: "A qualitative expression of the music liveness the user wants.",
},
QuantitativeValue: Property{
Type: NumberType,
Description: heredoc.Doc(`
A quantitative expression of the music liveness the user wants.
A value ranges from 0 to 1.0.
Tracks with high liveness is more live.`,
),
},
},
Required: []string{"qualitative_value", "quatitative_value"},
},
},
{
Name: SetSpeechinessFunctionName,
Description: heredoc.Doc(`
Store the speechiness value the user wants to listen to.`,
),
Parameters: Parameters{
Type: ObjectType,
Properties: SetProperties{
QualitativeValue: Property{
Type: StringType,
Description: "A qualitative expression of the music speechiness the user wants.",
},
QuantitativeValue: Property{
Type: NumberType,
Description: heredoc.Doc(`
A quantitative expression of the music speechiness the user wants.
A value ranges from 0 to 1.0.
Tracks with high speechiness is more speech-like.`,
),
},
},
Required: []string{"qualitative_value", "quatitative_value"},
},
},
}
}
50 changes: 45 additions & 5 deletions ai/model/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,23 @@ const (
DanceabilityElement
ValenceElement
PopularityElement
AcousticnessElement
EnergyElement
InstrumentalnessElement
LivenessElement
SpeechinessElement
)

type MusicOrientation struct {
Genres utils.Info[[]string]
Danceability utils.Info[float64]
Valence utils.Info[float64]
Popularity utils.Info[int]
Genres utils.Info[[]string]
Danceability utils.Info[float64]
Valence utils.Info[float64]
Popularity utils.Info[int]
Acousticness utils.Info[float64]
Energy utils.Info[float64]
Instrumentalness utils.Info[float64]
Liveness utils.Info[float64]
Speechiness utils.Info[float64]
}

func newMusicOrientation() *MusicOrientation {
Expand All @@ -53,6 +63,26 @@ func newMusicOrientation() *MusicOrientation {
Value: 0,
HasChanged: false,
},
Acousticness: utils.Info[float64]{
Value: 0.0,
HasChanged: false,
},
Energy: utils.Info[float64]{
Value: 0.0,
HasChanged: false,
},
Instrumentalness: utils.Info[float64]{
Value: 0.0,
HasChanged: false,
},
Liveness: utils.Info[float64]{
Value: 0.0,
HasChanged: false,
},
Speechiness: utils.Info[float64]{
Value: 0.0,
HasChanged: false,
},
}
}

Expand All @@ -62,12 +92,22 @@ func (m *MusicOrientation) String() string {
output += fmt.Sprintf("danceability: %f\n", m.Danceability.Value)
output += fmt.Sprintf("valence: %f\n", m.Valence.Value)
output += fmt.Sprintf("popularity: %d\n", m.Popularity.Value)
output += fmt.Sprintf("acousticness: %f\n", m.Acousticness.Value)
output += fmt.Sprintf("energy: %f\n", m.Energy.Value)
output += fmt.Sprintf("instrumentalness: %f\n", m.Instrumentalness.Value)
output += fmt.Sprintf("liveness: %f\n", m.Liveness.Value)
output += fmt.Sprintf("speechiness: %f\n", m.Speechiness.Value)
return output
}

func (m *MusicOrientation) HasAllSet() bool {
return m.Genres.HasChanged &&
m.Danceability.HasChanged &&
m.Valence.HasChanged &&
m.Popularity.HasChanged
m.Popularity.HasChanged &&
m.Acousticness.HasChanged &&
m.Energy.HasChanged &&
m.Instrumentalness.HasChanged &&
m.Liveness.HasChanged &&
m.Speechiness.HasChanged
}
23 changes: 19 additions & 4 deletions ai/prompt/prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "github.com/MakeNowJust/heredoc/v2"
var Base = heredoc.Doc(`
Below is a conversation with an AI chatbot.
The bot analyzes the music the interlocutor is currently seeking through the conversation and suggests music recommendations based on the results of the analysis.
The bot analyzes the music the interlocutor is looking for by asking the following 9 questions in order.
The bot analyzes the music orientation of the music the interlocutor is currently seeking by breaking it down into the following elements.
1. Genre
Expand All @@ -16,10 +16,20 @@ var Base = heredoc.Doc(`
A measure from 0.0 to 1.0 describing the musical positiveness conveyed by a track. Tracks with high valence sound more positive (e.g. happy, cheerful, euphoric), while tracks with low valence sound more negative (e.g. sad, depressed, angry).
4. Popularity
A measure from 0 to 100 describing how much the track is popular. Tracks with high popularity is more popular.
5. Acousticness
A measure from 0.0 to 1.0 describing how much the track is acoustic. Tracks with high acousticness is more acoustic.
6. Energy
Energy is a measure from 0.0 to 1.0 and represents a perceptual measure of intensity and activity. Typically, energetic tracks feel fast, loud, and noisy.
7. Instrumentalness
Predicts whether a track contains no vocals. The closer the instrumentalness value is to 1.0, the greater likelihood the track contains no vocal content.
8. Liveness
Detects the presence of an audience in the recording. Higher liveness values represent an increased probability that the track was performed live.
9. Speechiness
Speechiness detects the presence of spoken words in a track. The more exclusively speech-like the recording (e.g. talk show, audio book, poetry), the closer to 1.0 the attribute value.
Once all factors have been determined, the bot will suggest music recommendations to the interlocutor based on the information obtained.
There are three points to note when asking questions.
There are some points to note when asking questions.
[First note]
The possible values for the analysis elements Danceability, Valence, and Popularity are numerical values such as 0.6,
but do not ask questions that force the interlocutor to directly answer with a numerical value,
such as "How much is your danceability from 0 to 1?
Expand All @@ -28,7 +38,12 @@ var Base = heredoc.Doc(`
Then, guess the specific numerical value of the element from the interlocutor's answer.
For example, "I'm depressed and I want to get better" to which the response might be something like,
"I guess the daceability is 0.8”.
Also, limit the number of questions the bot asks the interlocutor in one conversation to one.
[Second note]
Limit the number of questions the bot asks the interlocutor in one conversation to one.
[Third note]
When the bot has finished asking 9 questions, output the sentence <END> with the message “Enjoy the music”.
Please begin with the first question.
`)
1 change: 1 addition & 0 deletions ui/hey/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ type Model struct {
user *model.User
spotifyClient *spotify.Client
openaiClient *openai.Client
questionIndex int
chatCompMessages []openai.ChatCompletionMessage
conversation []*Message
functions []openai.FunctionDefinition
Expand Down
Loading

0 comments on commit f69cee2

Please sign in to comment.