This commit is contained in:
2024-12-22 20:40:13 +07:00
parent 00f1a6775b
commit 27944a178b
2 changed files with 36 additions and 30 deletions

View File

@@ -173,6 +173,7 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
- All wines in your inventory are always in stock.
- If the user interrupts, prioritize the user
- 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.
- The best strategy for searching an inventory is to start broadly and then narrow down.
- 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.
Tips:
@@ -255,6 +256,7 @@ function decisionMaker(a::T; recent::Integer=5)::Dict{Symbol,Any} where {T<:agen
try
response = a.func[:text2textInstructLLM](prompt)
response = GeneralUtils.remove_french_accents(response)
responsedict = GeneralUtils.textToDict(response,
["Understanding", "Reasoning", "Plan", "Action_name", "Action_input"],
rightmarker=":", symbolkey=true, lowercasekey=true)
@@ -697,7 +699,7 @@ function conversation(a::sommelier, userinput::Dict)
# thinking loop until AI wants to communicate with the user
chatresponse = nothing
for i in 1:3
for i in 1:5
actionname, result = think(a)
if actionname ["CHATBOX", "PRESENTBOX", "ENDCONVERSATION"]
chatresponse = result
@@ -773,7 +775,7 @@ function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} wh
# map action and input() to llm function
response =
if actionname == "CHATBOX"
input = thoughtDict[:plan]
input = thoughtDict[:action_input]
(result=input, errormsg=nothing, success=true)
elseif actionname == "CHECKINVENTORY"
checkinventory(a, actioninput)
@@ -1338,7 +1340,7 @@ function detectWineryName(a, text)
Text: a text describing the situation.
Tips:
- Winery usually contains Château, Chateau, Domaine, Côte, Cote, St. de, or a combination of these words.
- Winery usually contains Château, Chateau, Domaine, Côte, Cotes, St. de, or a combination of these words.
You should then respond to the user with:
Winery_names: A list of winery names mentioned in the text or "None" if no winery name is mentioned.
@@ -1347,7 +1349,7 @@ function detectWineryName(a, text)
Winery_names: ...
Here are some examples:
Winery_names: Domaine Courbis, Chateau Lafite Rothschild, Matarromera Domaine Roulot, Château
Winery_names: Domaine Courbis, Chateau Lafite Rothschild, Matarromera Domaine Roulot, Château, Cotes
Let's begin!
"""

View File

@@ -421,6 +421,7 @@ function extractWineAttributes_1(a::T1, input::T2)::String where {T1<:agent, T2<
try
response = a.func[:text2textInstructLLM](prompt)
response = GeneralUtils.remove_french_accents(response)
# check wheter all attributes are in the response
for word in attributes
@@ -431,15 +432,13 @@ function extractWineAttributes_1(a::T1, input::T2)::String where {T1<:agent, T2<
responsedict = GeneralUtils.textToDict(response, attributes, rightmarker=":", symbolkey=true)
#[WORKING] check if winery, wine_name, region, country, wine_type, grape_variety are in the query because sometime AI halucinates
for i attributes
if length(JSON3.write(responsedict[Symbol(i)])) == 0
error("$i is empty ", @__LINE__)
end
end
#[PENDING] check if the following attributes has more than 1 name
#check if the following attributes has more than 1 name
responsedict[:grape_variety] = split(responsedict[:grape_variety], ',')[1]
responsedict[:grape_variety] = split(responsedict[:grape_variety], '/')[1]
@@ -449,33 +448,24 @@ function extractWineAttributes_1(a::T1, input::T2)::String where {T1<:agent, T2<
responsedict[:region] = split(responsedict[:region], ',')[1]
responsedict[:region] = split(responsedict[:region], '/')[1]
# check if grape_variety is mentioned in the input
if !occursin("NA", responsedict[:grape_variety]) && !occursin(responsedict[:grape_variety], input)
if attempt < maxattempt
errornote = "$(responsedict[:grape_variety]) is not mentioned in the user query, you must only use the info from the query."
error("$(responsedict[:grape_variety]) is not mentioned in the user query, you must only use the info from the query.")
else
responsedict[:grape_variety] = "NA"
end
end
# check if region is mentioned in the input
if !occursin("NA", responsedict[:region]) && !occursin(responsedict[:region], input)
if attempt < maxattempt
errornote = "$(responsedict[:region]) is not mentioned in the user query, you must only use the info from the query.."
error("$(responsedict[:region]) is not mentioned in the user query, you must only use the info from the query..")
else
responsedict[:region] = "NA"
end
end
# delete!(responsedict, :region)
delete!(responsedict, :reasoning)
# delete!(responsedict, :tasting_notes)
# delete!(responsedict, :price)
delete!(responsedict, :tasting_notes)
delete!(responsedict, :occasion)
delete!(responsedict, :food_to_be_paired_with_wine)
# check if winery, wine_name, region, country, wine_type, grape_variety are in the query because sometime AI halucinates
for i in [:grape_variety, :winery, :wine_name, :region]
result = check_key_in_input(input, responsedict, attempt, maxattempt, i)
if result === nothing
# nothing wrong
elseif result == "NA"
responsedict[i] = "NA"
else
errornote = result
error(errornote)
end
end
# remove (some text)
for (k, v) in responsedict
_v = replace(v, r"\(.*?\)" => "")
@@ -900,6 +890,20 @@ function jsoncorrection(config::T1, input::T2, correctJsonExample::T3;
end
function check_key_in_input(input::String, responsedict, attempt::Int, maxattempt::Int, key::Symbol)
if !occursin("NA", responsedict[key]) && !occursin(responsedict[key], input)
if attempt < maxattempt
errornote = "$(responsedict[key]) is not mentioned in the user query, you must only use the info from the query."
return errornote
else
return "NA"
end
else
return nothing
end
end
# function isrecommend(state::T1, text2textInstructLLM::Function
# ) where {T1<:AbstractDict}