update
This commit is contained in:
244
src/interface.jl
244
src/interface.jl
@@ -209,27 +209,28 @@ function decisionMaker(a::T)::Dict{Symbol, Any} where {T<:agent}
|
||||
# Let's begin!
|
||||
# """
|
||||
|
||||
QandA = generatequestion(a, a.text2textInstructLLM)
|
||||
|
||||
systemmsg =
|
||||
"""
|
||||
You are a helpful assistant acting as a polite, website-based sommelier for an online wine store.
|
||||
You are currently talking with the user.
|
||||
Your goal is to recommend the best wines from your inventory that match the user's preferences.
|
||||
You don't need to do any sale process.
|
||||
Your goal is: Help the user select the best wines from your inventory that align with the user's 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 are done choosing wines and invite them to comeback next time.
|
||||
|
||||
Your responsibility does not include:
|
||||
1) Processing sales orders or engaging in any other sales-related activities.
|
||||
|
||||
At each round of conversation, you will be given the current situation:
|
||||
Your conversation with the user: ...
|
||||
Recap: ...
|
||||
Context: ...
|
||||
Your Q&A: Your Q&A about the situation
|
||||
|
||||
You MUST follow the following guidelines:
|
||||
- Generally speaking, your inventory has some wines from France, the United States, Australia, Spain, and Italy, but you won't know which wines your store carries until you check your inventory.
|
||||
- All wines in your inventory are always in stock.
|
||||
- Use the "understand-then-check" inventory strategy to understand the user, as there are many wines in the 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 require any further assistance. Do not offer additional services.
|
||||
- If the user doesn't require any further assistance, use the ENDCONVERSATION function to end the conversation.
|
||||
- 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.
|
||||
|
||||
You should follow the following guidelines as you see fit:
|
||||
- If the user interrupts, prioritize the user.
|
||||
@@ -238,22 +239,20 @@ function decisionMaker(a::T)::Dict{Symbol, Any} where {T<:agent}
|
||||
- If you don't already know, find out the occasion for which the user is buying wine.
|
||||
- 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, compare the wines and present them to the user.
|
||||
- If you haven't already, present the wines you found to the user.
|
||||
|
||||
You should then respond to the user with interleaving Thought, Plan, Action:
|
||||
- thought:
|
||||
1) State your reasoning about the current situation.
|
||||
- plan: Based on the current situation, state a complete plan to complete the task. Be specific.
|
||||
- action_name (Must be aligned with your plan): The name of the action which can be one of the following functions:
|
||||
1) CHATBOX which you can use to generate conversation in order to communicate with the user. The input is your intention for the talk. Be specific.
|
||||
2) CHECKINVENTORY which you can use to check info about wine in your inventory. The input is a search term in verbal English.
|
||||
Good query example: black car, a stereo, 200 mile range, electric motor.
|
||||
Good query example: How many car brand are from Asia?
|
||||
3) PRESENTBOX which you can use to present the wines to the user. This function is better than CHATBOX at presenting wines. The input is the names of wines to present.
|
||||
4) ENDCONVERSATION which you can use to end the conversation with the user. The input is "NA".
|
||||
|
||||
- action_input: input details of the action
|
||||
- mentioning_wine: Are you mentioning specific wine name to the user? Can be "Yes" or "No"
|
||||
1) thought:
|
||||
- State your reasoning about the current situation.
|
||||
2) plan: Based on the current situation, state a complete plan to complete the task. Be specific.
|
||||
3) action_name (Must be aligned with your plan): The name of the action which can be one of the following functions:
|
||||
- CHATBOX which you can use to generate conversation in order to communicate with the user. The input is your intention for the talk. Be specific.
|
||||
- CHECKINVENTORY which you can use to check info about wine in your inventory. The input is a search term in verbal English.
|
||||
Good query example: black car, a stereo, 200 mile range, electric motor.
|
||||
- PRESENTBOX which you can use to introduce wines to users for the first time. It is more effective than the CHATBOX function for presenting wines. The input is the names of wines to present.
|
||||
- ENDCONVERSATION which you can use when you want to finish the conversation with the user. The input is "NA".
|
||||
4) action_input: input details of the action
|
||||
5) mentioning_wine: Are you mentioning specific wine name to the user? Can be "Yes" or "No"
|
||||
|
||||
You should only respond in format as described below:
|
||||
thought: ...
|
||||
@@ -271,16 +270,15 @@ function decisionMaker(a::T)::Dict{Symbol, Any} where {T<:agent}
|
||||
else
|
||||
""
|
||||
end
|
||||
chathistory = vectorOfDictToText(a.chathistory)
|
||||
# chathistory = vectorOfDictToText(a.chathistory)
|
||||
errornote = ""
|
||||
response = nothing # placeholder for show when error msg show up
|
||||
|
||||
for attempt in 1:10
|
||||
usermsg =
|
||||
"""
|
||||
Your conversation with the user: $chathistory
|
||||
$context
|
||||
Your Q&A: $QandA
|
||||
Recap: $(a.memory[:recap])
|
||||
Your Q&A: $(a.memory[:QandA])
|
||||
$errornote
|
||||
"""
|
||||
|
||||
@@ -996,10 +994,20 @@ function conversation(a::T, userinput::Dict) where {T<:agent}
|
||||
# add usermsg to a.chathistory
|
||||
addNewMessage(a, "user", userinput[:text])
|
||||
|
||||
# add user activity to events memory
|
||||
push!(a.memory[:events],
|
||||
eventdict(;
|
||||
event_description= "the user talks to the assistant.",
|
||||
timestamp= Dates.now(),
|
||||
subject= "user",
|
||||
action_or_dialogue= userinput[:text],
|
||||
)
|
||||
)
|
||||
|
||||
# use dummy memory to check generatechat() for halucination (checking inventory)
|
||||
for i in 1:3
|
||||
actionname, result = think(a)
|
||||
if actionname == "CHATBOX" || actionname == "PRESENTBOX"
|
||||
if actionname == "CHATBOX" || actionname == "PRESENTBOX" || actionname == "ENDCONVERSATION"
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -1025,6 +1033,14 @@ function conversation(a::T, userinput::Dict) where {T<:agent}
|
||||
|
||||
addNewMessage(a, "assistant", chatresponse)
|
||||
|
||||
push!(a.memory[:events],
|
||||
eventdict(;
|
||||
event_description= "the assistant talks to the user.",
|
||||
timestamp= Dates.now(),
|
||||
subject= "assistant",
|
||||
action_or_dialogue= chatresponse,
|
||||
)
|
||||
)
|
||||
return chatresponse
|
||||
end
|
||||
end
|
||||
@@ -1046,6 +1062,19 @@ julia>
|
||||
# Signature
|
||||
"""
|
||||
function think(a::T)::NamedTuple{(:actionname, :result), Tuple{String, String}} where {T<:agent}
|
||||
|
||||
|
||||
a.memory[:recap] = generateSituationReport(a, a.text2textInstructLLM)
|
||||
a.memory[:QandA] = generatequestion(a, a.text2textInstructLLM)
|
||||
# after the user selected their wine. No question should be asked
|
||||
# a.memory[:QandA] =
|
||||
# if occursin("None", a.memory[:sitrep][:wine_selected])
|
||||
# generatequestion(a, a.text2textInstructLLM)
|
||||
# else
|
||||
# generatequestion(a, a.text2textInstructLLM) #[PENDING] to be removed. this is just for explor
|
||||
# "None"
|
||||
# end
|
||||
|
||||
thoughtDict = decisionMaker(a)
|
||||
|
||||
actionname = thoughtDict[:action_name]
|
||||
@@ -1058,10 +1087,13 @@ function think(a::T)::NamedTuple{(:actionname, :result), Tuple{String, String}}
|
||||
elseif actionname == "CHECKINVENTORY"
|
||||
checkinventory(a, actioninput)
|
||||
elseif actionname == "PRESENTBOX"
|
||||
x = "Present the following wines to the user: $actioninput"
|
||||
x = """
|
||||
1) Present $actioninput for the user to choose: "
|
||||
2) compare each option against the others and explain why each one is a suitable match for the user's specific needs.
|
||||
"""
|
||||
(result=x, errormsg=nothing, success=true)
|
||||
elseif actionname == "ENDCONVERSATION"
|
||||
x = "Thank the user and conclude the conversation by saying goodbye and inviting them to return next time."
|
||||
x = "Conclude the conversation, thanks the user then goodbye and inviting them to return next time."
|
||||
(result=x, errormsg=nothing, success=true)
|
||||
else
|
||||
error("undefined LLM function. Requesting $actionname")
|
||||
@@ -1079,7 +1111,7 @@ function think(a::T)::NamedTuple{(:actionname, :result), Tuple{String, String}}
|
||||
if actionname == "CHATBOX"
|
||||
a.memory[:CHATBOX] = result
|
||||
elseif actionname == "CHECKINVENTORY"
|
||||
# x = "You have searched the inventory, this is what you found: $result"
|
||||
x = "I have searched the inventory, this is what I found: $result"
|
||||
x = result
|
||||
push!(a.memory[:shortmem], Dict(Symbol(actionname)=> x))
|
||||
elseif actionname == "PRESENTBOX" # tell the generatechat()
|
||||
@@ -1236,7 +1268,7 @@ julia>
|
||||
|
||||
# TODO
|
||||
- [] update docs
|
||||
- [x] implement the function
|
||||
- []
|
||||
|
||||
# Signature
|
||||
"""
|
||||
@@ -1244,9 +1276,10 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
|
||||
systemmsg =
|
||||
"""
|
||||
You are a helpful assistant acting as a polite, website-based sommelier for an online wine store.
|
||||
You are currently talking with the user.
|
||||
Your goal is to recommend the best wines from your inventory that match the user's preferences.
|
||||
You don't need to do any sale process.
|
||||
Your goal is: Recommend the best wines from your inventory that align with the user's preferences.
|
||||
|
||||
Your responsibility includes:
|
||||
1) Convey your thoughts to the user
|
||||
|
||||
At each round of conversation, you will be given the current situation:
|
||||
Your conversation with the user: ...
|
||||
@@ -1254,14 +1287,14 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
|
||||
Context: ...
|
||||
|
||||
You MUST follow the following guidelines:
|
||||
- Do not offer additional services I didn't thought.
|
||||
- Do not offer additional services you didn't thought.
|
||||
|
||||
You should follow the following guidelines:
|
||||
- When recommending wines, compare each option against the others and explain why each one is a suitable match for the user's specific needs.
|
||||
- Focus on the latest conversation.
|
||||
|
||||
You should then respond to the user with:
|
||||
- chat: Based on your thoughts, what will you say to the user?
|
||||
- mentioning_wine: Are you mentioning specific wine name to the user? Can be "Yes" or "No"
|
||||
1) chat: Given the current situation, what will you say to the user?
|
||||
2) mentioning_wine: Are you mentioning specific wine name to the user? Can be "Yes" or "No"
|
||||
|
||||
You should only respond in format as described below:
|
||||
chat: ...
|
||||
@@ -1344,7 +1377,7 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
|
||||
delete!(responsedict, :mentioning_wine)
|
||||
result = responsedict[:chat]
|
||||
|
||||
return result
|
||||
return result
|
||||
catch e
|
||||
io = IOBuffer()
|
||||
showerror(io, e)
|
||||
@@ -1364,28 +1397,33 @@ function generatequestion(a, text2textInstructLLM::Function)::String
|
||||
systemmsg =
|
||||
"""
|
||||
You are a helpful assistant acting as a polite, website-based sommelier for an online wine store.
|
||||
Your task is to self questioning about the current situation.
|
||||
You don't need to do any sale process.
|
||||
Your goal is: Help the user select the best wines from your inventory that align with the user's preferences.
|
||||
|
||||
Your responsibility includes:
|
||||
1) Self questioning about the current situation
|
||||
2) Thanks the user when they are done choosing wines and invite them to comeback next time
|
||||
|
||||
Your responsibility does not include:
|
||||
1) Processing sales orders or engaging in any other sales-related activities.
|
||||
|
||||
At each round of conversation, you will be given the current situation:
|
||||
Your conversation with the user: ...
|
||||
Context: ...
|
||||
|
||||
You must follow the following guidelines:
|
||||
1) Ask at least two questions but no more than five.
|
||||
2) Your question should be specific, self-contained and not require any additional context.
|
||||
3) Do not generate any question or comments at the end.
|
||||
4) Once the user has selected their wine, congratulate them on their choice. If they don't require any further assistance, politely the conversation without offering additional services.
|
||||
- Your question should be specific, self-contained and not require any additional context.
|
||||
- Do not generate any question or comments at the end.
|
||||
- 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.
|
||||
|
||||
You should follow the following guidelines:
|
||||
- Focus on the latest conversation.
|
||||
- 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.
|
||||
- All wines in your inventory are always in stock.
|
||||
|
||||
You should then respond to the user with:
|
||||
- Reasoning: State your detailed reasoning of the current situation
|
||||
- Q: Based on the current situation, ask yourself what you need to do in order to help the user
|
||||
- A: Based on the current situation, answer to yourself the best you can
|
||||
|
||||
1) Reasoning: State your detailed reasoning of the current situation
|
||||
2) Q: Based on the current situation, ask yourself at least two, but no more than five, questions about what you need to do to achieve the goal.
|
||||
3) A: Based on the current situation, answer to yourself the best you can
|
||||
|
||||
You must only respond in format as described below:
|
||||
Reasoning: ...
|
||||
@@ -1414,6 +1452,7 @@ function generatequestion(a, text2textInstructLLM::Function)::String
|
||||
usermsg =
|
||||
"""
|
||||
Your conversation with the user: $chathistory
|
||||
Recap: $(a.memory[:recap])
|
||||
$context
|
||||
$errornote
|
||||
"""
|
||||
@@ -1434,9 +1473,10 @@ function generatequestion(a, text2textInstructLLM::Function)::String
|
||||
try
|
||||
response = text2textInstructLLM(prompt)
|
||||
q_number = count("Q ", response)
|
||||
if q_number < 2
|
||||
if q_number < 1
|
||||
error("too few questions only $q_number questions are generated ", @__FILE__, " ", @__LINE__)
|
||||
end
|
||||
response = string(split(response, "Please")[1]) # LLM usually add comments which is no need.
|
||||
println("--> generatequestion ", @__FILE__, " ", @__LINE__)
|
||||
pprintln(response)
|
||||
return response
|
||||
@@ -1454,6 +1494,106 @@ function generatequestion(a, text2textInstructLLM::Function)::String
|
||||
end
|
||||
|
||||
|
||||
function generateSituationReport(a, text2textInstructLLM::Function)::Dict
|
||||
|
||||
# systemmsg =
|
||||
# """
|
||||
# You are a helpful assistant in the given timeline.
|
||||
# You task is to writes a situational report on the current situation.
|
||||
|
||||
# At each round of conversation, you will be given the current situation:
|
||||
# Timeline: ...
|
||||
# Context: ...
|
||||
|
||||
# You should then respond to the user with:
|
||||
# 1) report: State your detailed situational report on the current situation.
|
||||
# 2) wine_selected: Indicates whether the user selected wine. It can be the name of the selected wine or "None"
|
||||
|
||||
# You must only respond in format as described below:
|
||||
# report: ...
|
||||
# wine_selected: ...
|
||||
|
||||
# Let's begin!
|
||||
# """
|
||||
|
||||
systemmsg =
|
||||
"""
|
||||
You are the assistant being in the given events.
|
||||
Your task is to writes a summary of each event.
|
||||
|
||||
At each round of conversation, you will be given the situation:
|
||||
Events timeline: ...
|
||||
Context: ...
|
||||
|
||||
You should then respond to the user with:
|
||||
event: a detailed summary of each event without exaggerated details.
|
||||
|
||||
You must only respond in format as described below:
|
||||
event 1: ...
|
||||
event 2: ...
|
||||
...
|
||||
|
||||
Here are some examples:
|
||||
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.
|
||||
|
||||
Let's begin!
|
||||
"""
|
||||
|
||||
timeline = ""
|
||||
for (i, event) in enumerate(a.memory[:events])
|
||||
if event[:outcome] === nothing
|
||||
timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue])\n"
|
||||
else
|
||||
timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue]) $(event[:outcome])\n"
|
||||
end
|
||||
end
|
||||
|
||||
errornote = ""
|
||||
response = nothing # store for show when error msg show up
|
||||
|
||||
for attempt in 1:10
|
||||
usermsg =
|
||||
"""
|
||||
Events timeline: $timeline
|
||||
$errornote
|
||||
"""
|
||||
|
||||
_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|>
|
||||
"""
|
||||
|
||||
try
|
||||
response = text2textInstructLLM(prompt)
|
||||
# responsedict = GeneralUtils.textToDict(response,
|
||||
# ["summary", "presented", "selected"],
|
||||
# rightmarker=":", symbolkey=true)
|
||||
# println("--> generateSituationReport ", @__FILE__, " ", @__LINE__)
|
||||
pprintln(response)
|
||||
|
||||
return Dict(:recap=>response)
|
||||
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("generateSituationReport failed to generate a thought ", response)
|
||||
end
|
||||
|
||||
|
||||
|
||||
# """
|
||||
@@ -1636,8 +1776,6 @@ end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ module llmfunction
|
||||
export virtualWineUserChatbox, jsoncorrection, checkinventory, # recommendbox,
|
||||
virtualWineUserRecommendbox, userChatbox, userRecommendbox
|
||||
|
||||
using HTTP, JSON3, URIs, Random, PrettyPrinting, UUIDs
|
||||
using HTTP, JSON3, URIs, Random, PrettyPrinting, UUIDs, Dates
|
||||
using GeneralUtils, SQLLLM
|
||||
using ..type, ..util
|
||||
|
||||
@@ -289,13 +289,24 @@ julia> result = checkinventory(agent, input)
|
||||
"""
|
||||
function checkinventory(a::T1, input::T2
|
||||
)::NamedTuple{(:result, :success, :errormsg), Tuple{String, Bool, Union{String, Nothing}}} where {T1<:agent, T2<:AbstractString}
|
||||
println("--> checkinventory input: $input ", @__FILE__, " ", @__LINE__)
|
||||
println("--> checkinventory order: $input ", @__FILE__, " ", @__LINE__)
|
||||
wineattributes_1 = extractWineAttributes_1(a, input)
|
||||
wineattributes_2 = extractWineAttributes_2(a, input)
|
||||
|
||||
inventoryquery = "$wineattributes_1, $wineattributes_2"
|
||||
println("--> checkinventory: $inventoryquery ", @__FILE__, " ", @__LINE__)
|
||||
println("--> checkinventory input: $inventoryquery ", @__FILE__, " ", @__LINE__)
|
||||
result = SQLLLM.query(inventoryquery, a.executeSQL, a.text2textInstructLLM)
|
||||
|
||||
push!(a.memory[:events],
|
||||
eventdict(;
|
||||
event_description= "the assistant searched the database.",
|
||||
timestamp= Dates.now(),
|
||||
subject= "assistant",
|
||||
action_or_dialogue= "I searched the database with this query: $inventoryquery",
|
||||
outcome= "This is what I found in the database, $result"
|
||||
)
|
||||
)
|
||||
|
||||
return (result=result, success=true, errormsg=nothing)
|
||||
end
|
||||
|
||||
@@ -338,16 +349,16 @@ function extractWineAttributes_1(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
3) Do not generate other comments.
|
||||
|
||||
You should then respond to the user with the following points:
|
||||
- reasoning: State your understanding of the current situation
|
||||
- wine_type: Can be one of: "red", "white", "sparkling", "rose", "dessert" or "fortified"
|
||||
- price: Must be an integer representing the cost of the wine.
|
||||
- reasoning: state your understanding of the current situation
|
||||
- wine_type: can be one of: "red", "white", "sparkling", "rose", "dessert" or "fortified"
|
||||
- price: must be an integer representing the cost of the wine
|
||||
- occasion: ...
|
||||
- food_to_be_paired_with_wine: food that the user will be served with wine
|
||||
- country: wine's country of origin
|
||||
- region: wine's region of origin such as Burgundy, Napa Valley
|
||||
- grape variety: a single name of grape used to make wine.
|
||||
- flavors: Names of items that the wine tastes like.
|
||||
- aromas: wine's aroma
|
||||
- food_to_be_paired_with_wine: food that the user will be served with the wine
|
||||
- region: a region in a country where the wine is produced, such as Burgundy, Napa Valley, etc
|
||||
- country: a country where the wine is produced
|
||||
- grape_variety: the name of the primary grape used to make the wine
|
||||
- flavors: names of items that the wine tastes like, such as citrus, lime, etc
|
||||
- aromas: the wine's aromas, such as fruity, floral, etc
|
||||
|
||||
You should only respond in the form as described below:
|
||||
reasoning: ...
|
||||
@@ -355,8 +366,8 @@ function extractWineAttributes_1(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
price: ...
|
||||
occasion: ...
|
||||
food_to_be_paired_with_wine: ...
|
||||
country: ...
|
||||
region: ...
|
||||
country: ...
|
||||
grape_variety: ...
|
||||
flavors: ...
|
||||
aromas: ...
|
||||
@@ -364,7 +375,7 @@ function extractWineAttributes_1(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
Let's begin!
|
||||
"""
|
||||
|
||||
attributes = ["reasoning", "wine_type", "price", "occasion", "food_to_be_paired_with_wine", "country", "region", "grape_variety", "flavors", "aromas"]
|
||||
attributes = ["reasoning", "wine_type", "price", "occasion", "food_to_be_paired_with_wine", "region", "country", "grape_variety", "flavors", "aromas"]
|
||||
errornote = ""
|
||||
maxattempt = 5
|
||||
for attempt in 1:maxattempt
|
||||
@@ -427,6 +438,7 @@ function extractWineAttributes_1(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
# check if grape_variety is mentioned in the input
|
||||
if !occursin("NA", responsedict[:grape_variety]) && !occursin(responsedict[:grape_variety], input)
|
||||
if attempt < maxattempt
|
||||
errornote = "You are halucinating, $(responsedict[:grape_variety]) is not mentioned in the input"
|
||||
error("$(responsedict[:grape_variety]) is not mentioned in the input")
|
||||
else
|
||||
responsedict[:grape_variety] = "NA"
|
||||
@@ -438,6 +450,7 @@ function extractWineAttributes_1(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
delete!(responsedict, :tasting_notes)
|
||||
delete!(responsedict, :flavors)
|
||||
delete!(responsedict, :aromas)
|
||||
delete!(responsedict, :price)
|
||||
|
||||
# remove (some text)
|
||||
for (k, v) in responsedict
|
||||
@@ -527,14 +540,10 @@ function extractWineAttributes_2(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
|
||||
You should then respond to the user with the following points:
|
||||
- reasoning: State your understanding of the current situation
|
||||
- sweetness: S where S are integers represent the range of sweetness levels
|
||||
Example: 1-2
|
||||
- acidity: D where D are integers represent the range of acidity level
|
||||
Example: 3-5
|
||||
- tannin: T where T are integers represent the range of tannin level
|
||||
Example: 1-3
|
||||
- intensity: I where I are integers represent the range of intensity level
|
||||
Example: 2-4
|
||||
- sweetness: ( S ), where ( S ) represents integers indicating the range of sweetness levels. Example: 1-2
|
||||
- acidity: ( A ), where ( A ) represents integers indicating the range of acidity level. Example: 3-5
|
||||
- tannin: ( T ), where ( T ) represents integers indicating the range of tannin level. Example: 1-3
|
||||
- intensity: ( I ), where ( I ) represents integers indicating the range of intensity level. Example: 2-4
|
||||
- notes: Anything you want to add
|
||||
|
||||
You should only respond in the form as described below:
|
||||
|
||||
@@ -131,7 +131,8 @@ function sommelier(
|
||||
|
||||
memory = Dict{Symbol, Any}(
|
||||
:chatbox=> "",
|
||||
:shortmem=> Vector{Dict{Symbol, String}}()
|
||||
:shortmem=> Vector{Dict{Symbol, String}}(),
|
||||
:events=> Vector{Dict{Symbol, Any}}()
|
||||
)
|
||||
|
||||
newAgent = sommelier(
|
||||
|
||||
26
src/util.jl
26
src/util.jl
@@ -1,6 +1,6 @@
|
||||
module util
|
||||
|
||||
export clearhistory, addNewMessage, vectorOfDictToText
|
||||
export clearhistory, addNewMessage, vectorOfDictToText, eventdict
|
||||
|
||||
using UUIDs, Dates, DataStructures, HTTP, MQTTClient, JSON3
|
||||
using GeneralUtils
|
||||
@@ -153,7 +153,29 @@ function vectorOfDictToText(vecd::Vector; withkey=true)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function eventdict(;
|
||||
event_description::Union{String, Nothing}=nothing,
|
||||
timestamp::Union{DateTime, Nothing}=nothing,
|
||||
subject::Union{String, Nothing}=nothing,
|
||||
action_or_dialogue::Union{String, Nothing}=nothing,
|
||||
location::Union{String, Nothing}=nothing,
|
||||
equipment_used::Union{String, Nothing}=nothing,
|
||||
material_used::Union{String, Nothing}=nothing,
|
||||
outcome::Union{String, Nothing}=nothing,
|
||||
note::Union{String, Nothing}=nothing,
|
||||
)
|
||||
return Dict{Symbol, Any}(
|
||||
:event_description=> event_description,
|
||||
:timestamp=> timestamp,
|
||||
:subject=> subject,
|
||||
:action_or_dialogue=> action_or_dialogue,
|
||||
:location=> location,
|
||||
:equipment_used=> equipment_used,
|
||||
:material_used=> material_used,
|
||||
:outcome=> outcome,
|
||||
:note=> note,
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -88,9 +88,9 @@ end
|
||||
main()
|
||||
|
||||
"""
|
||||
I'm joining a graduation party this evening. I have unlimited budget but I'm ok with wine in all price range. I want a bottle of dry red wine.
|
||||
I'm joining a graduation party this evening. I have unlimited budget and I'm ok with wines in all price range. I want a bottle of full bodied, dry white wine.
|
||||
Well, it is a small casual party with close friends and no food serving.
|
||||
I'm open to suggestion since I have no specific idea about wine but I like full bodied wine from France.
|
||||
I'm open to suggestion since I have no specific idea about wine.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user