update
This commit is contained in:
@@ -9,81 +9,6 @@ using ..type, ..util
|
||||
|
||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
||||
|
||||
"""
|
||||
|
||||
# Arguments
|
||||
|
||||
# Return
|
||||
|
||||
# Example
|
||||
```jldoctest
|
||||
julia>
|
||||
```
|
||||
|
||||
# TODO
|
||||
- [] update docstring
|
||||
- [WORKING] implement the function
|
||||
|
||||
# Signature
|
||||
"""
|
||||
function userChatbox(a::T1, input::T2) where {T1<:agent, T2<:AbstractString}
|
||||
error("--> userChatbox")
|
||||
|
||||
# put in model format
|
||||
virtualWineCustomer = a.config[:externalservice][:virtualWineCustomer_1]
|
||||
llminfo = virtualWineCustomer[:llminfo]
|
||||
formattedinput =
|
||||
if llminfo[:name] == "llama3instruct"
|
||||
formatLLMtext_llama3instruct("assistant", input)
|
||||
else
|
||||
error("llm model name is not defied yet $(@__LINE__)")
|
||||
end
|
||||
|
||||
# send formatted input to user using GeneralUtils.sendReceiveMqttMsg
|
||||
|
||||
|
||||
# return response
|
||||
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
|
||||
# Arguments
|
||||
|
||||
# Return
|
||||
|
||||
# Example
|
||||
```jldoctest
|
||||
julia>
|
||||
```
|
||||
|
||||
# TODO
|
||||
- [] update docstring
|
||||
- [PENDING] implement the function
|
||||
|
||||
# Signature
|
||||
"""
|
||||
function userRecommendbox(a::T1, input::T2) where {T1<:agent, T2<:AbstractString}
|
||||
error("--> userRecommendbox")
|
||||
|
||||
# put in model format
|
||||
virtualWineCustomer = a.config[:externalservice][:virtualWineCustomer_1]
|
||||
llminfo = virtualWineCustomer[:llminfo]
|
||||
formattedinput =
|
||||
if llminfo[:name] == "llama3instruct"
|
||||
formatLLMtext_llama3instruct("assistant", input)
|
||||
else
|
||||
error("llm model name is not defied yet $(@__LINE__)")
|
||||
end
|
||||
|
||||
# send formatted input to user using GeneralUtils.sendReceiveMqttMsg
|
||||
|
||||
|
||||
# return response
|
||||
|
||||
end
|
||||
|
||||
|
||||
""" Chatbox for chatting with virtual wine customer.
|
||||
|
||||
@@ -363,15 +288,15 @@ julia> result = checkinventory(agent, input)
|
||||
# Signature
|
||||
"""
|
||||
function checkinventory(a::T1, input::T2
|
||||
)::Union{Tuple{String, Number, Number, Bool}, Tuple{String, Nothing, Number, Bool}} where {T1<:agent, T2<:AbstractString}
|
||||
)::NamedTuple{(:result, :success, :errormsg), Tuple{String, Bool, Union{String, Nothing}}} where {T1<:agent, T2<:AbstractString}
|
||||
|
||||
wineattributes_1 = extractWineAttributes_1(a, input)
|
||||
wineattributes_2 = extractWineAttributes_2(a, input)
|
||||
|
||||
inventoryquery = "$wineattributes_1, $wineattributes_2"
|
||||
|
||||
println("--> checkinventory: $inventoryquery")
|
||||
result = SQLLLM.query(inventoryquery, a.executeSQL, a.text2textInstructLLM)
|
||||
return result
|
||||
return (result=result, success=true, errormsg=nothing)
|
||||
end
|
||||
|
||||
|
||||
@@ -399,7 +324,7 @@ function extractWineAttributes_1(a::T1, input::T2
|
||||
|
||||
systemmsg =
|
||||
"""
|
||||
As an helpful sommelier, your task is to fill the user's preference form based on the user query.
|
||||
As an helpful sommelier, your task is to fill out the user's preference form by copying the corresponding words from the user's query.
|
||||
|
||||
At each round of conversation, the user will give you the current situation:
|
||||
User query: ...
|
||||
@@ -415,14 +340,14 @@ function extractWineAttributes_1(a::T1, input::T2
|
||||
|
||||
You should then respond to the user with the following points:
|
||||
- wine_type: Can be one of: red, white, sparkling, rose, dessert or fortified
|
||||
- price: ...
|
||||
- price: Must be an integer representing the cost of the wine.
|
||||
|
||||
- occasion: ...
|
||||
- food_to_be_paired_with_wine: food that will be served with wine
|
||||
- country: wine's country of origin
|
||||
- grape_variety: ...
|
||||
- wine_notes:
|
||||
Bad example (these words are not wine notes - descriptive words): dry, sour, full bodied, etc.
|
||||
Good example (these words are wine notes - descriptive words): floral, citrus, earthy, fruity, tropical, nutty, etc.
|
||||
- tasting_notes: dry, full bodied or something similar
|
||||
- flavor: what the wine tast like? e.g. floral, citrus, earthy, fruity, tropical, nutty or something similar
|
||||
|
||||
You should only respond in the form as described below:
|
||||
wine_type: ...
|
||||
@@ -431,7 +356,8 @@ function extractWineAttributes_1(a::T1, input::T2
|
||||
food_to_be_paired_with_wine: ...
|
||||
country: ...
|
||||
grape_variety: ...
|
||||
wine_notes: ...
|
||||
tasting_notes: ...
|
||||
flavor: ...
|
||||
|
||||
Let's begin!
|
||||
"""
|
||||
@@ -454,7 +380,7 @@ function extractWineAttributes_1(a::T1, input::T2
|
||||
<|start_header_id|>assistant<|end_header_id|>
|
||||
"""
|
||||
|
||||
attributes = ["wine_type", "price", "occasion", "food_to_be_paired_with_wine", "country", "grape_variety"]
|
||||
attributes = ["wine_type", "price", "occasion", "food_to_be_paired_with_wine", "country", "grape_variety", "tasting_notes", "flavor"]
|
||||
|
||||
for attempt in 1:5
|
||||
try
|
||||
@@ -467,6 +393,10 @@ function extractWineAttributes_1(a::T1, input::T2
|
||||
end
|
||||
end
|
||||
|
||||
#[TESTING] remove tasting_notes because the database didn't prepare to be search using it
|
||||
responsedict[:tasting_notes] = "NA"
|
||||
responsedict[:flavor] = "NA"
|
||||
|
||||
result = ""
|
||||
for (k, v) in responsedict
|
||||
if !occursin("NA", v)
|
||||
@@ -474,6 +404,9 @@ function extractWineAttributes_1(a::T1, input::T2
|
||||
end
|
||||
end
|
||||
|
||||
#[WORKING] remove halucination. "highend dry white wine" --> "wine_type: white, occasion: special occasion, food_to_be_paired_with_wine: seafood, fish, country: France, Italy, USA, grape_variety: Chardonnay, Sauvignon Blanc, Pinot Grigio\nwine_notes: citrus, green apple, floral"
|
||||
|
||||
|
||||
result = result[1:end-2] # remove the ending ", "
|
||||
|
||||
return result
|
||||
@@ -498,29 +431,29 @@ function extractWineAttributes_2(a::T1, input::T2
|
||||
"""
|
||||
Conversion Table:
|
||||
Intensity level:
|
||||
1: May correspond to "light-bodied" or a similar description.
|
||||
2: May correspond to "med light", "medium light" or a similar description.
|
||||
3: May correspond to "medium" or a similar description.
|
||||
4: May correspond to "med full", "medium full" or a similar description.
|
||||
5: May correspond to "full" or a similar description.
|
||||
1 to 2: May correspond to "light-bodied" or a similar description.
|
||||
2 to 3: May correspond to "med light bodied", "medium light" or a similar description.
|
||||
3 to 4: May correspond to "medium bodied" or a similar description.
|
||||
4 to 5: May correspond to "med full bodied", "medium full" or a similar description.
|
||||
4 to 5: May correspond to "full bodied" or a similar description.
|
||||
Sweetness level:
|
||||
1: May correspond to "dry", "no sweet" or a similar description.
|
||||
2: May correspond to "off dry", "less sweet" or a similar description.
|
||||
3: May correspond to "semi sweet" or a similar description.
|
||||
4: May correspond to "sweet" or a similar description.
|
||||
5: May correspond to "very sweet" or a similar description.
|
||||
1 to 2: May correspond to "dry", "no sweet" or a similar description.
|
||||
2 to 3: May correspond to "off dry", "less sweet" or a similar description.
|
||||
3 to 4: May correspond to "semi sweet" or a similar description.
|
||||
4 to 5: May correspond to "sweet" or a similar description.
|
||||
4 to 5: May correspond to "very sweet" or a similar description.
|
||||
Tannin level:
|
||||
1: May correspond to "low tannin" or a similar description.
|
||||
2: May correspond to "semi low tannin" or a similar description.
|
||||
3: May correspond to "medium tannin" or a similar description.
|
||||
4: May correspond to "semi high tannin" or a similar description.
|
||||
5: May correspond to "high tannin" or a similar description.
|
||||
1 to 2: May correspond to "low tannin" or a similar description.
|
||||
2 to 3: May correspond to "semi low tannin" or a similar description.
|
||||
3 to 4: May correspond to "medium tannin" or a similar description.
|
||||
4 to 5: May correspond to "semi high tannin" or a similar description.
|
||||
4 to 5: May correspond to "high tannin" or a similar description.
|
||||
Acidity level:
|
||||
1: May correspond to "low acidity" or a similar description.
|
||||
2: May correspond to "semi low acidity" or a similar description.
|
||||
3: May correspond to "medium acidity" or a similar description.
|
||||
4: May correspond to "semi high acidity" or a similar description.
|
||||
5: May correspond to "high acidity" or a similar description.
|
||||
1 to 2: May correspond to "low acidity" or a similar description.
|
||||
2 to 3: May correspond to "semi low acidity" or a similar description.
|
||||
3 to 4: May correspond to "medium acidity" or a similar description.
|
||||
4 to 5: May correspond to "semi high acidity" or a similar description.
|
||||
4 to 5: May correspond to "high acidity" or a similar description.
|
||||
"""
|
||||
|
||||
systemmsg =
|
||||
@@ -541,10 +474,10 @@ function extractWineAttributes_2(a::T1, input::T2
|
||||
3) Do not generate other comments.
|
||||
|
||||
You should then respond to the user with the following points:
|
||||
- sweetness: S where S is an integer indicating sweetness level
|
||||
- acidity: D where D is an integer indicating acidity level
|
||||
- tannin: T where T is an integer indicating tannin level
|
||||
- intensity: I where I is an integer indicating intensity level
|
||||
- sweetness: S where S are integers represent the range of sweetness levels e.g. 1-2
|
||||
- acidity: D where D are integers represent the range of acidity level e.g. 3-4
|
||||
- tannin: T where T are integers represent the range of tannin level e.g. 4-5
|
||||
- intensity: I where I are integers represent the range of intensity level e.g. 3-4
|
||||
|
||||
You should only respond in the form as described below:
|
||||
sweetness: ...
|
||||
@@ -587,6 +520,13 @@ function extractWineAttributes_2(a::T1, input::T2
|
||||
end
|
||||
end
|
||||
|
||||
# some time LLM think the user mentioning acidity and tannin but actually didn't
|
||||
for (k, v) in responsedict
|
||||
if k ∈ [:acidity, :tannin] && !occursin(string(k), input)
|
||||
responsedict[k] = "NA"
|
||||
end
|
||||
end
|
||||
|
||||
result = ""
|
||||
for (k, v) in responsedict
|
||||
if !occursin("NA", v)
|
||||
@@ -610,93 +550,6 @@ function extractWineAttributes_2(a::T1, input::T2
|
||||
error("wineattributes_wordToNumber() failed to get a response")
|
||||
end
|
||||
|
||||
# function recheckWineAttributes(a::T1, input::T2
|
||||
# )::String where {T1<:agent, T2<:AbstractString}
|
||||
|
||||
# systemmsg =
|
||||
# """
|
||||
# As an helpful sommelier, your task is to check what preferences the user mentioned in the query.
|
||||
|
||||
# At each round of conversation, the user will give you the current situation:
|
||||
# User query: ...
|
||||
|
||||
# The preferences are:
|
||||
# - wine type: red, white, sparkling, rose, dessert, fortified
|
||||
# - price
|
||||
# - occasion
|
||||
# - food to be paired with wine
|
||||
# - country
|
||||
# - grape_variety
|
||||
# - tasting_notes
|
||||
# - sweetness
|
||||
# - acidity
|
||||
# - tannin
|
||||
# - intensity: wine body e.g. full bodied, light bodied
|
||||
|
||||
# You should then respond to the user with the following points:
|
||||
# 1) mentioned_preferences: list all the preferences in the user's query.
|
||||
# Good example: mentioned_preferences: "price", "country", "wine type"
|
||||
|
||||
# You should only respond in the form as described below:
|
||||
# mentioned_preferences: ...
|
||||
|
||||
# Let's begin!
|
||||
# """
|
||||
|
||||
# usermsg =
|
||||
# """
|
||||
# User query: $input
|
||||
# """
|
||||
|
||||
# _prompt =
|
||||
# [
|
||||
# Dict(:name=> "system", :text=> systemmsg),
|
||||
# Dict(:name=> "user", :text=> usermsg)
|
||||
# ]
|
||||
|
||||
# # put in model format
|
||||
# prompt = GeneralUtils.formatLLMtext(_prompt, "llama3instruct")
|
||||
# prompt *=
|
||||
# """
|
||||
# <|start_header_id|>assistant<|end_header_id|>
|
||||
# """
|
||||
|
||||
# attributes = ["mentioned_preferences"]
|
||||
|
||||
# for attempt in 1:5
|
||||
# try
|
||||
# response = a.text2textInstructLLM(prompt)
|
||||
# responsedict = GeneralUtils.textToDict(response, attributes, rightmarker=":", symbolkey=true)
|
||||
|
||||
# for i ∈ attributes
|
||||
# if length(JSON3.write(responsedict[Symbol(i)])) == 0
|
||||
# error("$i is empty ", @__LINE__)
|
||||
# end
|
||||
# end
|
||||
|
||||
# result = ""
|
||||
# for (k, v) in responsedict
|
||||
# if !occursin("NA", v)
|
||||
# result *= "$k: $v, "
|
||||
# end
|
||||
# end
|
||||
|
||||
# result = result[1:end-2] # remove the ending ", "
|
||||
|
||||
# return result
|
||||
# catch e
|
||||
# io = IOBuffer()
|
||||
# showerror(io, e)
|
||||
# errorMsg = String(take!(io))
|
||||
# st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
|
||||
# println("")
|
||||
# println("Attempt $attempt. Error occurred: $errorMsg\n$st")
|
||||
# println("")
|
||||
# end
|
||||
# end
|
||||
# error("wineattributes_wordToNumber() failed to get a response")
|
||||
# end
|
||||
|
||||
|
||||
|
||||
""" Attemp to correct LLM response's incorrect JSON response.
|
||||
|
||||
Reference in New Issue
Block a user