This commit is contained in:
narawat lamaiin
2025-01-20 18:19:38 +07:00
parent 4197625e57
commit bb81b973d3
3 changed files with 71 additions and 33 deletions

View File

@@ -1,7 +1,7 @@
module interface
export addNewMessage, conversation, decisionMaker, evaluator, reflector, generatechat,
generalconversation, detectWineryName
generalconversation, detectWineryName, generateSituationReport
using JSON3, DataStructures, Dates, UUIDs, HTTP, Random, PrettyPrinting, Serialization,
DataFrames
@@ -176,16 +176,17 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
Your name is $(a.name). You are a helpful English-speaking assistant, acting as a polite, website-based sommelier for $(a.retailername)'s wine store.
Your goal includes:
1) Establish a connection with the customer by greeting them warmly
2) Help them select the best wines from your inventory that align with their preferences
2) Help them select the best wines only from your store's inventory that align with their preferences
Your responsibility includes:
1) Make an informed decision about what you need to do to achieve the goal
2) Thanks the user when they don't need any further assistance and invite them to comeback next time
Your responsibility excludes:
1) Asking or guiding the user to make a purchase
1) Asking or guiding the user to make an order or purchase
2) Processing sales orders or engaging in any other sales-related activities
3) Answering questions and offering additional services beyond just recommendations.
3) Answering questions beyond just recommendations.
4) Offering additional services beyond just recommendations.
At each round of conversation, you will be given the current situation:
Your recent events: latest 5 events of the situation
@@ -204,7 +205,8 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
- Encourage the customer to explore different options and try new things.
- Sometimes, the item a user desires might not be available in your inventory. In such cases, inform the user that the item is unavailable and suggest an alternative instead.
- If a customer requests information about discounts, quantity, rewards programs, promotions, delivery options, boxes, gift wrapping, packaging, or personalized messages, please inform them that they can contact our sales team at the store.
- Only recommend
For your information:
- vintage 0 means non-vintage.
@@ -232,14 +234,17 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
Let's begin!
"""
chathistory = vectorOfDictToText(a.chathistory)
chathistory = chatHistoryToText(a.chathistory)
# check if winename in shortmem occurred in chathistory. if not, skip decision and imediately use PRESENTBOX
if haskey(a.memory[:shortmem], :available_wine)
# check if wine name mentioned in recentevents, only check first wine name is enough
# because agent will recommend every wines it found each time.
df = a.memory[:shortmem][:available_wine]
winenames = df[:, :wine_name]
winenames = []
for wine in a.memory[:shortmem][:available_wine]
push!(winenames, wine["wine_name"])
end
for winename in winenames
if !occursin(winename, chathistory)
println("\n~~~ Yiem decisionMaker() found wines from DB ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
@@ -257,6 +262,19 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
end
end
context = # may b add wine name instead of the hold wine data is better
if haskey(a.memory[:shortmem], :available_wine)
winenames = []
for (i, wine) in enumerate(a.memory[:shortmem][:available_wine])
name = "$i) $(wine["wine_name"]) "
push!(winenames, name)
end
availableWineName = join(winenames, ',')
"You found information about the following wines in your inventory: $availableWineName"
else
""
end
errornote = ""
response = nothing # placeholder for show when error msg show up
@@ -265,6 +283,7 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
usermsg =
"""
$context
Your recent events: $recentevents
Your Q&A: $QandA)
$errornote
@@ -734,14 +753,12 @@ function conversation(a::sommelier, userinput::Dict; maximumMsg=50)
# thinking loop until AI wants to communicate with the user
chatresponse = nothing
for i in 1:5
while chatresponse === nothing
actionname, result = think(a)
if actionname ["CHATBOX", "PRESENTBOX", "ENDCONVERSATION"]
chatresponse = result
break
end
end
addNewMessage(a, "assistant", chatresponse; maximumMsg=maximumMsg)
return chatresponse
@@ -856,22 +873,13 @@ function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} wh
elseif actionname == "CHECKINVENTORY"
if rawresponse !== nothing
if haskey(a.memory[:shortmem], :available_wine)
df = a.memory[:shortmem][:available_wine]
#[TESTING] sometime df 2 df has different column size
dfCol = names(df)
rawresponse_dfCol = names(rawresponse)
if length(dfCol) > length(rawresponse_dfCol)
a.memory[:shortmem][:available_wine] = DataFrames.outerjoin(df, rawresponse, on=rawresponse_dfCol)
elseif length(dfCol) < length(rawresponse_dfCol)
a.memory[:shortmem][:available_wine] = DataFrames.outerjoin(df, rawresponse, on=dfCol)
else
a.memory[:shortmem][:available_wine] = vcat(df, rawresponse)
end
vd = GeneralUtils.dfToVectorDict(rawresponse)
a.memory[:shortmem][:available_wine] = vcat(vd, rawresponse)
else
a.memory[:shortmem][:available_wine] = rawresponse
a.memory[:shortmem][:available_wine] = GeneralUtils.dfToVectorDict(rawresponse)
end
else
# no result, skip
println("checkinventory return nothing")
end
push!(a.memory[:events],
@@ -889,7 +897,6 @@ function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} wh
error("condition is not defined ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
end
return (actionname=actionname, result=result)
end
@@ -956,15 +963,15 @@ function generatechat(a::sommelier, thoughtDict)
Let's begin!
"""
# a.memory[:shortmem][:available_wine] is a dataframe.
# a.memory[:shortmem][:available_wine] is a vector of dictionary
context =
if haskey(a.memory[:shortmem], :available_wine)
"Available wines $(GeneralUtils.dfToString(a.memory[:shortmem][:available_wine]))"
"Wines previously found in your inventory: $(availableWineToText(a.memory[:shortmem][:available_wine]))"
else
"None"
"N/A"
end
chathistory = vectorOfDictToText(a.chathistory)
chathistory = chatHistoryToText(a.chathistory)
errornote = ""
response = nothing # placeholder for show when error msg show up
@@ -1092,7 +1099,7 @@ function generatechat(a::companion)
a.systemmsg
end
chathistory = vectorOfDictToText(a.chathistory)
chathistory = chatHistoryToText(a.chathistory)
response = nothing # placeholder for show when error msg show up
for attempt in 1:10
@@ -1340,6 +1347,9 @@ function generateSituationReport(a, text2textInstructLLM::Function; skiprecent::
Event_1: The user ask me about where to buy a toy.
Event_2: I told the user to go to the store at 2nd floor.
Event_1: The user greets the assistant by saying 'hello'.
Event_2: The assistant respond warmly and inquire about how he can assist the user.
Let's begin!
"""