This commit is contained in:
narawat lamaiin
2025-05-18 17:21:51 +07:00
parent 3a88e0e7d4
commit 919d8ec85e
2 changed files with 56 additions and 28 deletions

View File

@@ -249,8 +249,9 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
<context>
<Available tools>
- CHATBOX which you can use to talk with the user. Be specific.
- CHECKINVENTORY allows you to check information about wines you want in your inventory's database. The input must be supported search criteria includeing: wine price, winery, name, vintage, region, country, type, grape varietal, tasting notes, occasion, food pairing, intensity, tannin, sweetness, and acidity.
Example query: "Dry, full-bodied red wine from Burgundy, France or Tuscany, Italy. Merlot varietal. price 100 to 1000 USD."
- CHECKWINE allows you to check information about wines you want in your inventory's database. The input must be supported search criteria includeing: wine price, winery, name, vintage, region, country, type, grape varietal, tasting notes, occasion, food pairing, intensity, tannin, sweetness, and acidity.
Example query 1: "Dry, full-bodied red wine from Burgundy region, France or Tuscany region, Italy. Merlot varietal. price 100 to 1000 USD."
Example query 2: "Red wine, bold intensity, price under 300 USD"
- PRESENTBOX which you can use to present wines you have found in your inventory to the user. The input are wine names that you want to present.
- ENDCONVERSATION which you can use to properly end the conversation with the user. Input is a dialogue where you wrap up the conversation, thank the user, and invite them to return next time.
</Available tools>
@@ -332,9 +333,9 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
# responsedict = GeneralUtils.textToDict(response, header;
# dictKey=dictkey, symbolkey=true)
if responsedict[:action_name] ["CHATBOX", "CHECKINVENTORY", "PRESENTBOX", "ENDCONVERSATION"]
if responsedict[:action_name] ["CHATBOX", "CHECKWINE", "PRESENTBOX", "ENDCONVERSATION"]
errornote = "Your previous attempt didn't use the given functions"
println("\nERROR YiemAgent decisionMaker() $errornote ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
println("\nERROR YiemAgent decisionMaker() $errornote --> $(responsedict[:action_name])", @__FILE__, ":", @__LINE__, " $(Dates.now())")
continue
end
@@ -420,7 +421,7 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
if evaluationdict[:approved] == "no"
mentor_comment = evaluationdict[:suggestion]
errornote = "Your previous attempt was not good enough. Please try again. Here is the mentor's suggestion: $mentor_comment"
println("\nERROR YiemAgent decisionMaker() - $response ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
println("\nERROR YiemAgent decisionMaker() $errornote --> \n$response ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
continue
end
@@ -814,7 +815,7 @@ function evaluator(a::T1, timeline, decisiondict, evaluateecontext
- Under your supervision, a trainee sommelier is engaging with a store customer. Each time the customer speaks, the trainee will assess the situation, determine the next course of action, and pause to await your guidance before proceeding.
</Situation>
<Your mission>
- To improve a trainee sommelier decision based on the store policy and guidelines.
- Improve a trainee sommelier decision based on the store policy and guidelines while ensuring seamless interactions between the trainee and customers.
</Your mission>
<At each round of conversation, you will be given the following information>
- trajectory: A conversation between your trainee and the customer that have occurred up until now
@@ -1084,7 +1085,7 @@ function conversation(a::Union{companion, virtualcustomer}, userinput::Dict;
actioninput=userinput[:text],
)
)
chatresponse = generatechat(a; converPartnerName=converPartnerName)
chatresponse = generatechat(a; converPartnerName=converPartnerName, recentEventNum=20)
addNewMessage(a, "assistant", chatresponse; maximumMsg=maximumMsg)
@@ -1127,8 +1128,8 @@ function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} wh
response =
if actionname == "CHATBOX" || actionname == "ENDCONVERSATION"
(result=thoughtDict[:plan], errormsg=nothing, success=true)
elseif actionname == "CHECKINVENTORY"
checkinventory(a, actioninput)
elseif actionname == "CHECKWINE"
checkwine(a, actioninput)
elseif actionname == "PRESENTBOX"
(result=actioninput, errormsg=nothing, success=true)
# elseif actionname == "ENDCONVERSATION"
@@ -1200,7 +1201,7 @@ function think(a::T)::NamedTuple{(:actionname, :result),Tuple{String,String}} wh
)
result = chatresponse
elseif actionname == "CHECKINVENTORY"
elseif actionname == "CHECKWINE"
if rawresponse !== nothing
vd = GeneralUtils.dfToVectorDict(rawresponse) # comes in dataframe format
a.memory[:shortmem][:found_wine] = vd # used by decisionMaker() as a short note
@@ -1417,6 +1418,17 @@ function presentbox(a::sommelier, thoughtDict; maxtattempt::Integer=10, recentev
if isWineInEvent == false
errornote = "Your previous response recommended wines that is not in your inventory which is not allowed"
println("\nERROR YiemAgent presentbox() $errornote ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
s = """
Perfect choice! The Colgin Tychson Hill Vineyard Cabernet Sauvignon (2014) is an excellent match for your criteria. Here's why:
Boldness & Flavor: This wine delivers intense blackberry, black cherry, and dark fruit notes, layered with vanilla, oak, and earthy undertones. Its high intensity (rated 5/5) ensures a rich, full-bodied experience that's both powerful and balanced.
Family-Owned Legacy: Produced by Colgin Cellars, a renowned Napa Valley family winery, this vintage reflects their commitment to quality and tradition. While not a limited-edition release, it's a highly regarded, consistently excellent Cabernet Sauvignon.
Gift-Ready & Affordable: Priced at USD144 (well under your USD250 budget), it comes in a sleek, gift-ready box—perfect for impressing friends or loved ones.
Why I Recommend It: It perfectly balances your desire for bold fruit, oak, and a presentable format without sacrificing quality. If you're curious about alternatives, the 2017 Hunter Glenn Cabernet (also USD159) shares similar intensity but lacks specific tasting notes. However, the 2014 Tychson Hill is a more complete match for your criteria. Enjoy your selection!"""
continue
end
end
@@ -1923,8 +1935,7 @@ function generatechat(a::virtualcustomer;
converPartnerName::Union{String, Nothing}=nothing, maxattempt=10, recentEventNum=10
)
recent_ind = GeneralUtils.recentElementsIndex(length(a.memory[:events]), recentEventNum; includelatest=true)
recentevents = a.memory[:events][recent_ind]
recentEventsDict = createEventsLog(recentevents; index=recent_ind)
recentEventsDict = createEventsLog(a.memory[:events]; index=recent_ind)
response = nothing # placeholder for show when error msg show up
errornote = "N/A"
header = ["Dialogue:", "Role"]

View File

@@ -1,6 +1,6 @@
module llmfunction
export virtualWineUserChatbox, jsoncorrection, checkinventory, # recommendbox,
export virtualWineUserChatbox, jsoncorrection, checkwine, # recommendbox,
virtualWineUserRecommendbox, userChatbox, userRecommendbox, extractWineAttributes_1,
extractWineAttributes_2, paraphrase
@@ -288,17 +288,25 @@ julia> result = checkinventory(agent, input)
# Signature
"""
function checkinventory(a::T1, input::T2
function checkwine(a::T1, input::T2; maxattempt::Int=3
) where {T1<:agent, T2<:AbstractString}
println("\ncheckinventory order: $input ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
wineattributes_1 = extractWineAttributes_1(a, input)
wineattributes_2 = extractWineAttributes_2(a, input)
# placeholder
textresult = nothing
rawresponse = nothing
for i in 1:maxattempt
#CHANGE if you want to add retailer name
# _inventoryquery = "retailer name: $(a.retailername), $wineattributes_1, $wineattributes_2"
_inventoryquery = "$wineattributes_1, $wineattributes_2"
inventoryquery = "Retrieves winery, wine_name, wine_id, 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}"
retrieve_attributes = ["winery", "wine_name", "wine_id", "vintage", "region", "country", "wine_type", "grape", "serving_temperature", "sweetness", "intensity", "tannin", "acidity", "tasting_notes", "price", "currency"]
inventoryquery = "Retrieves $retrieve_attributes of wines that match the following criteria - {$_inventoryquery}"
println("\ncheckinventory input: $inventoryquery ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
# add suppport for similarSQLVectorDB
textresult, rawresponse = SQLLLM.query(inventoryquery, a.func[:executeSQL],
@@ -306,10 +314,19 @@ function checkinventory(a::T1, input::T2
insertSQLVectorDB=a.func[:insertSQLVectorDB],
similarSQLVectorDB=a.func[:similarSQLVectorDB],
llmFormatName="qwen3")
#[PENDING] sometime wine data comeout {wine name, price, wine_id} and nothing else. I need to make sure that wine data include all of its attributes
# check if all of retrieve_attributes appears in textresult
isin = [occursin(x, textresult) for x in retrieve_attributes]
if !all(isin) && !occursin("The resulting table has 0 row", textresult)
errornote = "Not all of $retrieve_attributes appear in search result"
println("\nERROR YiemAgent checkwine() $errornote ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
continue
else
break
end
end
println("\ncheckinventory result ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
println(textresult)
#[PENDING] if there is no wine id, it is not a valid result
return (result=textresult, rawresponse=rawresponse, success=true, errormsg=nothing)
end
@@ -352,7 +369,7 @@ function extractWineAttributes_1(a::T1, input::T2; maxattempt=10
wine_name: name of the wine
winery: name of the winery
vintage: the year of the wine
region: a region (NOT a country) where the wine is produced, such as Burgundy, Napa Valley, etc
region: a region, such as Burgundy, Bordeaux, Champagne, Napa Valley, Tuscany, California, Oregon, etc
country: a country where wine is produced. Can be "Austria", "Australia", "France", "Germany", "Italy", "Portugal", "Spain", "United States"
wine_type: can be one of: "red", "white", "sparkling", "rose", "dessert" or "fortified"
grape_varietal: the name of the primary grape used to make the wine