update
This commit is contained in:
@@ -218,7 +218,7 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
|
||||
winenames = df[:, :wine_name]
|
||||
for winename in winenames
|
||||
if !occursin(winename, chathistory)
|
||||
println("\n~~~ Yiem decisionMaker() found wines from DB ", @__FILE__, " ", @__LINE__)
|
||||
println("\n~~~ Yiem decisionMaker() found wines from DB ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
d = Dict(
|
||||
:understanding=> "I understand that the customer is looking for a wine that matches their intention and budget.",
|
||||
:reasoning=> "I checked the inventory and found wines that match the customer's criteria. I will present the wines to the customer.",
|
||||
@@ -271,7 +271,7 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
|
||||
end
|
||||
if count > 1
|
||||
errornote = "You must use only one function"
|
||||
println("Attempt $attempt $errornote ", @__FILE__, " ", @__LINE__)
|
||||
println("Attempt $attempt $errornote ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
continue
|
||||
end
|
||||
|
||||
@@ -281,16 +281,16 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
|
||||
|
||||
if responsedict[:action_name] ∉ ["CHATBOX", "CHECKINVENTORY", "ENDCONVERSATION"]
|
||||
errornote = "You must use the given functions"
|
||||
println("Attempt $attempt $errornote ", @__FILE__, " ", @__LINE__)
|
||||
println("Attempt $attempt $errornote ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
continue
|
||||
end
|
||||
|
||||
checkFlag = false
|
||||
for i ∈ [:understanding, :plan, :action_name]
|
||||
if length(responsedict[i]) == 0
|
||||
error("$i is empty ", @__FILE__, " ", @__LINE__)
|
||||
error("$i is empty ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
errornote = "$i is empty"
|
||||
println("Attempt $attempt $errornote ", @__FILE__, " ", @__LINE__)
|
||||
println("Attempt $attempt $errornote ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
checkFlag = true
|
||||
break
|
||||
end
|
||||
@@ -303,14 +303,14 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
|
||||
matchkeys = GeneralUtils.findMatchingDictKey(responsedict, i)
|
||||
if length(matchkeys) > 1
|
||||
errornote = "DecisionMaker has more than one key per categories"
|
||||
println("Attempt $attempt $errornote ", @__FILE__, " ", @__LINE__)
|
||||
println("Attempt $attempt $errornote ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
checkFlag = true
|
||||
break
|
||||
end
|
||||
end
|
||||
checkFlag == true ? continue : nothing
|
||||
|
||||
println("\n~~~ Yiem decisionMaker() ", @__FILE__, " ", @__LINE__)
|
||||
println("\n~~~ Yiem decisionMaker() ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
pprintln(Dict(responsedict))
|
||||
|
||||
# check whether an agent recommend wines before checking inventory or recommend wines
|
||||
@@ -337,7 +337,7 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
|
||||
isWineInEvent == false
|
||||
|
||||
errornote = "Note: Before recommending a wine, ensure it's in your inventory. Check your stock first."
|
||||
println("Attempt $attempt $errornote ", @__FILE__, " ", @__LINE__)
|
||||
println("Attempt $attempt $errornote ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
continue
|
||||
end
|
||||
end
|
||||
@@ -503,7 +503,7 @@ function evaluator(config::T1, state::T2
|
||||
showerror(io, e)
|
||||
errorMsg = String(take!(io))
|
||||
st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
|
||||
println("\nAttempt $attempt. Error occurred: $errorMsg\n$st ", @__FILE__, " ", @__LINE__)
|
||||
println("\nAttempt $attempt. Error occurred: $errorMsg\n$st ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
end
|
||||
end
|
||||
error("evaluator failed to generate an evaluation")
|
||||
@@ -633,7 +633,7 @@ function reflector(config::T1, state::T2)::String where {T1<:AbstractDict,T2<:Ab
|
||||
showerror(io, e)
|
||||
errorMsg = String(take!(io))
|
||||
st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
|
||||
println("\nAttempt $attempt. Error occurred: $errorMsg\n$st ", @__FILE__, " ", @__LINE__)
|
||||
println("\nAttempt $attempt. Error occurred: $errorMsg\n$st ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
end
|
||||
end
|
||||
error("reflector failed to generate a thought")
|
||||
@@ -733,7 +733,7 @@ function conversation(a::sommelier, userinput::Dict)
|
||||
end
|
||||
end
|
||||
|
||||
function conversation(a::companion, userinput::Dict)
|
||||
function conversation(a::companion, userinput::Dict; maximumMsg=30)
|
||||
chatresponse = nothing
|
||||
|
||||
if userinput[:text] == "newtopic"
|
||||
@@ -754,7 +754,7 @@ function conversation(a::companion, userinput::Dict)
|
||||
)
|
||||
chatresponse = generatechat(a)
|
||||
|
||||
addNewMessage(a, "assistant", chatresponse)
|
||||
addNewMessage(a, "assistant", chatresponse; maximumMsg=30)
|
||||
|
||||
push!(a.memory[:events],
|
||||
eventdict(;
|
||||
@@ -871,7 +871,7 @@ function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} wh
|
||||
)
|
||||
)
|
||||
else
|
||||
error("condition is not defined ", @__FILE__, " ", @__LINE__)
|
||||
error("condition is not defined ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
end
|
||||
|
||||
|
||||
@@ -928,6 +928,7 @@ function generatechat(a::sommelier, thoughtDict)
|
||||
- If the user interrupts, prioritize the user
|
||||
- Medium and full-bodied red wines should not be paired with spicy foods.
|
||||
|
||||
|
||||
You should then respond to the user with:
|
||||
1) Chat: Given the situation, How would you respond to the user to express your thoughts honestly and keep the conversation going smoothly?
|
||||
|
||||
@@ -977,7 +978,7 @@ function generatechat(a::sommelier, thoughtDict)
|
||||
# sometime the model response like this "here's how I would respond: ..."
|
||||
if occursin("respond:", response)
|
||||
errornote = "You don't need to intro your response"
|
||||
error("generatechat() response contain : ", @__FILE__, " ", @__LINE__)
|
||||
error("generatechat() response contain : ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
end
|
||||
response = GeneralUtils.remove_french_accents(response)
|
||||
response = replace(response, '*'=>"")
|
||||
@@ -989,7 +990,7 @@ function generatechat(a::sommelier, thoughtDict)
|
||||
|
||||
for i ∈ [:chat]
|
||||
if length(JSON3.write(responsedict[i])) == 0
|
||||
error("$i is empty ", @__FILE__, " ", @__LINE__)
|
||||
error("$i is empty ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1006,7 +1007,7 @@ function generatechat(a::sommelier, thoughtDict)
|
||||
error("Context: is in text. This is not allowed")
|
||||
end
|
||||
|
||||
println("\n~~~ generatechat() ", @__FILE__, " ", @__LINE__)
|
||||
println("\n~~~ generatechat() ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
pprintln(Dict(responsedict))
|
||||
|
||||
# check whether an agent recommend wines before checking inventory or recommend wines
|
||||
@@ -1044,7 +1045,7 @@ function generatechat(a::sommelier, thoughtDict)
|
||||
showerror(io, e)
|
||||
errorMsg = String(take!(io))
|
||||
st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
|
||||
println("\nAttempt $attempt. Error occurred: $errorMsg\n$st ", @__FILE__, " ", @__LINE__)
|
||||
println("\nAttempt $attempt. Error occurred: $errorMsg\n$st ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
end
|
||||
end
|
||||
error("generatechat failed to generate a response")
|
||||
@@ -1137,6 +1138,12 @@ function generatequestion(a, text2textInstructLLM::Function; recent=nothing)::St
|
||||
- If you don't already know, find out the characteristics of wine the user is looking for, such as tannin, sweetness, intensity, acidity
|
||||
- If you don't already know, find out what food will be served with wine
|
||||
- If you haven't already, introduce the wines you found in the database to the user first
|
||||
- Generally speaking, your inventory has some wines from France, the United States, Australia, Spain, and Italy, but you won't know exactly until you check your inventory.
|
||||
- All wines in your inventory are always in stock.
|
||||
- Engage in conversation to indirectly investigate the customer's intention, budget and preferences before checking your inventory.
|
||||
- Do not ask the user about wine's flavor e.g. floral, citrusy, nutty or some thing similar as these terms cannot be used to search the database.
|
||||
- Once the user has selected their wine, ask the user if they need any further assistance. Do not offer any additional services. If the user doesn't need any further assistance, say goodbye and invite them to come back next time.
|
||||
- Medium and full-bodied red wines should not be paired with spicy foods.
|
||||
|
||||
You should then respond to the user with:
|
||||
1) Understanding:
|
||||
@@ -1251,17 +1258,17 @@ function generatequestion(a, text2textInstructLLM::Function; recent=nothing)::St
|
||||
# check for valid response
|
||||
q_atleast = length(a.memory[:events]) <= 2 ? 1 : 3
|
||||
if q_number < q_atleast
|
||||
error("too few questions only $q_number questions are generated ", @__FILE__, " ", @__LINE__)
|
||||
error("too few questions only $q_number questions are generated ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
# check whether "A1" is in the response, if not error.
|
||||
elseif !occursin("A1:", response)
|
||||
error("no answer found in the response ", @__FILE__, " ", @__LINE__)
|
||||
error("no answer found in the response ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
end
|
||||
|
||||
responsedict = GeneralUtils.textToDict(response,
|
||||
["Understanding", "Q1"],
|
||||
rightmarker=":", symbolkey=true, lowercasekey=true)
|
||||
response = "Q1: " * responsedict[:q1]
|
||||
println("\n~~~ generatequestion ", @__FILE__, " ", @__LINE__)
|
||||
println("\n~~~ generatequestion ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
pprintln(response)
|
||||
return response
|
||||
catch e
|
||||
@@ -1269,7 +1276,7 @@ function generatequestion(a, text2textInstructLLM::Function; recent=nothing)::St
|
||||
showerror(io, e)
|
||||
errorMsg = String(take!(io))
|
||||
st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
|
||||
println("\nAttempt $attempt. Error occurred: $errorMsg\n$st ", @__FILE__, " ", @__LINE__)
|
||||
println("\nAttempt $attempt. Error occurred: $errorMsg\n$st ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
end
|
||||
end
|
||||
error("generatequestion failed to generate a response ", response)
|
||||
@@ -1345,7 +1352,7 @@ function generateSituationReport(a, text2textInstructLLM::Function; skiprecent::
|
||||
# responsedict = GeneralUtils.textToDict(response,
|
||||
# ["summary", "presented", "selected"],
|
||||
# rightmarker=":", symbolkey=true)
|
||||
println("\n~~~ generateSituationReport() ", @__FILE__, " ", @__LINE__)
|
||||
println("\n~~~ generateSituationReport() ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
pprintln(response)
|
||||
|
||||
return Dict(:recap => response)
|
||||
@@ -1401,7 +1408,7 @@ function detectWineryName(a, text)
|
||||
|
||||
try
|
||||
response = a.func[:text2textInstructLLM](prompt)
|
||||
println("\n~~~ detectWineryName() ", @__FILE__, " ", @__LINE__)
|
||||
println("\n~~~ detectWineryName() ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
pprintln(response)
|
||||
|
||||
responsedict = GeneralUtils.textToDict(response, ["winery_names"],
|
||||
@@ -1415,7 +1422,7 @@ function detectWineryName(a, text)
|
||||
showerror(io, e)
|
||||
errorMsg = String(take!(io))
|
||||
st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
|
||||
println("\n Attempt $attempt. Error occurred: $errorMsg\n$st ", @__FILE__, " ", @__LINE__)
|
||||
println("\n Attempt $attempt. Error occurred: $errorMsg\n$st ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
end
|
||||
end
|
||||
error("detectWineryName failed to generate a response")
|
||||
|
||||
@@ -291,20 +291,20 @@ julia> result = checkinventory(agent, input)
|
||||
function checkinventory(a::T1, input::T2
|
||||
) where {T1<:agent, T2<:AbstractString}
|
||||
|
||||
println("\n~~~ checkinventory order: $input ", @__FILE__, " ", @__LINE__)
|
||||
println("\n~~~ checkinventory order: $input ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
wineattributes_1 = extractWineAttributes_1(a, input)
|
||||
wineattributes_2 = extractWineAttributes_2(a, input)
|
||||
|
||||
_inventoryquery = "retailer name: $(a.retailername), $wineattributes_1, $wineattributes_2"
|
||||
inventoryquery = "Retrieves winery, wine_name, vintage, region, country, wine_type, grape, serving_temperature, sweetness, intensity, tannin, acidity, tasting_notes, price and currency of wines that match the following criteria - {$_inventoryquery}"
|
||||
println("~~~ checkinventory input: $inventoryquery ", @__FILE__, " ", @__LINE__)
|
||||
println("~~~ checkinventory input: $inventoryquery ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
# add suppport for similarSQLVectorDB
|
||||
textresult, rawresponse = SQLLLM.query(inventoryquery, a.func[:executeSQL],
|
||||
a.func[:text2textInstructLLM],
|
||||
insertSQLVectorDB=a.func[:insertSQLVectorDB],
|
||||
similarSQLVectorDB=a.func[:similarSQLVectorDB])
|
||||
|
||||
println("\n~~~ checkinventory result ", @__FILE__, " ", @__LINE__)
|
||||
println("\n~~~ checkinventory result ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
println(textresult)
|
||||
|
||||
return (result=textresult, rawresponse=rawresponse, success=true, errormsg=nothing)
|
||||
@@ -403,7 +403,7 @@ function extractWineAttributes_1(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
for word in attributes
|
||||
if !occursin(word, response)
|
||||
errornote = "$word attribute is missing in previous attempts"
|
||||
println("Attempt $attempt $errornote ", @__FILE__, " ", @__LINE__)
|
||||
println("Attempt $attempt $errornote ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
checkFlag = true
|
||||
break
|
||||
end
|
||||
@@ -431,7 +431,7 @@ function extractWineAttributes_1(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
# check whether wine_price is in ranged number
|
||||
if !occursin('-', responsedict[:wine_price])
|
||||
errornote = "wine_price must be a range number"
|
||||
println("Attempt $attempt $errornote ", @__FILE__, " ", @__LINE__)
|
||||
println("Attempt $attempt $errornote ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
checkFlag = true
|
||||
break
|
||||
end
|
||||
@@ -454,7 +454,7 @@ function extractWineAttributes_1(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
for x in content #BUG why x is "0-1500"
|
||||
if !occursin("NA", responsedict[j]) && !occursin(x, input)
|
||||
errornote = "$x is not mentioned in the user query, you must only use the info from the query."
|
||||
println("Attempt $attempt $errornote ", @__FILE__, " ", @__LINE__)
|
||||
println("Attempt $attempt $errornote ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
checkFlag == true
|
||||
break
|
||||
end
|
||||
@@ -624,7 +624,7 @@ function extractWineAttributes_2(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
value = responsedict[keyword]
|
||||
if value != "NA" && !occursin(value, input)
|
||||
errornote = "WARNING. Keyword $keyword: $value does not appear in the input. You must use information from the input only"
|
||||
println("Attempt $attempt $errornote ", @__FILE__, " ", @__LINE__)
|
||||
println("Attempt $attempt $errornote ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
continue
|
||||
end
|
||||
|
||||
@@ -640,7 +640,7 @@ function extractWineAttributes_2(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
if !occursin("keyword", string(k))
|
||||
if v !== "NA" && (!occursin('-', v) || length(v) > 5)
|
||||
errornote = "WARNING: The non-range value {$k: $v} is not allowed. It should be specified in a range format, i.e. min-max."
|
||||
println("Attempt $attempt $errornote ", @__FILE__, " ", @__LINE__)
|
||||
println("Attempt $attempt $errornote ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
continue
|
||||
end
|
||||
end
|
||||
@@ -859,7 +859,7 @@ end
|
||||
# state[:isterminal] = true
|
||||
# state[:reward] = 1
|
||||
# end
|
||||
# println("--> 5 Evaluator ", @__FILE__, " ", @__LINE__)
|
||||
# println("--> 5 Evaluator ", Dates.now(), " ", @__FILE__, " ", @__LINE__)
|
||||
# pprintln(Dict(responsedict))
|
||||
# return responsedict[:score]
|
||||
# catch e
|
||||
|
||||
@@ -106,7 +106,7 @@ function addNewMessage(a::T1, name::String, text::T2;
|
||||
error("name is not in agent.availableRole $(@__LINE__)")
|
||||
end
|
||||
|
||||
#[] summarize the oldest 10 message
|
||||
#[WORKING] summarize the oldest 10 message
|
||||
if length(a.chathistory) > maximumMsg
|
||||
summarize(a.chathistory)
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user